xref: /netbsd-src/sys/arch/sh3/dev/sci.c (revision 0dd5877adce57db949b16ae963e5a6831cccdfb6)
1 /* $NetBSD: sci.c,v 1.18 2002/02/12 15:26:46 uch Exp $ */
2 
3 /*-
4  * Copyright (C) 1999 T.Horiuchi and SAITOH Masanobu.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*-
30  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
31  * All rights reserved.
32  *
33  * This code is derived from software contributed to The NetBSD Foundation
34  * by Charles M. Hannum.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  * 3. All advertising materials mentioning features or use of this software
45  *    must display the following acknowledgement:
46  *        This product includes software developed by the NetBSD
47  *        Foundation, Inc. and its contributors.
48  * 4. Neither the name of The NetBSD Foundation nor the names of its
49  *    contributors may be used to endorse or promote products derived
50  *    from this software without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
53  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
54  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
55  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
56  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
57  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
58  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
59  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
60  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
61  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62  * POSSIBILITY OF SUCH DAMAGE.
63  */
64 
65 /*
66  * Copyright (c) 1991 The Regents of the University of California.
67  * All rights reserved.
68  *
69  * Redistribution and use in source and binary forms, with or without
70  * modification, are permitted provided that the following conditions
71  * are met:
72  * 1. Redistributions of source code must retain the above copyright
73  *    notice, this list of conditions and the following disclaimer.
74  * 2. Redistributions in binary form must reproduce the above copyright
75  *    notice, this list of conditions and the following disclaimer in the
76  *    documentation and/or other materials provided with the distribution.
77  * 3. All advertising materials mentioning features or use of this software
78  *    must display the following acknowledgement:
79  *	This product includes software developed by the University of
80  *	California, Berkeley and its contributors.
81  * 4. Neither the name of the University nor the names of its contributors
82  *    may be used to endorse or promote products derived from this software
83  *    without specific prior written permission.
84  *
85  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
86  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
87  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
88  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
89  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
90  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
91  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
92  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
93  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
94  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
95  * SUCH DAMAGE.
96  *
97  *	@(#)com.c	7.5 (Berkeley) 5/16/91
98  */
99 
100 /*
101  * SH internal serial driver
102  *
103  * This code is derived from both z8530tty.c and com.c
104  */
105 
106 #include "opt_kgdb.h"
107 #include "opt_sci.h"
108 
109 #include <sys/param.h>
110 #include <sys/systm.h>
111 #include <sys/tty.h>
112 #include <sys/proc.h>
113 #include <sys/conf.h>
114 #include <sys/file.h>
115 #include <sys/syslog.h>
116 #include <sys/kernel.h>
117 #include <sys/device.h>
118 #include <sys/malloc.h>
119 
120 #include <dev/cons.h>
121 
122 #include <machine/cpu.h>
123 #include <sh3/pclock.h>
124 #include <sh3/scireg.h>
125 #include <sh3/tmureg.h>
126 
127 #include <machine/shbvar.h>
128 
129 static void	scistart(struct tty *);
130 static int	sciparam(struct tty *, struct termios *);
131 
132 void scicnprobe(struct consdev *);
133 void scicninit(struct consdev *);
134 void scicnputc(dev_t, int);
135 int scicngetc(dev_t);
136 void scicnpoolc(dev_t, int);
137 int sciintr(void *);
138 
139 struct sci_softc {
140 	struct device sc_dev;		/* boilerplate */
141 	struct tty *sc_tty;
142 	void *sc_ih;
143 
144 	struct callout sc_diag_ch;
145 
146 #if 0
147 	bus_space_tag_t sc_iot;		/* ISA i/o space identifier */
148 	bus_space_handle_t   sc_ioh;	/* ISA io handle */
149 
150 	int sc_drq;
151 
152 	int sc_frequency;
153 #endif
154 
155 	u_int sc_overflows,
156 	      sc_floods,
157 	      sc_errors;		/* number of retries so far */
158 	u_char sc_status[7];		/* copy of registers */
159 
160 	int sc_hwflags;
161 	int sc_swflags;
162 	u_int sc_fifolen;		/* XXX always 0? */
163 
164 	u_int sc_r_hiwat,
165 	      sc_r_lowat;
166 	u_char *volatile sc_rbget,
167 	       *volatile sc_rbput;
168  	volatile u_int sc_rbavail;
169 	u_char *sc_rbuf,
170 	       *sc_ebuf;
171 
172  	u_char *sc_tba;			/* transmit buffer address */
173  	u_int sc_tbc,			/* transmit byte count */
174 	      sc_heldtbc;
175 
176 	volatile u_char sc_rx_flags,	/* receiver blocked */
177 #define	RX_TTY_BLOCKED		0x01
178 #define	RX_TTY_OVERFLOWED	0x02
179 #define	RX_IBUF_BLOCKED		0x04
180 #define	RX_IBUF_OVERFLOWED	0x08
181 #define	RX_ANY_BLOCK		0x0f
182 			sc_tx_busy,	/* working on an output chunk */
183 			sc_tx_done,	/* done with one output chunk */
184 			sc_tx_stopped,	/* H/W level stop (lost CTS) */
185 			sc_st_check,	/* got a status interrupt */
186 			sc_rx_ready;
187 
188 	volatile u_char sc_heldchange;
189 };
190 
191 /* controller driver configuration */
192 static int sci_match(struct device *, struct cfdata *, void *);
193 static void sci_attach(struct device *, struct device *, void *);
194 
195 void	sci_break(struct sci_softc *, int);
196 void	sci_iflush(struct sci_softc *);
197 
198 #define	integrate	static inline
199 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
200 void 	scisoft(void *);
201 #else
202 #ifndef __NO_SOFT_SERIAL_INTERRUPT
203 void 	scisoft(void);
204 #else
205 void 	scisoft(void *);
206 #endif
207 #endif
208 integrate void sci_rxsoft(struct sci_softc *, struct tty *);
209 integrate void sci_txsoft(struct sci_softc *, struct tty *);
210 integrate void sci_stsoft(struct sci_softc *, struct tty *);
211 integrate void sci_schedrx(struct sci_softc *);
212 void	scidiag(void *);
213 
214 #define	SCIUNIT_MASK		0x7ffff
215 #define	SCIDIALOUT_MASK	0x80000
216 
217 #define	SCIUNIT(x)	(minor(x) & SCIUNIT_MASK)
218 #define	SCIDIALOUT(x)	(minor(x) & SCIDIALOUT_MASK)
219 
220 /* Macros to clear/set/test flags. */
221 #define SET(t, f)	(t) |= (f)
222 #define CLR(t, f)	(t) &= ~(f)
223 #define ISSET(t, f)	((t) & (f))
224 
225 /* Hardware flag masks */
226 #define	SCI_HW_NOIEN	0x01
227 #define	SCI_HW_FIFO	0x02
228 #define	SCI_HW_FLOW	0x08
229 #define	SCI_HW_DEV_OK	0x20
230 #define	SCI_HW_CONSOLE	0x40
231 #define	SCI_HW_KGDB	0x80
232 
233 /* Buffer size for character buffer */
234 #define	SCI_RING_SIZE	2048
235 
236 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
237 u_int sci_rbuf_hiwat = (SCI_RING_SIZE * 1) / 4;
238 u_int sci_rbuf_lowat = (SCI_RING_SIZE * 3) / 4;
239 
240 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
241 int sciconscflag = CONMODE;
242 int sciisconsole = 0;
243 
244 #ifdef SCICN_SPEED
245 int scicn_speed = SCICN_SPEED;
246 #else
247 int scicn_speed = 9600;
248 #endif
249 
250 #define	divrnd(n, q)	(((n)*2/(q)+1)/2)	/* divide and round off */
251 
252 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
253 #ifdef __NO_SOFT_SERIAL_INTERRUPT
254 volatile int	sci_softintr_scheduled;
255 struct callout sci_soft_ch = CALLOUT_INITIALIZER;
256 #endif
257 #endif
258 
259 u_int sci_rbuf_size = SCI_RING_SIZE;
260 
261 struct cfattach sci_ca = {
262 	sizeof(struct sci_softc), sci_match, sci_attach
263 };
264 
265 extern struct cfdriver sci_cd;
266 
267 cdev_decl(sci);
268 
269 void InitializeSci (unsigned int);
270 
271 /*
272  * following functions are debugging prupose only
273  */
274 #define CR      0x0D
275 #define I2C_ADRS (*(volatile unsigned int *)0xa8000000)
276 #define USART_ON (unsigned int)~0x08
277 
278 static void WaitFor(int);
279 void sci_putc(unsigned char);
280 unsigned char sci_getc(void);
281 int SciErrCheck(void);
282 
283 /*
284  * WaitFor
285  * : int mSec;
286  */
287 static void
288 WaitFor(int mSec)
289 {
290 
291 	/* Disable Under Flow interrupt, rising edge, 1/4 */
292 	SHREG_TCR2 = 0x0000;
293 
294 	/* Set counter value (count down with 4 KHz) */
295 	SHREG_TCNT2 = mSec * 4;
296 
297 	/* start Channel2 */
298 	SHREG_TSTR |= TSTR_STR2;
299 
300 	/* wait for under flag ON of channel2 */
301 	while ((SHREG_TCR2 & TCR_UNF) == 0)
302 		;
303 
304 	/* stop channel2 */
305 	SHREG_TSTR &= ~TSTR_STR2;
306 }
307 
308 /*
309  * InitializeSci
310  * : unsigned int bps;
311  * : SCI(Serial Communication Interface)
312  */
313 
314 void
315 InitializeSci(unsigned int bps)
316 {
317 
318 	/* Initialize SCR */
319 	SHREG_SCSCR = 0x00;
320 
321 	/* Serial Mode Register */
322 	SHREG_SCSMR = 0x00;	/* Async,8bit,NonParity,Even,1Stop,NoMulti */
323 
324 	/* Bit Rate Register */
325 	SHREG_SCBRR = divrnd(PCLOCK, 32 * bps) - 1;
326 
327 	/*
328 	 * wait 1mSec, because Send/Recv must begin 1 bit period after
329 	 * BRR is set.
330 	 */
331 	WaitFor(1);
332 
333 	/* Send permission, Receive permission ON */
334 	SHREG_SCSCR = SCSCR_TE | SCSCR_RE;
335 
336 	/* Serial Status Register */
337 	SHREG_SCSSR &= SCSSR_TDRE;	/* Clear Status */
338 
339 #if 0
340 	I2C_ADRS &= ~0x08;	/* enable RS-232C */
341 #endif
342 }
343 
344 
345 /*
346  * sci_putc
347  *  : unsigned char c;
348  */
349 void
350 sci_putc(unsigned char c)
351 {
352 
353 	if (c == '\n')
354 		sci_putc('\r');
355 
356 	/* wait for ready */
357 	while ((SHREG_SCSSR & SCSSR_TDRE) == NULL)
358 		;
359 
360 	/* write send data to send register */
361 	SHREG_SCTDR = c;
362 
363 	/* clear ready flag */
364 	SHREG_SCSSR &= ~SCSSR_TDRE;
365 }
366 
367 /*
368  * : SciErrCheck
369  *	0x20 = over run
370  *	0x10 = frame error
371  *	0x80 = parity error
372  */
373 int
374 SciErrCheck(void)
375 {
376 
377 	return(SHREG_SCSSR & (SCSSR_ORER | SCSSR_FER | SCSSR_PER));
378 }
379 
380 /*
381  * sci_getc
382  */
383 unsigned char
384 sci_getc(void)
385 {
386 	unsigned char c, err_c;
387 
388 	while (((err_c = SHREG_SCSSR)
389 		& (SCSSR_RDRF | SCSSR_ORER | SCSSR_FER | SCSSR_PER)) == 0)
390 		;
391 	if ((err_c & (SCSSR_ORER | SCSSR_FER | SCSSR_PER)) != 0) {
392 		SHREG_SCSSR &= ~(SCSSR_ORER | SCSSR_FER | SCSSR_PER);
393 		return(err_c |= 0x80);
394 	}
395 
396 	c = SHREG_SCRDR;
397 
398 	SHREG_SCSSR &= ~SCSSR_RDRF;
399 
400 	return(c);
401 }
402 
403 #if 0
404 #define SCI_MAX_UNITS 2
405 #else
406 #define SCI_MAX_UNITS 1
407 #endif
408 
409 
410 static int
411 sci_match(struct device *parent, struct cfdata *cfp, void *aux)
412 {
413 	struct shb_attach_args *sa = aux;
414 
415 	if (strcmp(cfp->cf_driver->cd_name, "sci")
416 	    || cfp->cf_unit >= SCI_MAX_UNITS)
417 		return 0;
418 
419 	sa->ia_iosize = 0x10;
420 	return 1;
421 }
422 
423 static void
424 sci_attach(struct device *parent, struct device *self, void *aux)
425 {
426 	struct sci_softc *sc = (struct sci_softc *)self;
427 	struct tty *tp;
428 	int irq;
429 	struct shb_attach_args *ia = aux;
430 
431 	sc->sc_hwflags = 0;	/* XXX */
432 	sc->sc_swflags = 0;	/* XXX */
433 	sc->sc_fifolen = 0;	/* XXX */
434 
435 	irq = ia->ia_irq;
436 
437 	if (sciisconsole) {
438 		SET(sc->sc_hwflags, SCI_HW_CONSOLE);
439 		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
440 		printf("\n%s: console\n", sc->sc_dev.dv_xname);
441 	} else {
442 		InitializeSci(9600);
443 		printf("\n");
444 	}
445 
446 	callout_init(&sc->sc_diag_ch);
447 
448 #if 0
449 	if (irq != IRQUNK) {
450 		sc->sc_ih = shb_intr_establish(irq,
451 		    IST_EDGE, IPL_SERIAL, sciintr, sc);
452 	}
453 #else
454 	if (irq != IRQUNK) {
455 		sc->sc_ih = shb_intr_establish(SCI_IRQ,
456 		    IST_EDGE, IPL_SERIAL, sciintr, sc);
457 	}
458 #endif
459 
460 	SET(sc->sc_hwflags, SCI_HW_DEV_OK);
461 
462 	tp = ttymalloc();
463 	tp->t_oproc = scistart;
464 	tp->t_param = sciparam;
465 	tp->t_hwiflow = NULL;
466 
467 	sc->sc_tty = tp;
468 	sc->sc_rbuf = malloc(sci_rbuf_size << 1, M_DEVBUF, M_NOWAIT);
469 	if (sc->sc_rbuf == NULL) {
470 		printf("%s: unable to allocate ring buffer\n",
471 		    sc->sc_dev.dv_xname);
472 		return;
473 	}
474 	sc->sc_ebuf = sc->sc_rbuf + (sci_rbuf_size << 1);
475 
476 	tty_attach(tp);
477 }
478 
479 /*
480  * Start or restart transmission.
481  */
482 static void
483 scistart(struct tty *tp)
484 {
485 	struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(tp->t_dev)];
486 	int s;
487 
488 	s = spltty();
489 	if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
490 		goto out;
491 	if (sc->sc_tx_stopped)
492 		goto out;
493 
494 	if (tp->t_outq.c_cc <= tp->t_lowat) {
495 		if (ISSET(tp->t_state, TS_ASLEEP)) {
496 			CLR(tp->t_state, TS_ASLEEP);
497 			wakeup(&tp->t_outq);
498 		}
499 		selwakeup(&tp->t_wsel);
500 		if (tp->t_outq.c_cc == 0)
501 			goto out;
502 	}
503 
504 	/* Grab the first contiguous region of buffer space. */
505 	{
506 		u_char *tba;
507 		int tbc;
508 
509 		tba = tp->t_outq.c_cf;
510 		tbc = ndqb(&tp->t_outq, 0);
511 
512 		(void)splserial();
513 
514 		sc->sc_tba = tba;
515 		sc->sc_tbc = tbc;
516 	}
517 
518 	SET(tp->t_state, TS_BUSY);
519 	sc->sc_tx_busy = 1;
520 
521 	/* Enable transmit completion interrupts if necessary. */
522 	SHREG_SCSCR |= SCSCR_TIE | SCSCR_RIE;
523 
524 	/* Output the first byte of the contiguous buffer. */
525 	{
526 		if (sc->sc_tbc > 0) {
527 			sci_putc(*(sc->sc_tba));
528 			sc->sc_tba++;
529 			sc->sc_tbc--;
530 		}
531 	}
532 out:
533 	splx(s);
534 	return;
535 }
536 
537 /*
538  * Set SCI tty parameters from termios.
539  * XXX - Should just copy the whole termios after
540  * making sure all the changes could be done.
541  */
542 static int
543 sciparam(struct tty *tp, struct termios *t)
544 {
545 	struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(tp->t_dev)];
546 	int ospeed = t->c_ospeed;
547 	int s;
548 
549 	if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
550 		return (EIO);
551 
552 	/* Check requested parameters. */
553 	if (ospeed < 0)
554 		return (EINVAL);
555 	if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
556 		return (EINVAL);
557 
558 	/*
559 	 * For the console, always force CLOCAL and !HUPCL, so that the port
560 	 * is always active.
561 	 */
562 	if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) ||
563 	    ISSET(sc->sc_hwflags, SCI_HW_CONSOLE)) {
564 		SET(t->c_cflag, CLOCAL);
565 		CLR(t->c_cflag, HUPCL);
566 	}
567 
568 	/*
569 	 * If there were no changes, don't do anything.  This avoids dropping
570 	 * input and improves performance when all we did was frob things like
571 	 * VMIN and VTIME.
572 	 */
573 	if (tp->t_ospeed == t->c_ospeed &&
574 	    tp->t_cflag == t->c_cflag)
575 		return (0);
576 
577 #if 0
578 /* XXX (msaitoh) */
579 	lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag);
580 #endif
581 
582 	s = splserial();
583 
584 	/*
585 	 * Set the FIFO threshold based on the receive speed.
586 	 *
587 	 *  * If it's a low speed, it's probably a mouse or some other
588 	 *    interactive device, so set the threshold low.
589 	 *  * If it's a high speed, trim the trigger level down to prevent
590 	 *    overflows.
591 	 *  * Otherwise set it a bit higher.
592 	 */
593 #if 0
594 /* XXX (msaitoh) */
595 	if (ISSET(sc->sc_hwflags, SCI_HW_HAYESP))
596 		sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8;
597 	else if (ISSET(sc->sc_hwflags, SCI_HW_FIFO))
598 		sc->sc_fifo = FIFO_ENABLE |
599 		    (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 :
600 		     t->c_ospeed <= 38400 ? FIFO_TRIGGER_8 : FIFO_TRIGGER_4);
601 	else
602 		sc->sc_fifo = 0;
603 #endif
604 
605 	/* And copy to tty. */
606 	tp->t_ispeed = 0;
607 	tp->t_ospeed = t->c_ospeed;
608 	tp->t_cflag = t->c_cflag;
609 
610 	if (!sc->sc_heldchange) {
611 		if (sc->sc_tx_busy) {
612 			sc->sc_heldtbc = sc->sc_tbc;
613 			sc->sc_tbc = 0;
614 			sc->sc_heldchange = 1;
615 		}
616 #if 0
617 /* XXX (msaitoh) */
618 		else
619 			sci_loadchannelregs(sc);
620 #endif
621 	}
622 
623 	if (!ISSET(t->c_cflag, CHWFLOW)) {
624 		/* Disable the high water mark. */
625 		sc->sc_r_hiwat = 0;
626 		sc->sc_r_lowat = 0;
627 		if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
628 			CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
629 			sci_schedrx(sc);
630 		}
631 	} else {
632 		sc->sc_r_hiwat = sci_rbuf_hiwat;
633 		sc->sc_r_lowat = sci_rbuf_lowat;
634 	}
635 
636 	splx(s);
637 
638 #ifdef SCI_DEBUG
639 	if (sci_debug)
640 		scistatus(sc, "sciparam ");
641 #endif
642 
643 	if (!ISSET(t->c_cflag, CHWFLOW)) {
644 		if (sc->sc_tx_stopped) {
645 			sc->sc_tx_stopped = 0;
646 			scistart(tp);
647 		}
648 	}
649 
650 	return (0);
651 }
652 
653 void
654 sci_iflush(struct sci_softc *sc)
655 {
656 	unsigned char err_c;
657 	volatile unsigned char c;
658 
659 	if (((err_c = SHREG_SCSSR)
660 	     & (SCSSR_RDRF | SCSSR_ORER | SCSSR_FER | SCSSR_PER)) != 0) {
661 
662 		if ((err_c & (SCSSR_ORER | SCSSR_FER | SCSSR_PER)) != 0) {
663 			SHREG_SCSSR &= ~(SCSSR_ORER | SCSSR_FER | SCSSR_PER);
664 			return;
665 		}
666 
667 		c = SHREG_SCRDR;
668 
669 		SHREG_SCSSR &= ~SCSSR_RDRF;
670 	}
671 }
672 
673 int
674 sciopen(dev_t dev, int flag, int mode, struct proc *p)
675 {
676 	int unit = SCIUNIT(dev);
677 	struct sci_softc *sc;
678 	struct tty *tp;
679 	int s, s2;
680 	int error;
681 
682 	if (unit >= sci_cd.cd_ndevs)
683 		return (ENXIO);
684 	sc = sci_cd.cd_devs[unit];
685 	if (sc == 0 || !ISSET(sc->sc_hwflags, SCI_HW_DEV_OK) ||
686 	    sc->sc_rbuf == NULL)
687 		return (ENXIO);
688 
689 	if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
690 		return (ENXIO);
691 
692 #ifdef KGDB
693 	/*
694 	 * If this is the kgdb port, no other use is permitted.
695 	 */
696 	if (ISSET(sc->sc_hwflags, SCI_HW_KGDB))
697 		return (EBUSY);
698 #endif
699 
700 	tp = sc->sc_tty;
701 
702 	if (ISSET(tp->t_state, TS_ISOPEN) &&
703 	    ISSET(tp->t_state, TS_XCLUDE) &&
704 	    p->p_ucred->cr_uid != 0)
705 		return (EBUSY);
706 
707 	s = spltty();
708 
709 	/*
710 	 * Do the following iff this is a first open.
711 	 */
712 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
713 		struct termios t;
714 
715 		tp->t_dev = dev;
716 
717 		s2 = splserial();
718 
719 		/* Turn on interrupts. */
720 		SHREG_SCSCR |= SCSCR_TIE | SCSCR_RIE;
721 
722 		splx(s2);
723 
724 		/*
725 		 * Initialize the termios status to the defaults.  Add in the
726 		 * sticky bits from TIOCSFLAGS.
727 		 */
728 		t.c_ispeed = 0;
729 		if (ISSET(sc->sc_hwflags, SCI_HW_CONSOLE)) {
730 			t.c_ospeed = scicn_speed;
731 			t.c_cflag = sciconscflag;
732 		} else {
733 			t.c_ospeed = TTYDEF_SPEED;
734 			t.c_cflag = TTYDEF_CFLAG;
735 		}
736 		if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
737 			SET(t.c_cflag, CLOCAL);
738 		if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
739 			SET(t.c_cflag, CRTSCTS);
740 		if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
741 			SET(t.c_cflag, MDMBUF);
742 		/* Make sure sciparam() will do something. */
743 		tp->t_ospeed = 0;
744 		(void) sciparam(tp, &t);
745 		tp->t_iflag = TTYDEF_IFLAG;
746 		tp->t_oflag = TTYDEF_OFLAG;
747 		tp->t_lflag = TTYDEF_LFLAG;
748 		ttychars(tp);
749 		ttsetwater(tp);
750 
751 		s2 = splserial();
752 
753 		/* Clear the input ring, and unblock. */
754 		sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
755 		sc->sc_rbavail = sci_rbuf_size;
756 		sci_iflush(sc);
757 		CLR(sc->sc_rx_flags, RX_ANY_BLOCK);
758 #if 0
759 /* XXX (msaitoh) */
760 		sci_hwiflow(sc);
761 #endif
762 
763 #ifdef SCI_DEBUG
764 		if (sci_debug)
765 			scistatus(sc, "sciopen  ");
766 #endif
767 
768 		splx(s2);
769 	}
770 
771 	splx(s);
772 
773 	error = ttyopen(tp, SCIDIALOUT(dev), ISSET(flag, O_NONBLOCK));
774 	if (error)
775 		goto bad;
776 
777 	error = (*tp->t_linesw->l_open)(dev, tp);
778 	if (error)
779 		goto bad;
780 
781 	return (0);
782 
783 bad:
784 
785 	return (error);
786 }
787 
788 int
789 sciclose(dev_t dev, int flag, int mode, struct proc *p)
790 {
791 	struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)];
792 	struct tty *tp = sc->sc_tty;
793 
794 	/* XXX This is for cons.c. */
795 	if (!ISSET(tp->t_state, TS_ISOPEN))
796 		return (0);
797 
798 	(*tp->t_linesw->l_close)(tp, flag);
799 	ttyclose(tp);
800 
801 	if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
802 		return (0);
803 
804 	return (0);
805 }
806 
807 int
808 sciread(dev_t dev, struct uio *uio, int flag)
809 {
810 	struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)];
811 	struct tty *tp = sc->sc_tty;
812 
813 	return ((*tp->t_linesw->l_read)(tp, uio, flag));
814 }
815 
816 int
817 sciwrite(dev_t dev, struct uio *uio, int flag)
818 {
819 	struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)];
820 	struct tty *tp = sc->sc_tty;
821 
822 	return ((*tp->t_linesw->l_write)(tp, uio, flag));
823 }
824 
825 int
826 scipoll(dev_t dev, int events, struct proc *p)
827 {
828 	struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)];
829 	struct tty *tp = sc->sc_tty;
830 
831 	return ((*tp->t_linesw->l_poll)(tp, events, p));
832 }
833 
834 struct tty *
835 scitty(dev_t dev)
836 {
837 	struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)];
838 	struct tty *tp = sc->sc_tty;
839 
840 	return (tp);
841 }
842 
843 int
844 sciioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
845 {
846 	struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)];
847 	struct tty *tp = sc->sc_tty;
848 	int error;
849 	int s;
850 
851 	if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
852 		return (EIO);
853 
854 	error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p);
855 	if (error >= 0)
856 		return (error);
857 
858 	error = ttioctl(tp, cmd, data, flag, p);
859 	if (error >= 0)
860 		return (error);
861 
862 	error = 0;
863 
864 	s = splserial();
865 
866 	switch (cmd) {
867 	case TIOCSBRK:
868 		sci_break(sc, 1);
869 		break;
870 
871 	case TIOCCBRK:
872 		sci_break(sc, 0);
873 		break;
874 
875 	case TIOCGFLAGS:
876 		*(int *)data = sc->sc_swflags;
877 		break;
878 
879 	case TIOCSFLAGS:
880 		error = suser(p->p_ucred, &p->p_acflag);
881 		if (error)
882 			break;
883 		sc->sc_swflags = *(int *)data;
884 		break;
885 
886 	default:
887 		error = ENOTTY;
888 		break;
889 	}
890 
891 	splx(s);
892 
893 	return (error);
894 }
895 
896 integrate void
897 sci_schedrx(struct sci_softc *sc)
898 {
899 
900 	sc->sc_rx_ready = 1;
901 
902 	/* Wake up the poller. */
903 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
904 	softintr_schedule(sc->sc_si);
905 #else
906 #ifndef __NO_SOFT_SERIAL_INTERRUPT
907 	setsoftserial();
908 #else
909 	if (!sci_softintr_scheduled) {
910 		sci_softintr_scheduled = 1;
911 		callout_reset(&sci_soft_ch, 1, scisoft, NULL);
912 	}
913 #endif
914 #endif
915 }
916 
917 void
918 sci_break(struct sci_softc *sc, int onoff)
919 {
920 
921 	if (onoff)
922 		SHREG_SCSSR &= ~SCSSR_TDRE;
923 	else
924 		SHREG_SCSSR |= SCSSR_TDRE;
925 
926 #if 0	/* XXX */
927 	if (!sc->sc_heldchange) {
928 		if (sc->sc_tx_busy) {
929 			sc->sc_heldtbc = sc->sc_tbc;
930 			sc->sc_tbc = 0;
931 			sc->sc_heldchange = 1;
932 		} else
933 			sci_loadchannelregs(sc);
934 	}
935 #endif
936 }
937 
938 /*
939  * Stop output, e.g., for ^S or output flush.
940  */
941 void
942 scistop(struct tty *tp, int flag)
943 {
944 	struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(tp->t_dev)];
945 	int s;
946 
947 	s = splserial();
948 	if (ISSET(tp->t_state, TS_BUSY)) {
949 		/* Stop transmitting at the next chunk. */
950 		sc->sc_tbc = 0;
951 		sc->sc_heldtbc = 0;
952 		if (!ISSET(tp->t_state, TS_TTSTOP))
953 			SET(tp->t_state, TS_FLUSH);
954 	}
955 	splx(s);
956 }
957 
958 void
959 scidiag(void *arg)
960 {
961 	struct sci_softc *sc = arg;
962 	int overflows, floods;
963 	int s;
964 
965 	s = splserial();
966 	overflows = sc->sc_overflows;
967 	sc->sc_overflows = 0;
968 	floods = sc->sc_floods;
969 	sc->sc_floods = 0;
970 	sc->sc_errors = 0;
971 	splx(s);
972 
973 	log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
974 	    sc->sc_dev.dv_xname,
975 	    overflows, overflows == 1 ? "" : "s",
976 	    floods, floods == 1 ? "" : "s");
977 }
978 
979 integrate void
980 sci_rxsoft(struct sci_softc *sc, struct tty *tp)
981 {
982 	int (*rint)(int c, struct tty *tp) = tp->t_linesw->l_rint;
983 	u_char *get, *end;
984 	u_int cc, scc;
985 	u_char ssr;
986 	int code;
987 	int s;
988 
989 	end = sc->sc_ebuf;
990 	get = sc->sc_rbget;
991 	scc = cc = sci_rbuf_size - sc->sc_rbavail;
992 
993 	if (cc == sci_rbuf_size) {
994 		sc->sc_floods++;
995 		if (sc->sc_errors++ == 0)
996 			callout_reset(&sc->sc_diag_ch, 60 * hz, scidiag, sc);
997 	}
998 
999 	while (cc) {
1000 		code = get[0];
1001 		ssr = get[1];
1002 		if (ISSET(ssr, SCSSR_FER | SCSSR_PER)) {
1003 			if (ISSET(ssr, SCSSR_FER))
1004 				SET(code, TTY_FE);
1005 			if (ISSET(ssr, SCSSR_PER))
1006 				SET(code, TTY_PE);
1007 		}
1008 		if ((*rint)(code, tp) == -1) {
1009 			/*
1010 			 * The line discipline's buffer is out of space.
1011 			 */
1012 			if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1013 				/*
1014 				 * We're either not using flow control, or the
1015 				 * line discipline didn't tell us to block for
1016 				 * some reason.  Either way, we have no way to
1017 				 * know when there's more space available, so
1018 				 * just drop the rest of the data.
1019 				 */
1020 				get += cc << 1;
1021 				if (get >= end)
1022 					get -= sci_rbuf_size << 1;
1023 				cc = 0;
1024 			} else {
1025 				/*
1026 				 * Don't schedule any more receive processing
1027 				 * until the line discipline tells us there's
1028 				 * space available (through scihwiflow()).
1029 				 * Leave the rest of the data in the input
1030 				 * buffer.
1031 				 */
1032 				SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1033 			}
1034 			break;
1035 		}
1036 		get += 2;
1037 		if (get >= end)
1038 			get = sc->sc_rbuf;
1039 		cc--;
1040 	}
1041 
1042 	if (cc != scc) {
1043 		sc->sc_rbget = get;
1044 		s = splserial();
1045 		cc = sc->sc_rbavail += scc - cc;
1046 		/* Buffers should be ok again, release possible block. */
1047 		if (cc >= sc->sc_r_lowat) {
1048 			if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
1049 				CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
1050 				SHREG_SCSCR |= SCSCR_RIE;
1051 			}
1052 #if 0
1053 			if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
1054 				CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
1055 				sci_hwiflow(sc);
1056 			}
1057 #endif
1058 		}
1059 		splx(s);
1060 	}
1061 }
1062 
1063 integrate void
1064 sci_txsoft(sc, tp)
1065 	struct sci_softc *sc;
1066 	struct tty *tp;
1067 {
1068 
1069 	CLR(tp->t_state, TS_BUSY);
1070 	if (ISSET(tp->t_state, TS_FLUSH))
1071 		CLR(tp->t_state, TS_FLUSH);
1072 	else
1073 		ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
1074 	(*tp->t_linesw->l_start)(tp);
1075 }
1076 
1077 integrate void
1078 sci_stsoft(struct sci_softc *sc, struct tty *tp)
1079 {
1080 #if 0
1081 /* XXX (msaitoh) */
1082 	u_char msr, delta;
1083 	int s;
1084 
1085 	s = splserial();
1086 	msr = sc->sc_msr;
1087 	delta = sc->sc_msr_delta;
1088 	sc->sc_msr_delta = 0;
1089 	splx(s);
1090 
1091 	if (ISSET(delta, sc->sc_msr_dcd)) {
1092 		/*
1093 		 * Inform the tty layer that carrier detect changed.
1094 		 */
1095 		(void) (*tp->t_linesw->l_modem)(tp, ISSET(msr, MSR_DCD));
1096 	}
1097 
1098 	if (ISSET(delta, sc->sc_msr_cts)) {
1099 		/* Block or unblock output according to flow control. */
1100 		if (ISSET(msr, sc->sc_msr_cts)) {
1101 			sc->sc_tx_stopped = 0;
1102 			(*tp->t_linesw->l_start)(tp);
1103 		} else {
1104 			sc->sc_tx_stopped = 1;
1105 		}
1106 	}
1107 
1108 #ifdef SCI_DEBUG
1109 	if (sci_debug)
1110 		scistatus(sc, "sci_stsoft");
1111 #endif
1112 #endif
1113 }
1114 
1115 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
1116 void
1117 scisoft(void *arg)
1118 {
1119 	struct sci_softc *sc = arg;
1120 	struct tty *tp;
1121 
1122 	if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
1123 		return;
1124 
1125 	{
1126 #else
1127 void
1128 #ifndef __NO_SOFT_SERIAL_INTERRUPT
1129 scisoft()
1130 #else
1131 scisoft(void *arg)
1132 #endif
1133 {
1134 	struct sci_softc	*sc;
1135 	struct tty	*tp;
1136 	int	unit;
1137 #ifdef __NO_SOFT_SERIAL_INTERRUPT
1138 	int s;
1139 
1140 	s = splsoftserial();
1141 	sci_softintr_scheduled = 0;
1142 #endif
1143 
1144 	for (unit = 0; unit < sci_cd.cd_ndevs; unit++) {
1145 		sc = sci_cd.cd_devs[unit];
1146 		if (sc == NULL || !ISSET(sc->sc_hwflags, SCI_HW_DEV_OK))
1147 			continue;
1148 
1149 		if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
1150 			continue;
1151 
1152 		tp = sc->sc_tty;
1153 		if (tp == NULL)
1154 			continue;
1155 		if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0)
1156 			continue;
1157 #endif
1158 		tp = sc->sc_tty;
1159 
1160 		if (sc->sc_rx_ready) {
1161 			sc->sc_rx_ready = 0;
1162 			sci_rxsoft(sc, tp);
1163 		}
1164 
1165 #if 0
1166 		if (sc->sc_st_check) {
1167 			sc->sc_st_check = 0;
1168 			sci_stsoft(sc, tp);
1169 		}
1170 #endif
1171 
1172 		if (sc->sc_tx_done) {
1173 			sc->sc_tx_done = 0;
1174 			sci_txsoft(sc, tp);
1175 		}
1176 	}
1177 
1178 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
1179 #ifdef __NO_SOFT_SERIAL_INTERRUPT
1180 	splx(s);
1181 #endif
1182 #endif
1183 }
1184 
1185 int
1186 sciintr(void *arg)
1187 {
1188 	struct sci_softc *sc = arg;
1189 	u_char *put, *end;
1190 	u_int cc;
1191 	u_short ssr;
1192 
1193 	if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
1194 		return (0);
1195 
1196 	end = sc->sc_ebuf;
1197 	put = sc->sc_rbput;
1198 	cc = sc->sc_rbavail;
1199 
1200 	ssr = SHREG_SCSSR;
1201 	if (ISSET(ssr, SCSSR_FER)) {
1202 		SHREG_SCSSR &= ~(SCSSR_ORER | SCSSR_PER | SCSSR_FER);
1203 #if defined(DDB) || defined(KGDB)
1204 #ifdef SH4
1205 		if ((SHREG_SCSPTR & SCPTR_SPB0DT) != 0) {
1206 #else
1207 		if ((SHREG_SCSPDR & SCPDR_SCP0DT) != 0) {
1208 #endif
1209 #ifdef DDB
1210 			if (ISSET(sc->sc_hwflags, SCI_HW_CONSOLE)) {
1211 				console_debugger();
1212 			}
1213 #endif
1214 #ifdef KGDB
1215 			if (ISSET(sc->sc_hwflags, SCI_HW_KGDB)) {
1216 				kgdb_connect(1);
1217 			}
1218 #endif
1219 		}
1220 #endif /* DDB || KGDB */
1221 	}
1222 	if ((SHREG_SCSSR & SCSSR_RDRF) != 0) {
1223 		if (cc > 0) {
1224 			put[0] = SHREG_SCRDR;
1225 			put[1] = SHREG_SCSSR & 0x00ff;
1226 
1227 			SHREG_SCSSR &= ~(SCSSR_ORER | SCSSR_FER | SCSSR_PER |
1228 					 SCSSR_RDRF);
1229 
1230 			put += 2;
1231 			if (put >= end)
1232 				put = sc->sc_rbuf;
1233 			cc--;
1234 		}
1235 
1236 		/*
1237 		 * Current string of incoming characters ended because
1238 		 * no more data was available or we ran out of space.
1239 		 * Schedule a receive event if any data was received.
1240 		 * If we're out of space, turn off receive interrupts.
1241 		 */
1242 		sc->sc_rbput = put;
1243 		sc->sc_rbavail = cc;
1244 		if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
1245 			sc->sc_rx_ready = 1;
1246 
1247 		/*
1248 		 * See if we are in danger of overflowing a buffer. If
1249 		 * so, use hardware flow control to ease the pressure.
1250 		 */
1251 		if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) &&
1252 		    cc < sc->sc_r_hiwat) {
1253 			SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
1254 #if 0
1255 			sci_hwiflow(sc);
1256 #endif
1257 		}
1258 
1259 		/*
1260 		 * If we're out of space, disable receive interrupts
1261 		 * until the queue has drained a bit.
1262 		 */
1263 		if (!cc) {
1264 			SHREG_SCSCR &= ~SCSCR_RIE;
1265 		}
1266 	} else {
1267 		if (SHREG_SCSSR & SCSSR_RDRF) {
1268 			SHREG_SCSCR &= ~(SCSCR_TIE | SCSCR_RIE);
1269 		}
1270 	}
1271 
1272 #if 0
1273 	msr = bus_space_read_1(iot, ioh, sci_msr);
1274 	delta = msr ^ sc->sc_msr;
1275 	sc->sc_msr = msr;
1276 	if (ISSET(delta, sc->sc_msr_mask)) {
1277 		SET(sc->sc_msr_delta, delta);
1278 
1279 		/*
1280 		 * Pulse-per-second clock signal on edge of DCD?
1281 		 */
1282 		if (ISSET(delta, sc->sc_ppsmask)) {
1283 			struct timeval tv;
1284 			if (ISSET(msr, sc->sc_ppsmask) ==
1285 			    sc->sc_ppsassert) {
1286 				/* XXX nanotime() */
1287 				microtime(&tv);
1288 				TIMEVAL_TO_TIMESPEC(&tv,
1289 						    &sc->ppsinfo.assert_timestamp);
1290 				if (sc->ppsparam.mode & PPS_OFFSETASSERT) {
1291 					timespecadd(&sc->ppsinfo.assert_timestamp,
1292 						    &sc->ppsparam.assert_offset,
1293 						    &sc->ppsinfo.assert_timestamp);
1294 					TIMESPEC_TO_TIMEVAL(&tv, &sc->ppsinfo.assert_timestamp);
1295 				}
1296 
1297 #ifdef PPS_SYNC
1298 				if (sc->ppsparam.mode & PPS_HARDPPSONASSERT)
1299 					hardpps(&tv, tv.tv_usec);
1300 #endif
1301 				sc->ppsinfo.assert_sequence++;
1302 				sc->ppsinfo.current_mode =
1303 					sc->ppsparam.mode;
1304 
1305 			} else if (ISSET(msr, sc->sc_ppsmask) ==
1306 				   sc->sc_ppsclear) {
1307 				/* XXX nanotime() */
1308 				microtime(&tv);
1309 				TIMEVAL_TO_TIMESPEC(&tv,
1310 						    &sc->ppsinfo.clear_timestamp);
1311 				if (sc->ppsparam.mode & PPS_OFFSETCLEAR) {
1312 					timespecadd(&sc->ppsinfo.clear_timestamp,
1313 						    &sc->ppsparam.clear_offset,
1314 						    &sc->ppsinfo.clear_timestamp);
1315 					TIMESPEC_TO_TIMEVAL(&tv, &sc->ppsinfo.clear_timestamp);
1316 				}
1317 
1318 #ifdef PPS_SYNC
1319 				if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR)
1320 					hardpps(&tv, tv.tv_usec);
1321 #endif
1322 				sc->ppsinfo.clear_sequence++;
1323 				sc->ppsinfo.current_mode =
1324 					sc->ppsparam.mode;
1325 			}
1326 		}
1327 
1328 		/*
1329 		 * Stop output immediately if we lose the output
1330 		 * flow control signal or carrier detect.
1331 		 */
1332 		if (ISSET(~msr, sc->sc_msr_mask)) {
1333 			sc->sc_tbc = 0;
1334 			sc->sc_heldtbc = 0;
1335 #ifdef SCI_DEBUG
1336 			if (sci_debug)
1337 				scistatus(sc, "sciintr  ");
1338 #endif
1339 		}
1340 
1341 		sc->sc_st_check = 1;
1342 	}
1343 #endif
1344 
1345 	/*
1346 	 * Done handling any receive interrupts. See if data can be
1347 	 * transmitted as well. Schedule tx done event if no data left
1348 	 * and tty was marked busy.
1349 	 */
1350 	if ((SHREG_SCSSR & SCSSR_TDRE) != 0) {
1351 		/*
1352 		 * If we've delayed a parameter change, do it now, and restart
1353 		 * output.
1354 		 */
1355 		if (sc->sc_heldchange) {
1356 			sc->sc_heldchange = 0;
1357 			sc->sc_tbc = sc->sc_heldtbc;
1358 			sc->sc_heldtbc = 0;
1359 		}
1360 
1361 		/* Output the next chunk of the contiguous buffer, if any. */
1362 		if (sc->sc_tbc > 0) {
1363 			sci_putc(*(sc->sc_tba));
1364 			sc->sc_tba++;
1365 			sc->sc_tbc--;
1366 		} else {
1367 			/* Disable transmit completion interrupts if necessary. */
1368 #if 0
1369 			if (ISSET(sc->sc_ier, IER_ETXRDY))
1370 #endif
1371 				SHREG_SCSCR &= ~SCSCR_TIE;
1372 
1373 			if (sc->sc_tx_busy) {
1374 				sc->sc_tx_busy = 0;
1375 				sc->sc_tx_done = 1;
1376 			}
1377 		}
1378 	}
1379 
1380 	/* Wake up the poller. */
1381 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
1382 	softintr_schedule(sc->sc_si);
1383 #else
1384 #ifndef __NO_SOFT_SERIAL_INTERRUPT
1385 	setsoftserial();
1386 #else
1387 	if (!sci_softintr_scheduled) {
1388 		sci_softintr_scheduled = 1;
1389 		callout_reset(&sci_soft_ch, 1, scisoft, 1);
1390 	}
1391 #endif
1392 #endif
1393 
1394 #if NRND > 0 && defined(RND_SCI)
1395 	rnd_add_uint32(&sc->rnd_source, iir | lsr);
1396 #endif
1397 
1398 	return (1);
1399 }
1400 
1401 void
1402 scicnprobe(cp)
1403 	struct consdev *cp;
1404 {
1405 	int maj;
1406 
1407 	/* locate the major number */
1408 	for (maj = 0; maj < nchrdev; maj++)
1409 		if (cdevsw[maj].d_open == sciopen)
1410 			break;
1411 
1412 	/* Initialize required fields. */
1413 	cp->cn_dev = makedev(maj, 0);
1414 #ifdef SCICONSOLE
1415 	cp->cn_pri = CN_REMOTE;
1416 #else
1417 	cp->cn_pri = CN_NORMAL;
1418 #endif
1419 }
1420 
1421 void
1422 scicninit(struct consdev *cp)
1423 {
1424 
1425 	InitializeSci(scicn_speed);
1426 	sciisconsole = 1;
1427 }
1428 
1429 int
1430 scicngetc(dev_t dev)
1431 {
1432 	int c;
1433 	int s;
1434 
1435 	s = splserial();
1436 	c = sci_getc();
1437 	splx(s);
1438 
1439 	return (c);
1440 }
1441 
1442 void
1443 scicnputc(dev_t dev, int c)
1444 {
1445 	int s;
1446 
1447 	s = splserial();
1448 	sci_putc((u_char)c);
1449 	splx(s);
1450 }
1451