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