com.c revision 1.105 1 /* $NetBSD: com.c,v 1.105 1997/08/16 08:33:10 drochner Exp $ */
2
3 /*-
4 * Copyright (c) 1993, 1994, 1995, 1996, 1997
5 * Charles M. Hannum. All rights reserved.
6 *
7 * Interrupt processing and hardware flow control partly based on code from
8 * Onno van der Linden and Gordon Ross.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Charles M. Hannum.
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 /*
37 * Copyright (c) 1991 The Regents of the University of California.
38 * All rights reserved.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by the University of
51 * California, Berkeley and its contributors.
52 * 4. Neither the name of the University nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
55 *
56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * SUCH DAMAGE.
67 *
68 * @(#)com.c 7.5 (Berkeley) 5/16/91
69 */
70
71 /*
72 * COM driver, uses National Semiconductor NS16450/NS16550AF UART
73 */
74 #include <sys/param.h>
75 #include <sys/systm.h>
76 #include <sys/ioctl.h>
77 #include <sys/select.h>
78 #include <sys/tty.h>
79 #include <sys/proc.h>
80 #include <sys/user.h>
81 #include <sys/conf.h>
82 #include <sys/file.h>
83 #include <sys/uio.h>
84 #include <sys/kernel.h>
85 #include <sys/syslog.h>
86 #include <sys/types.h>
87 #include <sys/device.h>
88
89 #include <machine/intr.h>
90 #include <machine/bus.h>
91
92 #include <dev/isa/comreg.h>
93 #include <dev/isa/comvar.h>
94 #include <dev/ic/ns16550reg.h>
95 #ifdef COM_HAYESP
96 #include <dev/ic/hayespreg.h>
97 #endif
98 #define com_lcr com_cfcr
99
100 #include "com.h"
101
102 #ifdef COM_HAYESP
103 int comprobeHAYESP __P((bus_space_handle_t hayespioh, struct com_softc *sc));
104 #endif
105
106 #if defined(DDB) || defined(KGDB)
107 static void com_enable_debugport __P((struct com_softc *));
108 #endif
109 void com_attach_subr __P((struct com_softc *sc));
110 void comdiag __P((void *));
111 int comspeed __P((long));
112 int comparam __P((struct tty *, struct termios *));
113 void comstart __P((struct tty *));
114 void comstop __P((struct tty *, int));
115 #ifdef __GENERIC_SOFT_INTERRUPTS
116 void comsoft __P((void *));
117 #else
118 #ifndef alpha
119 void comsoft __P((void));
120 #else
121 void comsoft __P((void *));
122 #endif
123 #endif
124 int comhwiflow __P((struct tty *, int));
125
126 void com_loadchannelregs __P((struct com_softc *));
127 void com_hwiflow __P((struct com_softc *));
128 void com_break __P((struct com_softc *, int));
129 void com_modem __P((struct com_softc *, int));
130 void com_iflush __P((struct com_softc *));
131
132 int com_common_getc __P((bus_space_tag_t, bus_space_handle_t));
133 void com_common_putc __P((bus_space_tag_t, bus_space_handle_t, int));
134
135 /* XXX: These belong elsewhere */
136 cdev_decl(com);
137 bdev_decl(com);
138
139 struct consdev;
140 void comcnprobe __P((struct consdev *));
141 void comcninit __P((struct consdev *));
142 int comcngetc __P((dev_t));
143 void comcnputc __P((dev_t, int));
144 void comcnpollc __P((dev_t, int));
145
146 #define integrate static inline
147 integrate void comrxint __P((struct com_softc *, struct tty *));
148 integrate void comtxint __P((struct com_softc *, struct tty *));
149 integrate void commsrint __P((struct com_softc *, struct tty *));
150 integrate void com_schedrx __P((struct com_softc *));
151
152 struct cfdriver com_cd = {
153 NULL, "com", DV_TTY
154 };
155
156 void cominitcons __P((bus_space_tag_t, bus_space_handle_t, int));
157
158 #ifdef CONSPEED
159 int comconsrate = CONSPEED;
160 #else
161 int comconsrate = TTYDEF_SPEED;
162 #endif
163 int comconsaddr;
164 bus_space_tag_t comconstag;
165 bus_space_handle_t comconsioh;
166 tcflag_t comconscflag = TTYDEF_CFLAG;
167 int comconsattached;
168
169 int commajor;
170
171 #ifndef __GENERIC_SOFT_INTERRUPTS
172 #ifdef alpha
173 volatile int com_softintr_scheduled;
174 #endif
175 #endif
176
177 #ifdef KGDB
178 #include <sys/kgdb.h>
179 extern int kgdb_dev;
180 extern int kgdb_rate;
181 extern int kgdb_debug_init;
182
183 int com_kgdb_addr;
184 bus_space_tag_t com_kgdb_iot;
185 bus_space_handle_t com_kgdb_ioh;
186
187 int com_kgdb_getc __P((void *));
188 void com_kgdb_putc __P((void *, int));
189 #endif /* KGDB */
190
191 #define COMUNIT(x) (minor(x))
192
193 int
194 comspeed(speed)
195 long speed;
196 {
197 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
198
199 int x, err;
200
201 #if 0
202 if (speed == 0)
203 return (0);
204 #endif
205 if (speed <= 0)
206 return (-1);
207 x = divrnd((COM_FREQ / 16), speed);
208 if (x <= 0)
209 return (-1);
210 err = divrnd((COM_FREQ / 16) * 1000, speed * x) - 1000;
211 if (err < 0)
212 err = -err;
213 if (err > COM_TOLERANCE)
214 return (-1);
215 return (x);
216
217 #undef divrnd(n, q)
218 }
219
220 #ifdef COM_DEBUG
221 int com_debug = 0;
222
223 void comstatus __P((struct com_softc *, char *));
224 void
225 comstatus(sc, str)
226 struct com_softc *sc;
227 char *str;
228 {
229 struct tty *tp = sc->sc_tty;
230
231 printf("%s: %s %sclocal %sdcd %sts_carr_on %sdtr %stx_stopped\n",
232 sc->sc_dev.dv_xname, str,
233 ISSET(tp->t_cflag, CLOCAL) ? "+" : "-",
234 ISSET(sc->sc_msr, MSR_DCD) ? "+" : "-",
235 ISSET(tp->t_state, TS_CARR_ON) ? "+" : "-",
236 ISSET(sc->sc_mcr, MCR_DTR) ? "+" : "-",
237 sc->sc_tx_stopped ? "+" : "-");
238
239 printf("%s: %s %scrtscts %scts %sts_ttstop %srts %xrx_flags\n",
240 sc->sc_dev.dv_xname, str,
241 ISSET(tp->t_cflag, CRTSCTS) ? "+" : "-",
242 ISSET(sc->sc_msr, MSR_CTS) ? "+" : "-",
243 ISSET(tp->t_state, TS_TTSTOP) ? "+" : "-",
244 ISSET(sc->sc_mcr, MCR_RTS) ? "+" : "-",
245 sc->sc_rx_flags);
246 }
247 #endif
248
249 int
250 comprobe1(iot, ioh, iobase)
251 bus_space_tag_t iot;
252 bus_space_handle_t ioh;
253 int iobase;
254 {
255
256 /* force access to id reg */
257 bus_space_write_1(iot, ioh, com_lcr, 0);
258 bus_space_write_1(iot, ioh, com_iir, 0);
259 if (bus_space_read_1(iot, ioh, com_iir) & 0x38)
260 return (0);
261
262 return (1);
263 }
264
265 #ifdef COM_HAYESP
266 int
267 comprobeHAYESP(hayespioh, sc)
268 bus_space_handle_t hayespioh;
269 struct com_softc *sc;
270 {
271 char val, dips;
272 int combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
273 bus_space_tag_t iot = sc->sc_iot;
274
275 /*
276 * Hayes ESP cards have two iobases. One is for compatibility with
277 * 16550 serial chips, and at the same ISA PC base addresses. The
278 * other is for ESP-specific enhanced features, and lies at a
279 * different addressing range entirely (0x140, 0x180, 0x280, or 0x300).
280 */
281
282 /* Test for ESP signature */
283 if ((bus_space_read_1(iot, hayespioh, 0) & 0xf3) == 0)
284 return (0);
285
286 /*
287 * ESP is present at ESP enhanced base address; unknown com port
288 */
289
290 /* Get the dip-switch configurations */
291 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETDIPS);
292 dips = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1);
293
294 /* Determine which com port this ESP card services: bits 0,1 of */
295 /* dips is the port # (0-3); combaselist[val] is the com_iobase */
296 if (sc->sc_iobase != combaselist[dips & 0x03])
297 return (0);
298
299 printf(": ESP");
300
301 /* Check ESP Self Test bits. */
302 /* Check for ESP version 2.0: bits 4,5,6 == 010 */
303 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETTEST);
304 val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1); /* Clear reg1 */
305 val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS2);
306 if ((val & 0x70) < 0x20) {
307 printf("-old (%o)", val & 0x70);
308 /* we do not support the necessary features */
309 return (0);
310 }
311
312 /* Check for ability to emulate 16550: bit 8 == 1 */
313 if ((dips & 0x80) == 0) {
314 printf(" slave");
315 /* XXX Does slave really mean no 16550 support?? */
316 return (0);
317 }
318
319 /*
320 * If we made it this far, we are a full-featured ESP v2.0 (or
321 * better), at the correct com port address.
322 */
323
324 SET(sc->sc_hwflags, COM_HW_HAYESP);
325 printf(", 1024 byte fifo\n");
326 return (1);
327 }
328 #endif
329
330 #ifdef KGDB
331 /* ARGSUSED */
332 int
333 com_kgdb_getc(arg)
334 void *arg;
335 {
336
337 return (com_common_getc(com_kgdb_iot, com_kgdb_ioh));
338 }
339
340 /* ARGSUSED */
341 void
342 com_kgdb_putc(arg, c)
343 void *arg;
344 int c;
345 {
346
347 return (com_common_putc(com_kgdb_iot, com_kgdb_ioh, c));
348 }
349 #endif /* KGDB */
350
351 #if defined(DDB) || defined(KGDB)
352 static void
353 com_enable_debugport(sc)
354 struct com_softc *sc;
355 {
356 int s;
357
358 /* Turn on line break interrupt, set carrier. */
359 s = splserial();
360 sc->sc_ier = IER_ERXRDY;
361 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
362 SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
363 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
364 splx(s);
365 }
366 #endif
367
368 void
369 com_attach_subr(sc)
370 struct com_softc *sc;
371 {
372 int iobase = sc->sc_iobase;
373 bus_space_tag_t iot = sc->sc_iot;
374 bus_space_handle_t ioh = sc->sc_ioh;
375 #ifdef COM_HAYESP
376 int hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 };
377 int *hayespp;
378 #endif
379
380 if (iobase == comconsaddr) {
381 comconsattached = 1;
382
383 /* Make sure the console is always "hardwired". */
384 delay(1000); /* wait for output to finish */
385 SET(sc->sc_hwflags, COM_HW_CONSOLE);
386 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
387 }
388
389 #ifdef COM_HAYESP
390 /* Look for a Hayes ESP board. */
391 for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) {
392 bus_space_handle_t hayespioh;
393
394 #define HAYESP_NPORTS 8 /* XXX XXX XXX ??? ??? ??? */
395 if (bus_space_map(iot, *hayespp, HAYESP_NPORTS, 0, &hayespioh))
396 continue;
397 if (comprobeHAYESP(hayespioh, sc)) {
398 sc->sc_hayespioh = hayespioh;
399 sc->sc_fifolen = 1024;
400
401 /* Set 16550 compatibility mode */
402 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETMODE);
403 bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
404 HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
405 HAYESP_MODE_SCALE);
406
407 /* Set RTS/CTS flow control */
408 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETFLOWTYPE);
409 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, HAYESP_FLOW_RTS);
410 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, HAYESP_FLOW_CTS);
411
412 /* Set flow control levels */
413 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETRXFLOW);
414 bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
415 HAYESP_HIBYTE(HAYESP_RXHIWMARK));
416 bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
417 HAYESP_LOBYTE(HAYESP_RXHIWMARK));
418 bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
419 HAYESP_HIBYTE(HAYESP_RXLOWMARK));
420 bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
421 HAYESP_LOBYTE(HAYESP_RXLOWMARK));
422
423 break;
424 }
425 bus_space_unmap(iot, hayespioh, HAYESP_NPORTS);
426 }
427 /* No ESP; look for other things. */
428 if (*hayespp == 0) {
429 #endif
430
431 sc->sc_fifolen = 1;
432 /* look for a NS 16550AF UART with FIFOs */
433 bus_space_write_1(iot, ioh, com_fifo,
434 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
435 delay(100);
436 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_FIFO_MASK)
437 == IIR_FIFO_MASK)
438 if (ISSET(bus_space_read_1(iot, ioh, com_fifo), FIFO_TRIGGER_14)
439 == FIFO_TRIGGER_14) {
440 SET(sc->sc_hwflags, COM_HW_FIFO);
441 printf(": ns16550a, working fifo\n");
442 sc->sc_fifolen = 16;
443 } else
444 printf(": ns16550, broken fifo\n");
445 else
446 printf(": ns8250 or ns16450, no fifo\n");
447 bus_space_write_1(iot, ioh, com_fifo, 0);
448 #ifdef COM_HAYESP
449 }
450 #endif
451
452 if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
453 SET(sc->sc_mcr, MCR_IENABLE);
454
455 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
456 #ifdef DDB
457 com_enable_debugport(sc);
458 #endif
459 printf("%s: console\n", sc->sc_dev.dv_xname);
460 }
461
462 #ifdef KGDB
463 /*
464 * Allow kgdb to "take over" this port. If this is
465 * the kgdb device, it has exclusive use.
466 */
467 if (iobase == com_kgdb_addr) {
468 SET(sc->sc_hwflags, COM_HW_KGDB);
469 com_enable_debugport(sc);
470 printf("%s: kgdb\n", sc->sc_dev.dv_xname);
471 }
472 #endif
473
474 #ifdef __GENERIC_SOFT_INTERRUPTS
475 sc->sc_si = softintr_establish(IPL_SOFTSERIAL, comsoft, sc);
476 #endif
477 }
478
479 int
480 comopen(dev, flag, mode, p)
481 dev_t dev;
482 int flag, mode;
483 struct proc *p;
484 {
485 int unit = COMUNIT(dev);
486 struct com_softc *sc;
487 struct tty *tp;
488 int s, s2;
489 int error = 0;
490
491 if (unit >= com_cd.cd_ndevs)
492 return (ENXIO);
493 sc = com_cd.cd_devs[unit];
494 if (!sc)
495 return (ENXIO);
496
497 #ifdef KGDB
498 /*
499 * If this is the kgdb port, no other use is permitted.
500 */
501 if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
502 return (EBUSY);
503 #endif
504
505 if (!sc->sc_tty) {
506 tp = sc->sc_tty = ttymalloc();
507 tty_attach(tp);
508 } else
509 tp = sc->sc_tty;
510
511 if (ISSET(tp->t_state, TS_ISOPEN) &&
512 ISSET(tp->t_state, TS_XCLUDE) &&
513 p->p_ucred->cr_uid != 0)
514 return (EBUSY);
515
516 s = spltty();
517
518 /* We need to set this early for the benefit of comsoft(). */
519 SET(tp->t_state, TS_WOPEN);
520
521 /*
522 * Do the following iff this is a first open.
523 */
524 if (!ISSET(tp->t_state, TS_ISOPEN)) {
525 struct termios t;
526
527 /* Turn on interrupts. */
528 sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
529 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
530
531 /* Fetch the current modem control status, needed later. */
532 sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr);
533
534 /* Add some entry points needed by the tty layer. */
535 tp->t_oproc = comstart;
536 tp->t_param = comparam;
537 tp->t_hwiflow = comhwiflow;
538 tp->t_dev = dev;
539
540 /*
541 * Initialize the termios status to the defaults. Add in the
542 * sticky bits from TIOCSFLAGS.
543 */
544 t.c_ispeed = 0;
545 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
546 t.c_ospeed = comconsrate;
547 t.c_cflag = comconscflag;
548 } else {
549 t.c_ospeed = TTYDEF_SPEED;
550 t.c_cflag = TTYDEF_CFLAG;
551 }
552 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
553 SET(t.c_cflag, CLOCAL);
554 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
555 SET(t.c_cflag, CRTSCTS);
556 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
557 SET(t.c_cflag, MDMBUF);
558 tp->t_iflag = TTYDEF_IFLAG;
559 tp->t_oflag = TTYDEF_OFLAG;
560 tp->t_lflag = TTYDEF_LFLAG;
561 ttychars(tp);
562 (void) comparam(tp, &t);
563 ttsetwater(tp);
564
565 s2 = splserial();
566
567 /*
568 * Turn on DTR. We must always do this, even if carrier is not
569 * present, because otherwise we'd have to use TIOCSDTR
570 * immediately after setting CLOCAL. We will drop DTR only on
571 * the next high-low transition of DCD, or by explicit request.
572 */
573 com_modem(sc, 1);
574
575 /* Clear the input ring, and unblock. */
576 sc->sc_rbput = sc->sc_rbget = 0;
577 sc->sc_rbavail = RXBUFSIZE;
578 com_iflush(sc);
579 CLR(sc->sc_rx_flags, RX_ANY_BLOCK);
580 com_hwiflow(sc);
581
582 #ifdef COM_DEBUG
583 if (com_debug)
584 comstatus(sc, "comopen ");
585 #endif
586
587 splx(s2);
588 }
589 error = 0;
590
591 /* If we're doing a blocking open... */
592 if (!ISSET(flag, O_NONBLOCK))
593 /* ...then wait for carrier. */
594 while (!ISSET(tp->t_state, TS_CARR_ON) &&
595 !ISSET(tp->t_cflag, CLOCAL | MDMBUF)) {
596 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
597 ttopen, 0);
598 if (error) {
599 /*
600 * If the open was interrupted and nobody
601 * else has the device open, then hang up.
602 */
603 if (!ISSET(tp->t_state, TS_ISOPEN)) {
604 com_modem(sc, 0);
605 CLR(tp->t_state, TS_WOPEN);
606 ttwakeup(tp);
607 }
608 break;
609 }
610 SET(tp->t_state, TS_WOPEN);
611 }
612
613 splx(s);
614 if (error == 0)
615 error = (*linesw[tp->t_line].l_open)(dev, tp);
616 return (error);
617 }
618
619 int
620 comclose(dev, flag, mode, p)
621 dev_t dev;
622 int flag, mode;
623 struct proc *p;
624 {
625 int unit = COMUNIT(dev);
626 struct com_softc *sc = com_cd.cd_devs[unit];
627 struct tty *tp = sc->sc_tty;
628 int s;
629
630 /* XXX This is for cons.c. */
631 if (!ISSET(tp->t_state, TS_ISOPEN))
632 return (0);
633
634 (*linesw[tp->t_line].l_close)(tp, flag);
635 ttyclose(tp);
636
637 /* If we were asserting flow control, then deassert it. */
638 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
639 com_hwiflow(sc);
640 /* Clear any break condition set with TIOCSBRK. */
641 com_break(sc, 0);
642 /*
643 * Hang up if necessary. Wait a bit, so the other side has time to
644 * notice even if we immediately open the port again.
645 */
646 if (ISSET(tp->t_cflag, HUPCL)) {
647 com_modem(sc, 0);
648 (void) tsleep(sc, TTIPRI, ttclos, hz);
649 }
650
651 s = splserial();
652 /* Turn off interrupts. */
653 #ifdef DDB
654 if(ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
655 sc->sc_ier = IER_ERXRDY; /* interrupt on break */
656 else
657 #else
658 sc->sc_ier = 0;
659 #endif
660 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
661 splx(s);
662
663 return (0);
664 }
665
666 int
667 comread(dev, uio, flag)
668 dev_t dev;
669 struct uio *uio;
670 int flag;
671 {
672 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
673 struct tty *tp = sc->sc_tty;
674
675 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
676 }
677
678 int
679 comwrite(dev, uio, flag)
680 dev_t dev;
681 struct uio *uio;
682 int flag;
683 {
684 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
685 struct tty *tp = sc->sc_tty;
686
687 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
688 }
689
690 struct tty *
691 comtty(dev)
692 dev_t dev;
693 {
694 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
695 struct tty *tp = sc->sc_tty;
696
697 return (tp);
698 }
699
700 int
701 comioctl(dev, cmd, data, flag, p)
702 dev_t dev;
703 u_long cmd;
704 caddr_t data;
705 int flag;
706 struct proc *p;
707 {
708 int unit = COMUNIT(dev);
709 struct com_softc *sc = com_cd.cd_devs[unit];
710 struct tty *tp = sc->sc_tty;
711 int error;
712
713 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
714 if (error >= 0)
715 return (error);
716
717 error = ttioctl(tp, cmd, data, flag, p);
718 if (error >= 0)
719 return (error);
720
721 switch (cmd) {
722 case TIOCSBRK:
723 com_break(sc, 1);
724 break;
725
726 case TIOCCBRK:
727 com_break(sc, 0);
728 break;
729
730 case TIOCSDTR:
731 com_modem(sc, 1);
732 break;
733
734 case TIOCCDTR:
735 com_modem(sc, 0);
736 break;
737
738 case TIOCGFLAGS:
739 *(int *)data = sc->sc_swflags;
740 break;
741
742 case TIOCSFLAGS:
743 error = suser(p->p_ucred, &p->p_acflag);
744 if (error)
745 return (error);
746 sc->sc_swflags = *(int *)data;
747 break;
748
749 case TIOCMSET:
750 case TIOCMBIS:
751 case TIOCMBIC:
752 case TIOCMGET:
753 default:
754 return (ENOTTY);
755 }
756
757 #ifdef COM_DEBUG
758 if (com_debug)
759 comstatus(sc, "comioctl ");
760 #endif
761
762 return (0);
763 }
764
765 integrate void
766 com_schedrx(sc)
767 struct com_softc *sc;
768 {
769
770 sc->sc_rx_ready = 1;
771
772 /* Wake up the poller. */
773 #ifdef __GENERIC_SOFT_INTERRUPTS
774 softintr_schedule(sc->sc_si);
775 #else
776 #ifndef alpha
777 setsoftserial();
778 #else
779 if (!com_softintr_scheduled) {
780 com_softintr_scheduled = 1;
781 timeout(comsoft, NULL, 1);
782 }
783 #endif
784 #endif
785 }
786
787 void
788 com_break(sc, onoff)
789 struct com_softc *sc;
790 int onoff;
791 {
792 int s;
793
794 s = splserial();
795 if (onoff)
796 SET(sc->sc_lcr, LCR_SBREAK);
797 else
798 CLR(sc->sc_lcr, LCR_SBREAK);
799
800 if (!sc->sc_heldchange) {
801 if (sc->sc_tx_busy) {
802 sc->sc_heldtbc = sc->sc_tbc;
803 sc->sc_tbc = 0;
804 sc->sc_heldchange = 1;
805 } else
806 com_loadchannelregs(sc);
807 }
808 splx(s);
809 }
810
811 void
812 com_modem(sc, onoff)
813 struct com_softc *sc;
814 int onoff;
815 {
816 int s;
817
818 s = splserial();
819 if (onoff)
820 SET(sc->sc_mcr, sc->sc_mcr_dtr);
821 else
822 CLR(sc->sc_mcr, sc->sc_mcr_dtr);
823
824 if (!sc->sc_heldchange) {
825 if (sc->sc_tx_busy) {
826 sc->sc_heldtbc = sc->sc_tbc;
827 sc->sc_tbc = 0;
828 sc->sc_heldchange = 1;
829 } else
830 com_loadchannelregs(sc);
831 }
832 splx(s);
833 }
834
835 int
836 comparam(tp, t)
837 struct tty *tp;
838 struct termios *t;
839 {
840 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
841 int ospeed = comspeed(t->c_ospeed);
842 u_char lcr;
843 int s;
844
845 /* check requested parameters */
846 if (ospeed < 0)
847 return (EINVAL);
848 if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
849 return (EINVAL);
850
851 lcr = ISSET(sc->sc_lcr, LCR_SBREAK);
852
853 switch (ISSET(t->c_cflag, CSIZE)) {
854 case CS5:
855 SET(lcr, LCR_5BITS);
856 break;
857 case CS6:
858 SET(lcr, LCR_6BITS);
859 break;
860 case CS7:
861 SET(lcr, LCR_7BITS);
862 break;
863 case CS8:
864 SET(lcr, LCR_8BITS);
865 break;
866 }
867 if (ISSET(t->c_cflag, PARENB)) {
868 SET(lcr, LCR_PENAB);
869 if (!ISSET(t->c_cflag, PARODD))
870 SET(lcr, LCR_PEVEN);
871 }
872 if (ISSET(t->c_cflag, CSTOPB))
873 SET(lcr, LCR_STOPB);
874
875 s = splserial();
876
877 sc->sc_lcr = lcr;
878
879 /*
880 * For the console, always force CLOCAL and !HUPCL, so that the port
881 * is always active.
882 */
883 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) ||
884 ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
885 SET(t->c_cflag, CLOCAL);
886 CLR(t->c_cflag, HUPCL);
887 }
888
889 /*
890 * If we're not in a mode that assumes a connection is present, then
891 * ignore carrier changes.
892 */
893 if (ISSET(t->c_cflag, CLOCAL | MDMBUF))
894 sc->sc_msr_dcd = 0;
895 else
896 sc->sc_msr_dcd = MSR_DCD;
897 /*
898 * Set the flow control pins depending on the current flow control
899 * mode.
900 */
901 if (ISSET(t->c_cflag, CRTSCTS)) {
902 sc->sc_mcr_dtr = MCR_DTR;
903 sc->sc_mcr_rts = MCR_RTS;
904 sc->sc_msr_cts = MSR_CTS;
905 sc->sc_r_hiwat = RXHIWAT;
906 sc->sc_r_lowat = RXLOWAT;
907 } else if (ISSET(t->c_cflag, MDMBUF)) {
908 /*
909 * For DTR/DCD flow control, make sure we don't toggle DTR for
910 * carrier detection.
911 */
912 sc->sc_mcr_dtr = 0;
913 sc->sc_mcr_rts = MCR_DTR;
914 sc->sc_msr_cts = MSR_DCD;
915 sc->sc_r_hiwat = RXHIWAT;
916 sc->sc_r_lowat = RXLOWAT;
917 } else {
918 /*
919 * If no flow control, then always set RTS. This will make
920 * the other side happy if it mistakenly thinks we're doing
921 * RTS/CTS flow control.
922 */
923 sc->sc_mcr_dtr = MCR_DTR | MCR_RTS;
924 sc->sc_mcr_rts = 0;
925 sc->sc_msr_cts = 0;
926 sc->sc_r_hiwat = 0;
927 sc->sc_r_lowat = 0;
928 if (ISSET(sc->sc_mcr, MCR_DTR))
929 SET(sc->sc_mcr, MCR_RTS);
930 else
931 CLR(sc->sc_mcr, MCR_RTS);
932 }
933 sc->sc_msr_mask = sc->sc_msr_cts | sc->sc_msr_dcd;
934
935 #if 0
936 if (ospeed == 0)
937 CLR(sc->sc_mcr, sc->sc_mcr_dtr);
938 else
939 SET(sc->sc_mcr, sc->sc_mcr_dtr);
940 #endif
941
942 sc->sc_dlbl = ospeed;
943 sc->sc_dlbh = ospeed >> 8;
944
945 /*
946 * Set the FIFO threshold based on the receive speed.
947 *
948 * * If it's a low speed, it's probably a mouse or some other
949 * interactive device, so set the threshold low.
950 * * If it's a high speed, trim the trigger level down to prevent
951 * overflows.
952 * * Otherwise set it a bit higher.
953 */
954 if (ISSET(sc->sc_hwflags, COM_HW_HAYESP))
955 sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8;
956 else if (ISSET(sc->sc_hwflags, COM_HW_FIFO))
957 sc->sc_fifo = FIFO_ENABLE |
958 (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 :
959 t->c_ospeed <= 38400 ? FIFO_TRIGGER_8 : FIFO_TRIGGER_4);
960 else
961 sc->sc_fifo = 0;
962
963 /* and copy to tty */
964 tp->t_ispeed = 0;
965 tp->t_ospeed = t->c_ospeed;
966 tp->t_cflag = t->c_cflag;
967
968 if (!sc->sc_heldchange) {
969 if (sc->sc_tx_busy) {
970 sc->sc_heldtbc = sc->sc_tbc;
971 sc->sc_tbc = 0;
972 sc->sc_heldchange = 1;
973 } else
974 com_loadchannelregs(sc);
975 }
976
977 splx(s);
978
979 /*
980 * Update the tty layer's idea of the carrier bit, in case we changed
981 * CLOCAL or MDMBUF. We don't hang up here; we only do that if we
982 * lose carrier while carrier detection is on.
983 */
984 (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(sc->sc_msr, MSR_DCD));
985
986 #ifdef COM_DEBUG
987 if (com_debug)
988 comstatus(sc, "comparam ");
989 #endif
990
991 /* Block or unblock as needed. */
992 if (!ISSET(t->c_cflag, CHWFLOW)) {
993 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
994 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
995 com_schedrx(sc);
996 }
997 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
998 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
999 com_hwiflow(sc);
1000 }
1001 if (sc->sc_tx_stopped) {
1002 sc->sc_tx_stopped = 0;
1003 comstart(tp);
1004 }
1005 } else {
1006 /* XXXXX FIX ME */
1007 #if 0
1008 commsrint(sc, tp);
1009 #endif
1010 }
1011
1012 return (0);
1013 }
1014
1015 void
1016 com_iflush(sc)
1017 struct com_softc *sc;
1018 {
1019 bus_space_tag_t iot = sc->sc_iot;
1020 bus_space_handle_t ioh = sc->sc_ioh;
1021
1022 /* flush any pending I/O */
1023 while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
1024 (void) bus_space_read_1(iot, ioh, com_data);
1025 }
1026
1027 void
1028 com_loadchannelregs(sc)
1029 struct com_softc *sc;
1030 {
1031 bus_space_tag_t iot = sc->sc_iot;
1032 bus_space_handle_t ioh = sc->sc_ioh;
1033
1034 /* XXXXX necessary? */
1035 com_iflush(sc);
1036
1037 bus_space_write_1(iot, ioh, com_ier, 0);
1038
1039 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr | LCR_DLAB);
1040 bus_space_write_1(iot, ioh, com_dlbl, sc->sc_dlbl);
1041 bus_space_write_1(iot, ioh, com_dlbh, sc->sc_dlbh);
1042 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
1043 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active = sc->sc_mcr);
1044 bus_space_write_1(iot, ioh, com_fifo, sc->sc_fifo);
1045
1046 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1047 }
1048
1049 int
1050 comhwiflow(tp, block)
1051 struct tty *tp;
1052 int block;
1053 {
1054 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
1055 int s;
1056
1057 if (sc->sc_mcr_rts == 0)
1058 return (0);
1059
1060 s = splserial();
1061 if (block) {
1062 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1063 SET(sc->sc_rx_flags, RX_TTY_BLOCKED);
1064 com_hwiflow(sc);
1065 }
1066 } else {
1067 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
1068 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1069 com_schedrx(sc);
1070 }
1071 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1072 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED);
1073 com_hwiflow(sc);
1074 }
1075 }
1076 splx(s);
1077 return (1);
1078 }
1079
1080 /*
1081 * (un)block input via hw flowcontrol
1082 */
1083 void
1084 com_hwiflow(sc)
1085 struct com_softc *sc;
1086 {
1087 bus_space_tag_t iot = sc->sc_iot;
1088 bus_space_handle_t ioh = sc->sc_ioh;
1089
1090 if (sc->sc_mcr_rts == 0)
1091 return;
1092
1093 if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) {
1094 CLR(sc->sc_mcr, sc->sc_mcr_rts);
1095 CLR(sc->sc_mcr_active, sc->sc_mcr_rts);
1096 } else {
1097 SET(sc->sc_mcr, sc->sc_mcr_rts);
1098 SET(sc->sc_mcr_active, sc->sc_mcr_rts);
1099 }
1100 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active);
1101 }
1102
1103
1104 void
1105 comstart(tp)
1106 struct tty *tp;
1107 {
1108 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
1109 bus_space_tag_t iot = sc->sc_iot;
1110 bus_space_handle_t ioh = sc->sc_ioh;
1111 int s;
1112
1113 s = spltty();
1114 if (ISSET(tp->t_state, TS_BUSY))
1115 goto out;
1116 if (ISSET(tp->t_state, TS_TIMEOUT | TS_TTSTOP))
1117 goto stopped;
1118
1119 if (sc->sc_tx_stopped)
1120 goto stopped;
1121
1122 if (tp->t_outq.c_cc <= tp->t_lowat) {
1123 if (ISSET(tp->t_state, TS_ASLEEP)) {
1124 CLR(tp->t_state, TS_ASLEEP);
1125 wakeup(&tp->t_outq);
1126 }
1127 selwakeup(&tp->t_wsel);
1128 if (tp->t_outq.c_cc == 0)
1129 goto stopped;
1130 }
1131
1132 /* Grab the first contiguous region of buffer space. */
1133 {
1134 u_char *tba;
1135 int tbc;
1136
1137 tba = tp->t_outq.c_cf;
1138 tbc = ndqb(&tp->t_outq, 0);
1139
1140 (void)splserial();
1141
1142 sc->sc_tba = tba;
1143 sc->sc_tbc = tbc;
1144 }
1145
1146 SET(tp->t_state, TS_BUSY);
1147 sc->sc_tx_busy = 1;
1148
1149 /* Enable transmit completion interrupts if necessary. */
1150 if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
1151 SET(sc->sc_ier, IER_ETXRDY);
1152 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1153 }
1154
1155 /* Output the first chunk of the contiguous buffer. */
1156 {
1157 int n;
1158
1159 n = sc->sc_fifolen;
1160 if (n > sc->sc_tbc)
1161 n = sc->sc_tbc;
1162 bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n);
1163 sc->sc_tbc -= n;
1164 sc->sc_tba += n;
1165 }
1166 splx(s);
1167 return;
1168
1169 stopped:
1170 /* Disable transmit completion interrupts if necessary. */
1171 if (ISSET(sc->sc_ier, IER_ETXRDY)) {
1172 CLR(sc->sc_ier, IER_ETXRDY);
1173 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1174 }
1175 out:
1176 splx(s);
1177 return;
1178 }
1179
1180 /*
1181 * Stop output on a line.
1182 */
1183 void
1184 comstop(tp, flag)
1185 struct tty *tp;
1186 int flag;
1187 {
1188 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
1189 int s;
1190
1191 s = splserial();
1192 if (ISSET(tp->t_state, TS_BUSY)) {
1193 /* Stop transmitting at the next chunk. */
1194 sc->sc_tbc = 0;
1195 sc->sc_heldtbc = 0;
1196 if (!ISSET(tp->t_state, TS_TTSTOP))
1197 SET(tp->t_state, TS_FLUSH);
1198 }
1199 splx(s);
1200 }
1201
1202 void
1203 comdiag(arg)
1204 void *arg;
1205 {
1206 struct com_softc *sc = arg;
1207 int overflows, floods;
1208 int s;
1209
1210 s = splserial();
1211 overflows = sc->sc_overflows;
1212 sc->sc_overflows = 0;
1213 floods = sc->sc_floods;
1214 sc->sc_floods = 0;
1215 sc->sc_errors = 0;
1216 splx(s);
1217
1218 log(LOG_WARNING,
1219 "%s: %d silo overflow%s, %d ibuf flood%s\n",
1220 sc->sc_dev.dv_xname,
1221 overflows, overflows == 1 ? "" : "s",
1222 floods, floods == 1 ? "" : "s");
1223 }
1224
1225 integrate void
1226 comrxint(sc, tp)
1227 struct com_softc *sc;
1228 struct tty *tp;
1229 {
1230 u_int get, cc, scc;
1231 int code;
1232 u_char lsr;
1233 int s;
1234 static int lsrmap[8] = {
1235 0, TTY_PE,
1236 TTY_FE, TTY_PE|TTY_FE,
1237 TTY_FE, TTY_PE|TTY_FE,
1238 TTY_FE, TTY_PE|TTY_FE
1239 };
1240
1241 get = sc->sc_rbget;
1242 scc = cc = RXBUFSIZE - sc->sc_rbavail;
1243
1244 if (cc == RXBUFSIZE) {
1245 sc->sc_floods++;
1246 if (sc->sc_errors++ == 0)
1247 timeout(comdiag, sc, 60 * hz);
1248 }
1249
1250 while (cc) {
1251 lsr = sc->sc_lbuf[get];
1252 if (ISSET(lsr, LSR_OE)) {
1253 sc->sc_overflows++;
1254 if (sc->sc_errors++ == 0)
1255 timeout(comdiag, sc, 60 * hz);
1256 }
1257 code = sc->sc_rbuf[get] |
1258 lsrmap[(lsr & (LSR_BI|LSR_FE|LSR_PE)) >> 2];
1259 if ((*linesw[tp->t_line].l_rint)(code, tp) == -1) {
1260 /*
1261 * The line discipline's buffer is out of space.
1262 */
1263 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1264 /*
1265 * We're either not using flow control, or the
1266 * line discipline didn't tell us to block for
1267 * some reason. Either way, we have no way to
1268 * know when there's more space available, so
1269 * just drop the rest of the data.
1270 */
1271 get = (get + cc) & RXBUFMASK;
1272 cc = 0;
1273 } else {
1274 /*
1275 * Don't schedule any more receive processing
1276 * until the line discipline tells us there's
1277 * space available (through comhwiflow()).
1278 * Leave the rest of the data in the input
1279 * buffer.
1280 */
1281 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1282 }
1283 break;
1284 }
1285 get = (get + 1) & RXBUFMASK;
1286 cc--;
1287 }
1288
1289 if (cc != scc) {
1290 sc->sc_rbget = get;
1291 s = splserial();
1292 cc = sc->sc_rbavail += scc - cc;
1293 /* Buffers should be ok again, release possible block. */
1294 if (cc >= sc->sc_r_lowat) {
1295 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
1296 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
1297 SET(sc->sc_ier, IER_ERXRDY);
1298 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
1299 }
1300 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
1301 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
1302 com_hwiflow(sc);
1303 }
1304 }
1305 splx(s);
1306 }
1307 }
1308
1309 integrate void
1310 comtxint(sc, tp)
1311 struct com_softc *sc;
1312 struct tty *tp;
1313 {
1314
1315 CLR(tp->t_state, TS_BUSY);
1316 if (ISSET(tp->t_state, TS_FLUSH))
1317 CLR(tp->t_state, TS_FLUSH);
1318 else
1319 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
1320 (*linesw[tp->t_line].l_start)(tp);
1321 }
1322
1323 integrate void
1324 commsrint(sc, tp)
1325 struct com_softc *sc;
1326 struct tty *tp;
1327 {
1328 u_char msr, delta;
1329 int s;
1330
1331 s = splserial();
1332 msr = sc->sc_msr;
1333 delta = sc->sc_msr_delta;
1334 sc->sc_msr_delta = 0;
1335 splx(s);
1336
1337 if (ISSET(delta, sc->sc_msr_dcd)) {
1338 /*
1339 * Inform the tty layer that carrier detect changed.
1340 */
1341 (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD));
1342 }
1343
1344 if (ISSET(delta, sc->sc_msr_cts)) {
1345 /* Block or unblock output according to flow control. */
1346 if (ISSET(msr, sc->sc_msr_cts)) {
1347 sc->sc_tx_stopped = 0;
1348 (*linesw[tp->t_line].l_start)(tp);
1349 } else {
1350 sc->sc_tx_stopped = 1;
1351 }
1352 }
1353
1354 #ifdef COM_DEBUG
1355 if (com_debug)
1356 comstatus(sc, "commsrint");
1357 #endif
1358 }
1359
1360 #ifdef __GENERIC_SOFT_INTERRUPTS
1361 void
1362 comsoft(arg)
1363 void *arg;
1364 {
1365 struct com_softc *sc = arg;
1366 struct tty *tp;
1367
1368 {
1369 #else
1370 void
1371 #ifndef alpha
1372 comsoft()
1373 #else
1374 comsoft(arg)
1375 void *arg;
1376 #endif
1377 {
1378 struct com_softc *sc;
1379 struct tty *tp;
1380 int unit;
1381 #ifdef alpha
1382 int s;
1383
1384 s = splsoftserial();
1385 com_softintr_scheduled = 0;
1386 #endif
1387
1388 for (unit = 0; unit < com_cd.cd_ndevs; unit++) {
1389 sc = com_cd.cd_devs[unit];
1390 if (sc == NULL)
1391 continue;
1392 #endif
1393
1394 tp = sc->sc_tty;
1395 if (tp == NULL || !ISSET(tp->t_state, TS_ISOPEN | TS_WOPEN))
1396 continue;
1397
1398 if (sc->sc_rx_ready) {
1399 sc->sc_rx_ready = 0;
1400 comrxint(sc, tp);
1401 }
1402
1403 if (sc->sc_st_check) {
1404 sc->sc_st_check = 0;
1405 commsrint(sc, tp);
1406 }
1407
1408 if (sc->sc_tx_done) {
1409 sc->sc_tx_done = 0;
1410 comtxint(sc, tp);
1411 }
1412 }
1413
1414 #ifndef __GENERIC_SOFT_INTERRUPTS
1415 #ifdef alpha
1416 splx(s);
1417 #endif
1418 #endif
1419 }
1420
1421 int
1422 comintr(arg)
1423 void *arg;
1424 {
1425 struct com_softc *sc = arg;
1426 bus_space_tag_t iot = sc->sc_iot;
1427 bus_space_handle_t ioh = sc->sc_ioh;
1428 u_char lsr, iir;
1429 u_int put, cc;
1430
1431 iir = bus_space_read_1(iot, ioh, com_iir);
1432 if (ISSET(iir, IIR_NOPEND))
1433 return (0);
1434
1435 put = sc->sc_rbput;
1436 cc = sc->sc_rbavail;
1437
1438 do {
1439 u_char msr, delta;
1440
1441 lsr = bus_space_read_1(iot, ioh, com_lsr);
1442 #if defined(DDB) || defined(KGDB)
1443 if (ISSET(lsr, LSR_BI)) {
1444 #ifdef DDB
1445 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
1446 Debugger();
1447 continue;
1448 }
1449 #endif
1450 #ifdef KGDB
1451 if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) {
1452 kgdb_connect(1);
1453 continue;
1454 }
1455 #endif
1456 }
1457 #endif /* DDB || KGDB */
1458
1459 if (ISSET(lsr, LSR_RCV_MASK) &&
1460 !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
1461 for (; ISSET(lsr, LSR_RCV_MASK) && cc > 0; cc--) {
1462 sc->sc_rbuf[put] =
1463 bus_space_read_1(iot, ioh, com_data);
1464 sc->sc_lbuf[put] = lsr;
1465 put = (put + 1) & RXBUFMASK;
1466 lsr = bus_space_read_1(iot, ioh, com_lsr);
1467 }
1468 /*
1469 * Current string of incoming characters ended because
1470 * no more data was available. Schedule a receive event
1471 * if any data was received. Drop any characters that
1472 * we couldn't handle.
1473 */
1474 sc->sc_rbput = put;
1475 sc->sc_rbavail = cc;
1476 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
1477 sc->sc_rx_ready = 1;
1478 /*
1479 * See if we are in danger of overflowing a buffer. If
1480 * so, use hardware flow control to ease the pressure.
1481 */
1482 if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) &&
1483 cc < sc->sc_r_hiwat) {
1484 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
1485 com_hwiflow(sc);
1486 }
1487 /*
1488 * If we're out of space, disable receive interrupts
1489 * until the queue has drained a bit.
1490 */
1491 if (!cc) {
1492 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
1493 CLR(sc->sc_ier, IER_ERXRDY);
1494 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1495 }
1496 } else {
1497 if ((iir & IIR_IMASK) == IIR_RXRDY) {
1498 bus_space_write_1(iot, ioh, com_ier, 0);
1499 delay(10);
1500 bus_space_write_1(iot, ioh, com_ier,sc->sc_ier);
1501 iir = IIR_NOPEND;
1502 continue;
1503 }
1504 }
1505
1506 msr = bus_space_read_1(iot, ioh, com_msr);
1507 delta = msr ^ sc->sc_msr;
1508 sc->sc_msr = msr;
1509 if (ISSET(delta, sc->sc_msr_mask)) {
1510 sc->sc_msr_delta |= delta;
1511
1512 /*
1513 * Stop output immediately if we lose the output
1514 * flow control signal or carrier detect.
1515 */
1516 if (ISSET(~msr, sc->sc_msr_mask)) {
1517 sc->sc_tbc = 0;
1518 sc->sc_heldtbc = 0;
1519 #ifdef COM_DEBUG
1520 if (com_debug)
1521 comstatus(sc, "comintr ");
1522 #endif
1523 }
1524
1525 sc->sc_st_check = 1;
1526 }
1527 } while (!ISSET((iir = bus_space_read_1(iot, ioh, com_iir)), IIR_NOPEND));
1528
1529 /*
1530 * Done handling any receive interrupts. See if data can be
1531 * transmitted as well. Schedule tx done event if no data left
1532 * and tty was marked busy.
1533 */
1534 if (ISSET(lsr, LSR_TXRDY)) {
1535 /*
1536 * If we've delayed a parameter change, do it now, and restart
1537 * output.
1538 */
1539 if (sc->sc_heldchange) {
1540 com_loadchannelregs(sc);
1541 sc->sc_heldchange = 0;
1542 sc->sc_tbc = sc->sc_heldtbc;
1543 sc->sc_heldtbc = 0;
1544 }
1545 /* Output the next chunk of the contiguous buffer, if any. */
1546 if (sc->sc_tbc > 0) {
1547 int n;
1548
1549 n = sc->sc_fifolen;
1550 if (n > sc->sc_tbc)
1551 n = sc->sc_tbc;
1552 bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n);
1553 sc->sc_tbc -= n;
1554 sc->sc_tba += n;
1555 } else if (sc->sc_tx_busy) {
1556 sc->sc_tx_busy = 0;
1557 sc->sc_tx_done = 1;
1558 }
1559 }
1560
1561 /* Wake up the poller. */
1562 #ifdef __GENERIC_SOFT_INTERRUPTS
1563 softintr_schedule(sc->sc_si);
1564 #else
1565 #ifndef alpha
1566 setsoftserial();
1567 #else
1568 if (!com_softintr_scheduled) {
1569 com_softintr_scheduled = 1;
1570 timeout(comsoft, NULL, 1);
1571 }
1572 #endif
1573 #endif
1574 return (1);
1575 }
1576
1577 /*
1578 * The following functions are polled getc and putc routines, shared
1579 * by the console and kgdb glue.
1580 */
1581
1582 int
1583 com_common_getc(iot, ioh)
1584 bus_space_tag_t iot;
1585 bus_space_handle_t ioh;
1586 {
1587 int s = splserial();
1588 u_char stat, c;
1589
1590 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
1591 ;
1592 c = bus_space_read_1(iot, ioh, com_data);
1593 stat = bus_space_read_1(iot, ioh, com_iir);
1594 splx(s);
1595 return (c);
1596 }
1597
1598 void
1599 com_common_putc(iot, ioh, c)
1600 bus_space_tag_t iot;
1601 bus_space_handle_t ioh;
1602 int c;
1603 {
1604 int s = splserial();
1605 u_char stat;
1606 register int timo;
1607
1608 /* wait for any pending transmission to finish */
1609 timo = 50000;
1610 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY)
1611 && --timo)
1612 ;
1613 bus_space_write_1(iot, ioh, com_data, c);
1614 /* wait for this transmission to complete */
1615 timo = 1500000;
1616 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY)
1617 && --timo)
1618 ;
1619 /* clear any interrupts generated by this transmission */
1620 stat = bus_space_read_1(iot, ioh, com_iir);
1621 splx(s);
1622 }
1623
1624 /*
1625 * Following are all routines needed for COM to act as console
1626 */
1627 #include <dev/cons.h>
1628
1629 void
1630 comcnprobe(cp)
1631 struct consdev *cp;
1632 {
1633 /* XXX NEEDS TO BE FIXED XXX */
1634 bus_space_tag_t iot = 0;
1635 bus_space_handle_t ioh;
1636 int found;
1637
1638 if (bus_space_map(iot, CONADDR, COM_NPORTS, 0, &ioh)) {
1639 cp->cn_pri = CN_DEAD;
1640 return;
1641 }
1642 found = comprobe1(iot, ioh, CONADDR);
1643 bus_space_unmap(iot, ioh, COM_NPORTS);
1644 if (!found) {
1645 cp->cn_pri = CN_DEAD;
1646 return;
1647 }
1648
1649 /* locate the major number */
1650 for (commajor = 0; commajor < nchrdev; commajor++)
1651 if (cdevsw[commajor].d_open == comopen)
1652 break;
1653
1654 /* initialize required fields */
1655 cp->cn_dev = makedev(commajor, CONUNIT);
1656 #ifdef COMCONSOLE
1657 cp->cn_pri = CN_REMOTE; /* Force a serial port console */
1658 #else
1659 cp->cn_pri = CN_NORMAL;
1660 #endif
1661 }
1662
1663 void
1664 comcninit(cp)
1665 struct consdev *cp;
1666 {
1667
1668 #if 0
1669 XXX NEEDS TO BE FIXED XXX
1670 comconstag = ???;
1671 #endif
1672 if (bus_space_map(comconstag, CONADDR, COM_NPORTS, 0, &comconsioh))
1673 panic("comcninit: mapping failed");
1674
1675 cominitcons(comconstag, comconsioh, comconsrate);
1676 comconsaddr = CONADDR;
1677 }
1678
1679 /*
1680 * Initialize UART to known state.
1681 */
1682 void
1683 cominit(iot, ioh, rate)
1684 bus_space_tag_t iot;
1685 bus_space_handle_t ioh;
1686 int rate;
1687 {
1688
1689 bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);
1690 rate = comspeed(rate);
1691 bus_space_write_1(iot, ioh, com_dlbl, rate);
1692 bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
1693 bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS);
1694 bus_space_write_1(iot, ioh, com_mcr, 0);
1695 bus_space_write_1(iot, ioh, com_fifo,
1696 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
1697 bus_space_write_1(iot, ioh, com_ier, 0);
1698 }
1699
1700 /*
1701 * Set UART for console use. Do normal init, then enable interrupts.
1702 */
1703 void
1704 cominitcons(iot, ioh, rate)
1705 bus_space_tag_t iot;
1706 bus_space_handle_t ioh;
1707 int rate;
1708 {
1709 int s = splserial();
1710 u_char stat;
1711
1712 cominit(iot, ioh, rate);
1713 bus_space_write_1(iot, ioh, com_ier, IER_ERXRDY | IER_ETXRDY);
1714 bus_space_write_1(iot, ioh, com_mcr, MCR_DTR | MCR_RTS);
1715 DELAY(100);
1716 stat = bus_space_read_1(iot, ioh, com_iir);
1717 splx(s);
1718 }
1719
1720 int
1721 comcngetc(dev)
1722 dev_t dev;
1723 {
1724
1725 return (com_common_getc(comconstag, comconsioh));
1726 }
1727
1728 /*
1729 * Console kernel output character routine.
1730 */
1731 void
1732 comcnputc(dev, c)
1733 dev_t dev;
1734 int c;
1735 {
1736
1737 com_common_putc(comconstag, comconsioh, c);
1738 }
1739
1740 void
1741 comcnpollc(dev, on)
1742 dev_t dev;
1743 int on;
1744 {
1745
1746 }
1747