com.c revision 1.143 1 /* $NetBSD: com.c,v 1.143 1998/03/22 00:55:37 mycroft Exp $ */
2
3 /*-
4 * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
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 * Supports automatic hardware flow control on StarTech ST16C650A UART
74 */
75
76 #include "rnd.h"
77 #if NRND > 0 && defined(RND_COM)
78 #include <sys/rnd.h>
79 #endif
80
81 #include <sys/param.h>
82 #include <sys/systm.h>
83 #include <sys/ioctl.h>
84 #include <sys/select.h>
85 #include <sys/tty.h>
86 #include <sys/proc.h>
87 #include <sys/user.h>
88 #include <sys/conf.h>
89 #include <sys/file.h>
90 #include <sys/uio.h>
91 #include <sys/kernel.h>
92 #include <sys/syslog.h>
93 #include <sys/types.h>
94 #include <sys/device.h>
95 #include <sys/malloc.h>
96
97 #include <machine/intr.h>
98 #include <machine/bus.h>
99
100 #include <dev/ic/comreg.h>
101 #include <dev/ic/comvar.h>
102 #include <dev/ic/ns16550reg.h>
103 #include <dev/ic/st16650reg.h>
104 #ifdef COM_HAYESP
105 #include <dev/ic/hayespreg.h>
106 #endif
107 #define com_lcr com_cfcr
108 #include <dev/cons.h>
109
110 #include "com.h"
111
112 #ifdef COM_HAYESP
113 int comprobeHAYESP __P((bus_space_handle_t hayespioh, struct com_softc *sc));
114 #endif
115
116 #if defined(DDB) || defined(KGDB)
117 static void com_enable_debugport __P((struct com_softc *));
118 #endif
119 void com_attach_subr __P((struct com_softc *sc));
120 void com_config __P((struct com_softc *));
121 void com_shutdown __P((struct com_softc *));
122 int comspeed __P((long, long));
123 static u_char cflag2lcr __P((tcflag_t));
124 int comparam __P((struct tty *, struct termios *));
125 void comstart __P((struct tty *));
126 void comstop __P((struct tty *, int));
127 int comhwiflow __P((struct tty *, int));
128
129 void com_loadchannelregs __P((struct com_softc *));
130 void com_hwiflow __P((struct com_softc *));
131 void com_break __P((struct com_softc *, int));
132 void com_modem __P((struct com_softc *, int));
133 void com_iflush __P((struct com_softc *));
134
135 int com_common_getc __P((bus_space_tag_t, bus_space_handle_t));
136 void com_common_putc __P((bus_space_tag_t, bus_space_handle_t, int));
137
138 /* XXX: These belong elsewhere */
139 cdev_decl(com);
140 bdev_decl(com);
141
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 #ifdef __GENERIC_SOFT_INTERRUPTS
148 void comsoft __P((void *));
149 #else
150 #ifndef __NO_SOFT_SERIAL_INTERRUPT
151 void comsoft __P((void));
152 #else
153 void comsoft __P((void *));
154 #endif
155 #endif
156 integrate void com_rxsoft __P((struct com_softc *, struct tty *));
157 integrate void com_txsoft __P((struct com_softc *, struct tty *));
158 integrate void com_stsoft __P((struct com_softc *, struct tty *));
159 integrate void com_schedrx __P((struct com_softc *));
160 void comdiag __P((void *));
161
162 extern struct cfdriver com_cd;
163
164 /*
165 * Make this an option variable one can patch.
166 * But be warned: this must be a power of 2!
167 */
168 u_int com_rbuf_size = COM_RING_SIZE;
169
170 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
171 u_int com_rbuf_hiwat = (COM_RING_SIZE * 1) / 4;
172 u_int com_rbuf_lowat = (COM_RING_SIZE * 3) / 4;
173
174 static int comconsaddr;
175 static bus_space_tag_t comconstag;
176 static bus_space_handle_t comconsioh;
177 static int comconsattached;
178 static int comconsrate;
179 static tcflag_t comconscflag;
180
181 static u_char tiocm_xxx2mcr __P((int));
182
183 #ifndef __GENERIC_SOFT_INTERRUPTS
184 #ifdef __NO_SOFT_SERIAL_INTERRUPT
185 volatile int com_softintr_scheduled;
186 #endif
187 #endif
188
189 #ifdef KGDB
190 #include <sys/kgdb.h>
191
192 static int com_kgdb_addr;
193 static bus_space_tag_t com_kgdb_iot;
194 static bus_space_handle_t com_kgdb_ioh;
195 static int com_kgdb_attached;
196
197 int com_kgdb_getc __P((void *));
198 void com_kgdb_putc __P((void *, int));
199 #endif /* KGDB */
200
201 #define COMUNIT(x) (minor(x) & 0x7ffff)
202 #define COMDIALOUT(x) (minor(x) & 0x80000)
203
204 int
205 comspeed(speed, frequency)
206 long speed, frequency;
207 {
208 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
209
210 int x, err;
211
212 #if 0
213 if (speed == 0)
214 return (0);
215 #endif
216 if (speed <= 0)
217 return (-1);
218 x = divrnd(frequency / 16, speed);
219 if (x <= 0)
220 return (-1);
221 err = divrnd(((quad_t)frequency) * 1000 / 16, speed * x) - 1000;
222 if (err < 0)
223 err = -err;
224 if (err > COM_TOLERANCE)
225 return (-1);
226 return (x);
227
228 #undef divrnd(n, q)
229 }
230
231 #ifdef COM_DEBUG
232 int com_debug = 0;
233
234 void comstatus __P((struct com_softc *, char *));
235 void
236 comstatus(sc, str)
237 struct com_softc *sc;
238 char *str;
239 {
240 struct tty *tp = sc->sc_tty;
241
242 printf("%s: %s %sclocal %sdcd %sts_carr_on %sdtr %stx_stopped\n",
243 sc->sc_dev.dv_xname, str,
244 ISSET(tp->t_cflag, CLOCAL) ? "+" : "-",
245 ISSET(sc->sc_msr, MSR_DCD) ? "+" : "-",
246 ISSET(tp->t_state, TS_CARR_ON) ? "+" : "-",
247 ISSET(sc->sc_mcr, MCR_DTR) ? "+" : "-",
248 sc->sc_tx_stopped ? "+" : "-");
249
250 printf("%s: %s %scrtscts %scts %sts_ttstop %srts %xrx_flags\n",
251 sc->sc_dev.dv_xname, str,
252 ISSET(tp->t_cflag, CRTSCTS) ? "+" : "-",
253 ISSET(sc->sc_msr, MSR_CTS) ? "+" : "-",
254 ISSET(tp->t_state, TS_TTSTOP) ? "+" : "-",
255 ISSET(sc->sc_mcr, MCR_RTS) ? "+" : "-",
256 sc->sc_rx_flags);
257 }
258 #endif
259
260 int
261 comprobe1(iot, ioh, iobase)
262 bus_space_tag_t iot;
263 bus_space_handle_t ioh;
264 int iobase;
265 {
266
267 /* force access to id reg */
268 bus_space_write_1(iot, ioh, com_lcr, 0);
269 bus_space_write_1(iot, ioh, com_iir, 0);
270 if (bus_space_read_1(iot, ioh, com_iir) & 0x38)
271 return (0);
272
273 return (1);
274 }
275
276 #ifdef COM_HAYESP
277 int
278 comprobeHAYESP(hayespioh, sc)
279 bus_space_handle_t hayespioh;
280 struct com_softc *sc;
281 {
282 char val, dips;
283 int combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
284 bus_space_tag_t iot = sc->sc_iot;
285
286 /*
287 * Hayes ESP cards have two iobases. One is for compatibility with
288 * 16550 serial chips, and at the same ISA PC base addresses. The
289 * other is for ESP-specific enhanced features, and lies at a
290 * different addressing range entirely (0x140, 0x180, 0x280, or 0x300).
291 */
292
293 /* Test for ESP signature */
294 if ((bus_space_read_1(iot, hayespioh, 0) & 0xf3) == 0)
295 return (0);
296
297 /*
298 * ESP is present at ESP enhanced base address; unknown com port
299 */
300
301 /* Get the dip-switch configurations */
302 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETDIPS);
303 dips = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1);
304
305 /* Determine which com port this ESP card services: bits 0,1 of */
306 /* dips is the port # (0-3); combaselist[val] is the com_iobase */
307 if (sc->sc_iobase != combaselist[dips & 0x03])
308 return (0);
309
310 printf(": ESP");
311
312 /* Check ESP Self Test bits. */
313 /* Check for ESP version 2.0: bits 4,5,6 == 010 */
314 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETTEST);
315 val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1); /* Clear reg1 */
316 val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS2);
317 if ((val & 0x70) < 0x20) {
318 printf("-old (%o)", val & 0x70);
319 /* we do not support the necessary features */
320 return (0);
321 }
322
323 /* Check for ability to emulate 16550: bit 8 == 1 */
324 if ((dips & 0x80) == 0) {
325 printf(" slave");
326 /* XXX Does slave really mean no 16550 support?? */
327 return (0);
328 }
329
330 /*
331 * If we made it this far, we are a full-featured ESP v2.0 (or
332 * better), at the correct com port address.
333 */
334
335 SET(sc->sc_hwflags, COM_HW_HAYESP);
336 printf(", 1024 byte fifo\n");
337 return (1);
338 }
339 #endif
340
341 #if defined(DDB) || defined(KGDB)
342 static void
343 com_enable_debugport(sc)
344 struct com_softc *sc;
345 {
346 int s;
347
348 /* Turn on line break interrupt, set carrier. */
349 s = splserial();
350 sc->sc_ier = IER_ERXRDY;
351 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
352 SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
353 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
354 splx(s);
355 }
356 #endif
357
358 void
359 com_attach_subr(sc)
360 struct com_softc *sc;
361 {
362 int iobase = sc->sc_iobase;
363 bus_space_tag_t iot = sc->sc_iot;
364 bus_space_handle_t ioh = sc->sc_ioh;
365 struct tty *tp;
366 #ifdef COM16650
367 u_int8_t lcr;
368 #endif
369 #ifdef COM_HAYESP
370 int hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 };
371 int *hayespp;
372 #endif
373
374 /* Disable interrupts before configuring the device. */
375 sc->sc_ier = 0;
376 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
377
378 if (iot == comconstag && iobase == comconsaddr) {
379 comconsattached = 1;
380
381 /* Make sure the console is always "hardwired". */
382 delay(1000); /* wait for output to finish */
383 SET(sc->sc_hwflags, COM_HW_CONSOLE);
384 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
385 }
386
387 #ifdef COM_HAYESP
388 /* Look for a Hayes ESP board. */
389 for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) {
390 bus_space_handle_t hayespioh;
391
392 #define HAYESP_NPORTS 8 /* XXX XXX XXX ??? ??? ??? */
393 if (bus_space_map(iot, *hayespp, HAYESP_NPORTS, 0, &hayespioh))
394 continue;
395 if (comprobeHAYESP(hayespioh, sc)) {
396 sc->sc_hayespioh = hayespioh;
397 sc->sc_fifolen = 1024;
398
399 break;
400 }
401 bus_space_unmap(iot, hayespioh, HAYESP_NPORTS);
402 }
403 /* No ESP; look for other things. */
404 if (!ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
405 #endif
406 sc->sc_fifolen = 1;
407 /* look for a NS 16550AF UART with FIFOs */
408 bus_space_write_1(iot, ioh, com_fifo,
409 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
410 delay(100);
411 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_FIFO_MASK)
412 == IIR_FIFO_MASK)
413 if (ISSET(bus_space_read_1(iot, ioh, com_fifo), FIFO_TRIGGER_14)
414 == FIFO_TRIGGER_14) {
415 SET(sc->sc_hwflags, COM_HW_FIFO);
416
417 #ifdef COM16650
418 /*
419 * IIR changes into the EFR if LCR is set to LCR_EERS
420 * on 16650s. We also know IIR != 0 at this point.
421 * Write 0 into the EFR, and read it. If the result
422 * is 0, we have a 16650.
423 *
424 * Older 16650s were broken; the test to detect them
425 * is taken from the Linux driver. Apparently
426 * setting DLAB enable gives access to the EFR on
427 * these chips.
428 */
429 lcr = bus_space_read_1(iot, ioh, com_lcr);
430 bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
431 bus_space_write_1(iot, ioh, com_efr, 0);
432 if (bus_space_read_1(iot, ioh, com_efr) == 0) {
433 bus_space_write_1(iot, ioh, com_lcr,
434 lcr | LCR_DLAB);
435 if (bus_space_read_1(iot, ioh, com_efr) == 0) {
436 CLR(sc->sc_hwflags, COM_HW_FIFO);
437 sc->sc_fifolen = 0;
438 } else {
439 SET(sc->sc_hwflags, COM_HW_FLOW);
440 sc->sc_fifolen = 32;
441 }
442 } else
443 #endif
444 sc->sc_fifolen = 16;
445
446 #ifdef COM16650
447 bus_space_write_1(iot, ioh, com_lcr, lcr);
448 if (sc->sc_fifolen == 0)
449 printf(": st16650, broken fifo\n");
450 else if (sc->sc_fifolen == 32)
451 printf(": st16650a, working fifo\n");
452 else
453 #endif
454 printf(": ns16550a, working fifo\n");
455 } else
456 printf(": ns16550, broken fifo\n");
457 else
458 printf(": ns8250 or ns16450, no fifo\n");
459 bus_space_write_1(iot, ioh, com_fifo, 0);
460 #ifdef COM_HAYESP
461 }
462 #endif
463
464 tp = ttymalloc();
465 tp->t_oproc = comstart;
466 tp->t_param = comparam;
467 tp->t_hwiflow = comhwiflow;
468 tty_attach(tp);
469
470 sc->sc_tty = tp;
471 sc->sc_rbuf = malloc(com_rbuf_size << 1, M_DEVBUF, M_WAITOK);
472 sc->sc_ebuf = sc->sc_rbuf + (com_rbuf_size << 1);
473
474 if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
475 SET(sc->sc_mcr, MCR_IENABLE);
476
477 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
478 int maj;
479
480 /* locate the major number */
481 for (maj = 0; maj < nchrdev; maj++)
482 if (cdevsw[maj].d_open == comopen)
483 break;
484
485 cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
486
487 printf("%s: console\n", sc->sc_dev.dv_xname);
488 }
489
490 #ifdef KGDB
491 /*
492 * Allow kgdb to "take over" this port. If this is
493 * the kgdb device, it has exclusive use.
494 */
495 if (iot == com_kgdb_iot && iobase == com_kgdb_addr) {
496 com_kgdb_attached = 1;
497
498 SET(sc->sc_hwflags, COM_HW_KGDB);
499 printf("%s: kgdb\n", sc->sc_dev.dv_xname);
500 }
501 #endif
502
503 #ifdef __GENERIC_SOFT_INTERRUPTS
504 sc->sc_si = softintr_establish(IPL_SOFTSERIAL, comsoft, sc);
505 #endif
506
507 #if NRND > 0 && defined(RND_COM)
508 rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
509 RND_TYPE_TTY);
510 #endif
511
512 /* if there are no enable/disable functions, assume the device
513 is always enabled */
514 if (!sc->enable)
515 sc->enabled = 1;
516
517 com_config(sc);
518
519 SET(sc->sc_hwflags, COM_HW_DEV_OK);
520 }
521
522 void
523 com_config(sc)
524 struct com_softc *sc;
525 {
526 bus_space_tag_t iot = sc->sc_iot;
527 bus_space_handle_t ioh = sc->sc_ioh;
528
529 /* Disable interrupts before configuring the device. */
530 sc->sc_ier = 0;
531 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
532
533 #ifdef COM_HAYESP
534 /* Look for a Hayes ESP board. */
535 if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
536 sc->sc_fifolen = 1024;
537
538 /* Set 16550 compatibility mode */
539 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
540 HAYESP_SETMODE);
541 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
542 HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
543 HAYESP_MODE_SCALE);
544
545 /* Set RTS/CTS flow control */
546 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
547 HAYESP_SETFLOWTYPE);
548 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
549 HAYESP_FLOW_RTS);
550 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
551 HAYESP_FLOW_CTS);
552
553 /* Set flow control levels */
554 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
555 HAYESP_SETRXFLOW);
556 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
557 HAYESP_HIBYTE(HAYESP_RXHIWMARK));
558 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
559 HAYESP_LOBYTE(HAYESP_RXHIWMARK));
560 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
561 HAYESP_HIBYTE(HAYESP_RXLOWMARK));
562 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
563 HAYESP_LOBYTE(HAYESP_RXLOWMARK));
564 }
565 #endif
566
567 #ifdef DDB
568 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
569 com_enable_debugport(sc);
570 #endif
571
572 #ifdef KGDB
573 /*
574 * Allow kgdb to "take over" this port. If this is
575 * the kgdb device, it has exclusive use.
576 */
577 if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
578 com_enable_debugport(sc);
579 #endif
580 }
581
582 void
583 com_shutdown(sc)
584 struct com_softc *sc;
585 {
586 struct tty *tp = sc->sc_tty;
587 int s;
588
589 s = splserial();
590
591 /* If we were asserting flow control, then deassert it. */
592 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
593 com_hwiflow(sc);
594
595 /* Clear any break condition set with TIOCSBRK. */
596 com_break(sc, 0);
597
598 /*
599 * Hang up if necessary. Wait a bit, so the other side has time to
600 * notice even if we immediately open the port again.
601 */
602 if (ISSET(tp->t_cflag, HUPCL)) {
603 com_modem(sc, 0);
604 (void) tsleep(sc, TTIPRI, ttclos, hz);
605 }
606
607 /* Turn off interrupts. */
608 #ifdef DDB
609 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
610 sc->sc_ier = IER_ERXRDY; /* interrupt on break */
611 else
612 #endif
613 sc->sc_ier = 0;
614 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
615
616 if (sc->disable) {
617 #ifdef DIAGNOSTIC
618 if (!sc->enabled)
619 panic("com_shutdown: not enabled?");
620 #endif
621 (*sc->disable)(sc);
622 sc->enabled = 0;
623 }
624
625 splx(s);
626 }
627
628 int
629 comopen(dev, flag, mode, p)
630 dev_t dev;
631 int flag, mode;
632 struct proc *p;
633 {
634 int unit = COMUNIT(dev);
635 struct com_softc *sc;
636 struct tty *tp;
637 int s, s2;
638 int error;
639
640 if (unit >= com_cd.cd_ndevs)
641 return (ENXIO);
642 sc = com_cd.cd_devs[unit];
643 if (sc == 0 || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK))
644 return (ENXIO);
645
646 #ifdef KGDB
647 /*
648 * If this is the kgdb port, no other use is permitted.
649 */
650 if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
651 return (EBUSY);
652 #endif
653
654 tp = sc->sc_tty;
655
656 if (ISSET(tp->t_state, TS_ISOPEN) &&
657 ISSET(tp->t_state, TS_XCLUDE) &&
658 p->p_ucred->cr_uid != 0)
659 return (EBUSY);
660
661 s = spltty();
662
663 /*
664 * Do the following iff this is a first open.
665 */
666 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
667 struct termios t;
668
669 tp->t_dev = dev;
670
671 s2 = splserial();
672
673 if (sc->enable) {
674 if ((*sc->enable)(sc)) {
675 splx(s2);
676 splx(s);
677 printf("%s: device enable failed\n",
678 sc->sc_dev.dv_xname);
679 return (EIO);
680 }
681 sc->enabled = 1;
682 com_config(sc);
683 }
684
685 /* Turn on interrupts. */
686 sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
687 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
688
689 /* Fetch the current modem control status, needed later. */
690 sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr);
691
692 splx(s2);
693
694 /*
695 * Initialize the termios status to the defaults. Add in the
696 * sticky bits from TIOCSFLAGS.
697 */
698 t.c_ispeed = 0;
699 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
700 t.c_ospeed = comconsrate;
701 t.c_cflag = comconscflag;
702 } else {
703 t.c_ospeed = TTYDEF_SPEED;
704 t.c_cflag = TTYDEF_CFLAG;
705 }
706 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
707 SET(t.c_cflag, CLOCAL);
708 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
709 SET(t.c_cflag, CRTSCTS);
710 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
711 SET(t.c_cflag, MDMBUF);
712 /* Make sure comparam() will do something. */
713 tp->t_ospeed = 0;
714 (void) comparam(tp, &t);
715 tp->t_iflag = TTYDEF_IFLAG;
716 tp->t_oflag = TTYDEF_OFLAG;
717 tp->t_lflag = TTYDEF_LFLAG;
718 ttychars(tp);
719 ttsetwater(tp);
720
721 s2 = splserial();
722
723 /*
724 * Turn on DTR. We must always do this, even if carrier is not
725 * present, because otherwise we'd have to use TIOCSDTR
726 * immediately after setting CLOCAL, which applications do not
727 * expect. We always assert DTR while the device is open
728 * unless explicitly requested to deassert it.
729 */
730 com_modem(sc, 1);
731
732 /* Clear the input ring, and unblock. */
733 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
734 sc->sc_rbavail = com_rbuf_size;
735 com_iflush(sc);
736 CLR(sc->sc_rx_flags, RX_ANY_BLOCK);
737 com_hwiflow(sc);
738
739 #ifdef COM_DEBUG
740 if (com_debug)
741 comstatus(sc, "comopen ");
742 #endif
743
744 splx(s2);
745 }
746
747 splx(s);
748
749 error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK));
750 if (error)
751 goto bad;
752
753 error = (*linesw[tp->t_line].l_open)(dev, tp);
754 if (error)
755 goto bad;
756
757 return (0);
758
759 bad:
760 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
761 /*
762 * We failed to open the device, and nobody else had it opened.
763 * Clean up the state as appropriate.
764 */
765 com_shutdown(sc);
766 }
767
768 return (error);
769 }
770
771 int
772 comclose(dev, flag, mode, p)
773 dev_t dev;
774 int flag, mode;
775 struct proc *p;
776 {
777 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
778 struct tty *tp = sc->sc_tty;
779
780 /* XXX This is for cons.c. */
781 if (!ISSET(tp->t_state, TS_ISOPEN))
782 return (0);
783
784 (*linesw[tp->t_line].l_close)(tp, flag);
785 ttyclose(tp);
786
787 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
788 /*
789 * Although we got a last close, the device may still be in
790 * use; e.g. if this was the dialout node, and there are still
791 * processes waiting for carrier on the non-dialout node.
792 */
793 com_shutdown(sc);
794 }
795
796 return (0);
797 }
798
799 int
800 comread(dev, uio, flag)
801 dev_t dev;
802 struct uio *uio;
803 int flag;
804 {
805 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
806 struct tty *tp = sc->sc_tty;
807
808 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
809 }
810
811 int
812 comwrite(dev, uio, flag)
813 dev_t dev;
814 struct uio *uio;
815 int flag;
816 {
817 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
818 struct tty *tp = sc->sc_tty;
819
820 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
821 }
822
823 struct tty *
824 comtty(dev)
825 dev_t dev;
826 {
827 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
828 struct tty *tp = sc->sc_tty;
829
830 return (tp);
831 }
832
833 static u_char
834 tiocm_xxx2mcr(data)
835 int data;
836 {
837 u_char m = 0;
838
839 if (ISSET(data, TIOCM_DTR))
840 SET(m, MCR_DTR);
841 if (ISSET(data, TIOCM_RTS))
842 SET(m, MCR_RTS);
843 return m;
844 }
845
846 int
847 comioctl(dev, cmd, data, flag, p)
848 dev_t dev;
849 u_long cmd;
850 caddr_t data;
851 int flag;
852 struct proc *p;
853 {
854 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
855 struct tty *tp = sc->sc_tty;
856 int error;
857 int s;
858
859 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
860 if (error >= 0)
861 return (error);
862
863 error = ttioctl(tp, cmd, data, flag, p);
864 if (error >= 0)
865 return (error);
866
867 error = 0;
868
869 s = splserial();
870
871 switch (cmd) {
872 case TIOCSBRK:
873 com_break(sc, 1);
874 break;
875
876 case TIOCCBRK:
877 com_break(sc, 0);
878 break;
879
880 case TIOCSDTR:
881 com_modem(sc, 1);
882 break;
883
884 case TIOCCDTR:
885 com_modem(sc, 0);
886 break;
887
888 case TIOCGFLAGS:
889 *(int *)data = sc->sc_swflags;
890 break;
891
892 case TIOCSFLAGS:
893 error = suser(p->p_ucred, &p->p_acflag);
894 if (error)
895 break;
896 sc->sc_swflags = *(int *)data;
897 break;
898
899 case TIOCMSET:
900 CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
901 /*FALLTHROUGH*/
902
903 case TIOCMBIS:
904 SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
905 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
906 break;
907
908 case TIOCMBIC:
909 CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
910 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
911 break;
912
913 case TIOCMGET: {
914 u_char m;
915 int bits = 0;
916
917 m = sc->sc_mcr;
918 if (ISSET(m, MCR_DTR))
919 SET(bits, TIOCM_DTR);
920 if (ISSET(m, MCR_RTS))
921 SET(bits, TIOCM_RTS);
922 m = sc->sc_msr;
923 if (ISSET(m, MSR_DCD))
924 SET(bits, TIOCM_CD);
925 if (ISSET(m, MSR_CTS))
926 SET(bits, TIOCM_CTS);
927 if (ISSET(m, MSR_DSR))
928 SET(bits, TIOCM_DSR);
929 if (ISSET(m, MSR_RI | MSR_TERI))
930 SET(bits, TIOCM_RI);
931 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_ier))
932 SET(bits, TIOCM_LE);
933 *(int *)data = bits;
934 break;
935 }
936 default:
937 error = ENOTTY;
938 break;
939 }
940
941 splx(s);
942
943 #ifdef COM_DEBUG
944 if (com_debug)
945 comstatus(sc, "comioctl ");
946 #endif
947
948 return (error);
949 }
950
951 integrate void
952 com_schedrx(sc)
953 struct com_softc *sc;
954 {
955
956 sc->sc_rx_ready = 1;
957
958 /* Wake up the poller. */
959 #ifdef __GENERIC_SOFT_INTERRUPTS
960 softintr_schedule(sc->sc_si);
961 #else
962 #ifndef __NO_SOFT_SERIAL_INTERRUPT
963 setsoftserial();
964 #else
965 if (!com_softintr_scheduled) {
966 com_softintr_scheduled = 1;
967 timeout(comsoft, NULL, 1);
968 }
969 #endif
970 #endif
971 }
972
973 void
974 com_break(sc, onoff)
975 struct com_softc *sc;
976 int onoff;
977 {
978
979 if (onoff)
980 SET(sc->sc_lcr, LCR_SBREAK);
981 else
982 CLR(sc->sc_lcr, LCR_SBREAK);
983
984 if (!sc->sc_heldchange) {
985 if (sc->sc_tx_busy) {
986 sc->sc_heldtbc = sc->sc_tbc;
987 sc->sc_tbc = 0;
988 sc->sc_heldchange = 1;
989 } else
990 com_loadchannelregs(sc);
991 }
992 }
993
994 void
995 com_modem(sc, onoff)
996 struct com_softc *sc;
997 int onoff;
998 {
999
1000 if (onoff)
1001 SET(sc->sc_mcr, sc->sc_mcr_dtr);
1002 else
1003 CLR(sc->sc_mcr, sc->sc_mcr_dtr);
1004
1005 if (!sc->sc_heldchange) {
1006 if (sc->sc_tx_busy) {
1007 sc->sc_heldtbc = sc->sc_tbc;
1008 sc->sc_tbc = 0;
1009 sc->sc_heldchange = 1;
1010 } else
1011 com_loadchannelregs(sc);
1012 }
1013 }
1014
1015 static u_char
1016 cflag2lcr(cflag)
1017 tcflag_t cflag;
1018 {
1019 u_char lcr = 0;
1020
1021 switch (ISSET(cflag, CSIZE)) {
1022 case CS5:
1023 SET(lcr, LCR_5BITS);
1024 break;
1025 case CS6:
1026 SET(lcr, LCR_6BITS);
1027 break;
1028 case CS7:
1029 SET(lcr, LCR_7BITS);
1030 break;
1031 case CS8:
1032 SET(lcr, LCR_8BITS);
1033 break;
1034 }
1035 if (ISSET(cflag, PARENB)) {
1036 SET(lcr, LCR_PENAB);
1037 if (!ISSET(cflag, PARODD))
1038 SET(lcr, LCR_PEVEN);
1039 }
1040 if (ISSET(cflag, CSTOPB))
1041 SET(lcr, LCR_STOPB);
1042
1043 return (lcr);
1044 }
1045
1046 int
1047 comparam(tp, t)
1048 struct tty *tp;
1049 struct termios *t;
1050 {
1051 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
1052 int ospeed = comspeed(t->c_ospeed, sc->sc_frequency);
1053 u_char lcr;
1054 int s;
1055
1056 /* Check requested parameters. */
1057 if (ospeed < 0)
1058 return (EINVAL);
1059 if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
1060 return (EINVAL);
1061
1062 /*
1063 * For the console, always force CLOCAL and !HUPCL, so that the port
1064 * is always active.
1065 */
1066 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) ||
1067 ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
1068 SET(t->c_cflag, CLOCAL);
1069 CLR(t->c_cflag, HUPCL);
1070 }
1071
1072 /*
1073 * If there were no changes, don't do anything. This avoids dropping
1074 * input and improves performance when all we did was frob things like
1075 * VMIN and VTIME.
1076 */
1077 if (tp->t_ospeed == t->c_ospeed &&
1078 tp->t_cflag == t->c_cflag)
1079 return (0);
1080
1081 lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag);
1082
1083 s = splserial();
1084
1085 sc->sc_lcr = lcr;
1086
1087 /*
1088 * If we're not in a mode that assumes a connection is present, then
1089 * ignore carrier changes.
1090 */
1091 if (ISSET(t->c_cflag, CLOCAL | MDMBUF))
1092 sc->sc_msr_dcd = 0;
1093 else
1094 sc->sc_msr_dcd = MSR_DCD;
1095 /*
1096 * Set the flow control pins depending on the current flow control
1097 * mode.
1098 */
1099 if (ISSET(t->c_cflag, CRTSCTS)) {
1100 sc->sc_mcr_dtr = MCR_DTR;
1101 sc->sc_mcr_rts = MCR_RTS;
1102 sc->sc_msr_cts = MSR_CTS;
1103 sc->sc_efr = EFR_AUTORTS | EFR_AUTOCTS;
1104 } else if (ISSET(t->c_cflag, MDMBUF)) {
1105 /*
1106 * For DTR/DCD flow control, make sure we don't toggle DTR for
1107 * carrier detection.
1108 */
1109 sc->sc_mcr_dtr = 0;
1110 sc->sc_mcr_rts = MCR_DTR;
1111 sc->sc_msr_cts = MSR_DCD;
1112 sc->sc_efr = 0;
1113 } else {
1114 /*
1115 * If no flow control, then always set RTS. This will make
1116 * the other side happy if it mistakenly thinks we're doing
1117 * RTS/CTS flow control.
1118 */
1119 sc->sc_mcr_dtr = MCR_DTR | MCR_RTS;
1120 sc->sc_mcr_rts = 0;
1121 sc->sc_msr_cts = 0;
1122 sc->sc_efr = 0;
1123 if (ISSET(sc->sc_mcr, MCR_DTR))
1124 SET(sc->sc_mcr, MCR_RTS);
1125 else
1126 CLR(sc->sc_mcr, MCR_RTS);
1127 }
1128 sc->sc_msr_mask = sc->sc_msr_cts | sc->sc_msr_dcd;
1129
1130 #if 0
1131 if (ospeed == 0)
1132 CLR(sc->sc_mcr, sc->sc_mcr_dtr);
1133 else
1134 SET(sc->sc_mcr, sc->sc_mcr_dtr);
1135 #endif
1136
1137 sc->sc_dlbl = ospeed;
1138 sc->sc_dlbh = ospeed >> 8;
1139
1140 /*
1141 * Set the FIFO threshold based on the receive speed.
1142 *
1143 * * If it's a low speed, it's probably a mouse or some other
1144 * interactive device, so set the threshold low.
1145 * * If it's a high speed, trim the trigger level down to prevent
1146 * overflows.
1147 * * Otherwise set it a bit higher.
1148 */
1149 if (ISSET(sc->sc_hwflags, COM_HW_HAYESP))
1150 sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8;
1151 else if (ISSET(sc->sc_hwflags, COM_HW_FIFO))
1152 sc->sc_fifo = FIFO_ENABLE |
1153 (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 :
1154 t->c_ospeed <= 38400 ? FIFO_TRIGGER_8 : FIFO_TRIGGER_4);
1155 else
1156 sc->sc_fifo = 0;
1157
1158 /* And copy to tty. */
1159 tp->t_ispeed = 0;
1160 tp->t_ospeed = t->c_ospeed;
1161 tp->t_cflag = t->c_cflag;
1162
1163 if (!sc->sc_heldchange) {
1164 if (sc->sc_tx_busy) {
1165 sc->sc_heldtbc = sc->sc_tbc;
1166 sc->sc_tbc = 0;
1167 sc->sc_heldchange = 1;
1168 } else
1169 com_loadchannelregs(sc);
1170 }
1171
1172 if (!ISSET(t->c_cflag, CHWFLOW)) {
1173 /* Disable the high water mark. */
1174 sc->sc_r_hiwat = 0;
1175 sc->sc_r_lowat = 0;
1176 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
1177 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1178 com_schedrx(sc);
1179 }
1180 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
1181 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
1182 com_hwiflow(sc);
1183 }
1184 } else {
1185 sc->sc_r_hiwat = com_rbuf_hiwat;
1186 sc->sc_r_lowat = com_rbuf_lowat;
1187 }
1188
1189 splx(s);
1190
1191 /*
1192 * Update the tty layer's idea of the carrier bit, in case we changed
1193 * CLOCAL or MDMBUF. We don't hang up here; we only do that by
1194 * explicit request.
1195 */
1196 (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(sc->sc_msr, MSR_DCD));
1197
1198 #ifdef COM_DEBUG
1199 if (com_debug)
1200 comstatus(sc, "comparam ");
1201 #endif
1202
1203 if (!ISSET(t->c_cflag, CHWFLOW)) {
1204 if (sc->sc_tx_stopped) {
1205 sc->sc_tx_stopped = 0;
1206 comstart(tp);
1207 }
1208 }
1209
1210 return (0);
1211 }
1212
1213 void
1214 com_iflush(sc)
1215 struct com_softc *sc;
1216 {
1217 bus_space_tag_t iot = sc->sc_iot;
1218 bus_space_handle_t ioh = sc->sc_ioh;
1219 #ifdef DIAGNOSTIC
1220 int reg;
1221 #endif
1222 int timo;
1223
1224 #ifdef DIAGNOSTIC
1225 reg = 0xffff;
1226 #endif
1227 timo = 50000;
1228 /* flush any pending I/O */
1229 while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)
1230 && --timo)
1231 #ifdef DIAGNOSTIC
1232 reg =
1233 #else
1234 (void)
1235 #endif
1236 bus_space_read_1(iot, ioh, com_data);
1237 #ifdef DIAGNOSTIC
1238 if (!timo)
1239 printf("%s: com_iflush timeout %02x\n", sc->sc_dev.dv_xname,
1240 reg);
1241 #endif
1242 }
1243
1244 void
1245 com_loadchannelregs(sc)
1246 struct com_softc *sc;
1247 {
1248 bus_space_tag_t iot = sc->sc_iot;
1249 bus_space_handle_t ioh = sc->sc_ioh;
1250
1251 /* XXXXX necessary? */
1252 com_iflush(sc);
1253
1254 bus_space_write_1(iot, ioh, com_ier, 0);
1255
1256 if (ISSET(sc->sc_hwflags, COM_HW_FLOW)) {
1257 bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
1258 bus_space_write_1(iot, ioh, com_efr, sc->sc_efr);
1259 }
1260 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr | LCR_DLAB);
1261 bus_space_write_1(iot, ioh, com_dlbl, sc->sc_dlbl);
1262 bus_space_write_1(iot, ioh, com_dlbh, sc->sc_dlbh);
1263 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
1264 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active = sc->sc_mcr);
1265 bus_space_write_1(iot, ioh, com_fifo, sc->sc_fifo);
1266
1267 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1268 }
1269
1270 int
1271 comhwiflow(tp, block)
1272 struct tty *tp;
1273 int block;
1274 {
1275 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
1276 int s;
1277
1278 if (sc->sc_mcr_rts == 0)
1279 return (0);
1280
1281 s = splserial();
1282 if (block) {
1283 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1284 SET(sc->sc_rx_flags, RX_TTY_BLOCKED);
1285 com_hwiflow(sc);
1286 }
1287 } else {
1288 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
1289 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1290 com_schedrx(sc);
1291 }
1292 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1293 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED);
1294 com_hwiflow(sc);
1295 }
1296 }
1297 splx(s);
1298 return (1);
1299 }
1300
1301 /*
1302 * (un)block input via hw flowcontrol
1303 */
1304 void
1305 com_hwiflow(sc)
1306 struct com_softc *sc;
1307 {
1308 bus_space_tag_t iot = sc->sc_iot;
1309 bus_space_handle_t ioh = sc->sc_ioh;
1310
1311 if (sc->sc_mcr_rts == 0)
1312 return;
1313
1314 if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) {
1315 CLR(sc->sc_mcr, sc->sc_mcr_rts);
1316 CLR(sc->sc_mcr_active, sc->sc_mcr_rts);
1317 } else {
1318 SET(sc->sc_mcr, sc->sc_mcr_rts);
1319 SET(sc->sc_mcr_active, sc->sc_mcr_rts);
1320 }
1321 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active);
1322 }
1323
1324
1325 void
1326 comstart(tp)
1327 struct tty *tp;
1328 {
1329 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
1330 bus_space_tag_t iot = sc->sc_iot;
1331 bus_space_handle_t ioh = sc->sc_ioh;
1332 int s;
1333
1334 s = spltty();
1335 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
1336 goto out;
1337 if (sc->sc_tx_stopped)
1338 goto out;
1339
1340 if (tp->t_outq.c_cc <= tp->t_lowat) {
1341 if (ISSET(tp->t_state, TS_ASLEEP)) {
1342 CLR(tp->t_state, TS_ASLEEP);
1343 wakeup(&tp->t_outq);
1344 }
1345 selwakeup(&tp->t_wsel);
1346 if (tp->t_outq.c_cc == 0)
1347 goto out;
1348 }
1349
1350 /* Grab the first contiguous region of buffer space. */
1351 {
1352 u_char *tba;
1353 int tbc;
1354
1355 tba = tp->t_outq.c_cf;
1356 tbc = ndqb(&tp->t_outq, 0);
1357
1358 (void)splserial();
1359
1360 sc->sc_tba = tba;
1361 sc->sc_tbc = tbc;
1362 }
1363
1364 SET(tp->t_state, TS_BUSY);
1365 sc->sc_tx_busy = 1;
1366
1367 /* Enable transmit completion interrupts if necessary. */
1368 if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
1369 SET(sc->sc_ier, IER_ETXRDY);
1370 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1371 }
1372
1373 /* Output the first chunk of the contiguous buffer. */
1374 {
1375 int n;
1376
1377 n = sc->sc_tbc;
1378 if (n > sc->sc_fifolen)
1379 n = sc->sc_fifolen;
1380 bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n);
1381 sc->sc_tbc -= n;
1382 sc->sc_tba += n;
1383 }
1384 out:
1385 splx(s);
1386 return;
1387 }
1388
1389 /*
1390 * Stop output on a line.
1391 */
1392 void
1393 comstop(tp, flag)
1394 struct tty *tp;
1395 int flag;
1396 {
1397 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
1398 int s;
1399
1400 s = splserial();
1401 if (ISSET(tp->t_state, TS_BUSY)) {
1402 /* Stop transmitting at the next chunk. */
1403 sc->sc_tbc = 0;
1404 sc->sc_heldtbc = 0;
1405 if (!ISSET(tp->t_state, TS_TTSTOP))
1406 SET(tp->t_state, TS_FLUSH);
1407 }
1408 splx(s);
1409 }
1410
1411 void
1412 comdiag(arg)
1413 void *arg;
1414 {
1415 struct com_softc *sc = arg;
1416 int overflows, floods;
1417 int s;
1418
1419 s = splserial();
1420 overflows = sc->sc_overflows;
1421 sc->sc_overflows = 0;
1422 floods = sc->sc_floods;
1423 sc->sc_floods = 0;
1424 sc->sc_errors = 0;
1425 splx(s);
1426
1427 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
1428 sc->sc_dev.dv_xname,
1429 overflows, overflows == 1 ? "" : "s",
1430 floods, floods == 1 ? "" : "s");
1431 }
1432
1433 integrate void
1434 com_rxsoft(sc, tp)
1435 struct com_softc *sc;
1436 struct tty *tp;
1437 {
1438 int (*rint) __P((int c, struct tty *tp)) = linesw[tp->t_line].l_rint;
1439 u_char *get, *end;
1440 u_int cc, scc;
1441 u_char lsr;
1442 int code;
1443 int s;
1444
1445 end = sc->sc_ebuf;
1446 get = sc->sc_rbget;
1447 scc = cc = com_rbuf_size - sc->sc_rbavail;
1448
1449 if (cc == com_rbuf_size) {
1450 sc->sc_floods++;
1451 if (sc->sc_errors++ == 0)
1452 timeout(comdiag, sc, 60 * hz);
1453 }
1454
1455 while (cc) {
1456 code = get[0];
1457 lsr = get[1];
1458 if (ISSET(lsr, LSR_OE | LSR_BI | LSR_FE | LSR_PE)) {
1459 if (ISSET(lsr, LSR_OE)) {
1460 sc->sc_overflows++;
1461 if (sc->sc_errors++ == 0)
1462 timeout(comdiag, sc, 60 * hz);
1463 }
1464 if (ISSET(lsr, LSR_BI | LSR_FE))
1465 SET(code, TTY_FE);
1466 if (ISSET(lsr, LSR_PE))
1467 SET(code, TTY_PE);
1468 }
1469 if ((*rint)(code, tp) == -1) {
1470 /*
1471 * The line discipline's buffer is out of space.
1472 */
1473 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1474 /*
1475 * We're either not using flow control, or the
1476 * line discipline didn't tell us to block for
1477 * some reason. Either way, we have no way to
1478 * know when there's more space available, so
1479 * just drop the rest of the data.
1480 */
1481 get += cc << 1;
1482 if (get >= end)
1483 get -= com_rbuf_size << 1;
1484 cc = 0;
1485 } else {
1486 /*
1487 * Don't schedule any more receive processing
1488 * until the line discipline tells us there's
1489 * space available (through comhwiflow()).
1490 * Leave the rest of the data in the input
1491 * buffer.
1492 */
1493 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1494 }
1495 break;
1496 }
1497 get += 2;
1498 if (get >= end)
1499 get = sc->sc_rbuf;
1500 cc--;
1501 }
1502
1503 if (cc != scc) {
1504 sc->sc_rbget = get;
1505 s = splserial();
1506 cc = sc->sc_rbavail += scc - cc;
1507 /* Buffers should be ok again, release possible block. */
1508 if (cc >= sc->sc_r_lowat) {
1509 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
1510 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
1511 SET(sc->sc_ier, IER_ERXRDY);
1512 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
1513 }
1514 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
1515 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
1516 com_hwiflow(sc);
1517 }
1518 }
1519 splx(s);
1520 }
1521 }
1522
1523 integrate void
1524 com_txsoft(sc, tp)
1525 struct com_softc *sc;
1526 struct tty *tp;
1527 {
1528
1529 CLR(tp->t_state, TS_BUSY);
1530 if (ISSET(tp->t_state, TS_FLUSH))
1531 CLR(tp->t_state, TS_FLUSH);
1532 else
1533 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
1534 (*linesw[tp->t_line].l_start)(tp);
1535 }
1536
1537 integrate void
1538 com_stsoft(sc, tp)
1539 struct com_softc *sc;
1540 struct tty *tp;
1541 {
1542 u_char msr, delta;
1543 int s;
1544
1545 s = splserial();
1546 msr = sc->sc_msr;
1547 delta = sc->sc_msr_delta;
1548 sc->sc_msr_delta = 0;
1549 splx(s);
1550
1551 if (ISSET(delta, sc->sc_msr_dcd)) {
1552 /*
1553 * Inform the tty layer that carrier detect changed.
1554 */
1555 (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD));
1556 }
1557
1558 if (ISSET(delta, sc->sc_msr_cts)) {
1559 /* Block or unblock output according to flow control. */
1560 if (ISSET(msr, sc->sc_msr_cts)) {
1561 sc->sc_tx_stopped = 0;
1562 (*linesw[tp->t_line].l_start)(tp);
1563 } else {
1564 sc->sc_tx_stopped = 1;
1565 }
1566 }
1567
1568 #ifdef COM_DEBUG
1569 if (com_debug)
1570 comstatus(sc, "com_stsoft");
1571 #endif
1572 }
1573
1574 #ifdef __GENERIC_SOFT_INTERRUPTS
1575 void
1576 comsoft(arg)
1577 void *arg;
1578 {
1579 struct com_softc *sc = arg;
1580 struct tty *tp;
1581
1582 if (!sc->enabled)
1583 return;
1584
1585 {
1586 #else
1587 void
1588 #ifndef __NO_SOFT_SERIAL_INTERRUPT
1589 comsoft()
1590 #else
1591 comsoft(arg)
1592 void *arg;
1593 #endif
1594 {
1595 struct com_softc *sc;
1596 struct tty *tp;
1597 int unit;
1598 #ifdef __NO_SOFT_SERIAL_INTERRUPT
1599 int s;
1600
1601 s = splsoftserial();
1602 com_softintr_scheduled = 0;
1603 #endif
1604
1605 for (unit = 0; unit < com_cd.cd_ndevs; unit++) {
1606 sc = com_cd.cd_devs[unit];
1607 if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK))
1608 continue;
1609
1610 if (!sc->enabled)
1611 continue;
1612
1613 tp = sc->sc_tty;
1614 if (tp == NULL)
1615 continue;
1616 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0)
1617 continue;
1618 #endif
1619 tp = sc->sc_tty;
1620
1621 if (sc->sc_rx_ready) {
1622 sc->sc_rx_ready = 0;
1623 com_rxsoft(sc, tp);
1624 }
1625
1626 if (sc->sc_st_check) {
1627 sc->sc_st_check = 0;
1628 com_stsoft(sc, tp);
1629 }
1630
1631 if (sc->sc_tx_done) {
1632 sc->sc_tx_done = 0;
1633 com_txsoft(sc, tp);
1634 }
1635 }
1636
1637 #ifndef __GENERIC_SOFT_INTERRUPTS
1638 #ifdef __NO_SOFT_SERIAL_INTERRUPT
1639 splx(s);
1640 #endif
1641 #endif
1642 }
1643
1644 #ifdef __ALIGN_BRACKET_LEVEL_FOR_CTAGS
1645 /* there has got to be a better way to do comsoft() */
1646 }}
1647 #endif
1648
1649 int
1650 comintr(arg)
1651 void *arg;
1652 {
1653 struct com_softc *sc = arg;
1654 bus_space_tag_t iot = sc->sc_iot;
1655 bus_space_handle_t ioh = sc->sc_ioh;
1656 u_char *put, *end;
1657 u_int cc;
1658 u_char lsr, iir;
1659
1660 if (!sc->enabled)
1661 return (0);
1662
1663 iir = bus_space_read_1(iot, ioh, com_iir);
1664 if (ISSET(iir, IIR_NOPEND))
1665 return (0);
1666
1667 end = sc->sc_ebuf;
1668 put = sc->sc_rbput;
1669 cc = sc->sc_rbavail;
1670
1671 do {
1672 u_char msr, delta;
1673
1674 lsr = bus_space_read_1(iot, ioh, com_lsr);
1675 #if defined(DDB) || defined(KGDB)
1676 if (ISSET(lsr, LSR_BI)) {
1677 #ifdef DDB
1678 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
1679 Debugger();
1680 continue;
1681 }
1682 #endif
1683 #ifdef KGDB
1684 if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) {
1685 kgdb_connect(1);
1686 continue;
1687 }
1688 #endif
1689 }
1690 #endif /* DDB || KGDB */
1691
1692 if (ISSET(lsr, LSR_RCV_MASK) &&
1693 !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
1694 while (cc > 0) {
1695 put[0] = bus_space_read_1(iot, ioh, com_data);
1696 put[1] = lsr;
1697 put += 2;
1698 if (put >= end)
1699 put = sc->sc_rbuf;
1700 cc--;
1701
1702 lsr = bus_space_read_1(iot, ioh, com_lsr);
1703 if (!ISSET(lsr, LSR_RCV_MASK))
1704 break;
1705 }
1706
1707 /*
1708 * Current string of incoming characters ended because
1709 * no more data was available or we ran out of space.
1710 * Schedule a receive event if any data was received.
1711 * If we're out of space, turn off receive interrupts.
1712 */
1713 sc->sc_rbput = put;
1714 sc->sc_rbavail = cc;
1715 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
1716 sc->sc_rx_ready = 1;
1717
1718 /*
1719 * See if we are in danger of overflowing a buffer. If
1720 * so, use hardware flow control to ease the pressure.
1721 */
1722 if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) &&
1723 cc < sc->sc_r_hiwat) {
1724 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
1725 com_hwiflow(sc);
1726 }
1727
1728 /*
1729 * If we're out of space, disable receive interrupts
1730 * until the queue has drained a bit.
1731 */
1732 if (!cc) {
1733 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
1734 CLR(sc->sc_ier, IER_ERXRDY);
1735 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1736 }
1737 } else {
1738 if ((iir & IIR_IMASK) == IIR_RXRDY) {
1739 bus_space_write_1(iot, ioh, com_ier, 0);
1740 delay(10);
1741 bus_space_write_1(iot, ioh, com_ier,sc->sc_ier);
1742 iir = IIR_NOPEND;
1743 continue;
1744 }
1745 }
1746
1747 msr = bus_space_read_1(iot, ioh, com_msr);
1748 delta = msr ^ sc->sc_msr;
1749 sc->sc_msr = msr;
1750 if (ISSET(delta, sc->sc_msr_mask)) {
1751 SET(sc->sc_msr_delta, delta);
1752
1753 /*
1754 * Stop output immediately if we lose the output
1755 * flow control signal or carrier detect.
1756 */
1757 if (ISSET(~msr, sc->sc_msr_mask)) {
1758 sc->sc_tbc = 0;
1759 sc->sc_heldtbc = 0;
1760 #ifdef COM_DEBUG
1761 if (com_debug)
1762 comstatus(sc, "comintr ");
1763 #endif
1764 }
1765
1766 sc->sc_st_check = 1;
1767 }
1768 } while (!ISSET((iir = bus_space_read_1(iot, ioh, com_iir)), IIR_NOPEND));
1769
1770 /*
1771 * Done handling any receive interrupts. See if data can be
1772 * transmitted as well. Schedule tx done event if no data left
1773 * and tty was marked busy.
1774 */
1775 if (ISSET(lsr, LSR_TXRDY)) {
1776 /*
1777 * If we've delayed a parameter change, do it now, and restart
1778 * output.
1779 */
1780 if (sc->sc_heldchange) {
1781 com_loadchannelregs(sc);
1782 sc->sc_heldchange = 0;
1783 sc->sc_tbc = sc->sc_heldtbc;
1784 sc->sc_heldtbc = 0;
1785 }
1786
1787 /* Output the next chunk of the contiguous buffer, if any. */
1788 if (sc->sc_tbc > 0) {
1789 int n;
1790
1791 n = sc->sc_tbc;
1792 if (n > sc->sc_fifolen)
1793 n = sc->sc_fifolen;
1794 bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n);
1795 sc->sc_tbc -= n;
1796 sc->sc_tba += n;
1797 } else {
1798 /* Disable transmit completion interrupts if necessary. */
1799 if (ISSET(sc->sc_ier, IER_ETXRDY)) {
1800 CLR(sc->sc_ier, IER_ETXRDY);
1801 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1802 }
1803 if (sc->sc_tx_busy) {
1804 sc->sc_tx_busy = 0;
1805 sc->sc_tx_done = 1;
1806 }
1807 }
1808 }
1809
1810 /* Wake up the poller. */
1811 #ifdef __GENERIC_SOFT_INTERRUPTS
1812 softintr_schedule(sc->sc_si);
1813 #else
1814 #ifndef __NO_SOFT_SERIAL_INTERRUPT
1815 setsoftserial();
1816 #else
1817 if (!com_softintr_scheduled) {
1818 com_softintr_scheduled = 1;
1819 timeout(comsoft, NULL, 1);
1820 }
1821 #endif
1822 #endif
1823
1824 #if NRND > 0 && defined(RND_COM)
1825 rnd_add_uint32(&sc->rnd_source, iir | lsr);
1826 #endif
1827
1828 return (1);
1829 }
1830
1831 /*
1832 * The following functions are polled getc and putc routines, shared
1833 * by the console and kgdb glue.
1834 */
1835
1836 int
1837 com_common_getc(iot, ioh)
1838 bus_space_tag_t iot;
1839 bus_space_handle_t ioh;
1840 {
1841 int s = splserial();
1842 u_char stat, c;
1843
1844 /* block until a character becomes available */
1845 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
1846 ;
1847
1848 c = bus_space_read_1(iot, ioh, com_data);
1849 stat = bus_space_read_1(iot, ioh, com_iir);
1850 splx(s);
1851 return (c);
1852 }
1853
1854 void
1855 com_common_putc(iot, ioh, c)
1856 bus_space_tag_t iot;
1857 bus_space_handle_t ioh;
1858 int c;
1859 {
1860 int s = splserial();
1861 u_char stat;
1862 int timo;
1863
1864 /* wait for any pending transmission to finish */
1865 timo = 50000;
1866 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY)
1867 && --timo)
1868 ;
1869
1870 bus_space_write_1(iot, ioh, com_data, c);
1871 /* wait for this transmission to complete */
1872 timo = 1500000;
1873 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY)
1874 && --timo)
1875 ;
1876
1877 /* clear any interrupts generated by this transmission */
1878 stat = bus_space_read_1(iot, ioh, com_iir);
1879 splx(s);
1880 }
1881
1882 /*
1883 * Initialize UART to known state.
1884 */
1885 int
1886 cominit(iot, iobase, rate, frequency, cflag, iohp)
1887 bus_space_tag_t iot;
1888 int iobase;
1889 int rate, frequency;
1890 tcflag_t cflag;
1891 bus_space_handle_t *iohp;
1892 {
1893 bus_space_handle_t ioh;
1894
1895 if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh))
1896 return (ENOMEM); /* ??? */
1897
1898 bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
1899 bus_space_write_1(iot, ioh, com_efr, 0);
1900 bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);
1901 rate = comspeed(rate, frequency);
1902 bus_space_write_1(iot, ioh, com_dlbl, rate);
1903 bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
1904 bus_space_write_1(iot, ioh, com_lcr, cflag2lcr(cflag));
1905 bus_space_write_1(iot, ioh, com_mcr, 0);
1906 bus_space_write_1(iot, ioh, com_fifo,
1907 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
1908 bus_space_write_1(iot, ioh, com_ier, 0);
1909
1910 *iohp = ioh;
1911 return (0);
1912 }
1913
1914 /*
1915 * Following are all routines needed for COM to act as console
1916 */
1917
1918 int
1919 comcnattach(iot, iobase, rate, frequency, cflag)
1920 bus_space_tag_t iot;
1921 int iobase;
1922 int rate, frequency;
1923 tcflag_t cflag;
1924 {
1925 int res;
1926 static struct consdev comcons = {
1927 NULL, NULL, comcngetc, comcnputc, comcnpollc, NODEV, CN_NORMAL
1928 };
1929
1930 res = cominit(iot, iobase, rate, frequency, cflag, &comconsioh);
1931 if (res)
1932 return (res);
1933
1934 cn_tab = &comcons;
1935
1936 comconstag = iot;
1937 comconsaddr = iobase;
1938 comconsrate = rate;
1939 comconscflag = cflag;
1940
1941 return (0);
1942 }
1943
1944 int
1945 comcngetc(dev)
1946 dev_t dev;
1947 {
1948
1949 return (com_common_getc(comconstag, comconsioh));
1950 }
1951
1952 /*
1953 * Console kernel output character routine.
1954 */
1955 void
1956 comcnputc(dev, c)
1957 dev_t dev;
1958 int c;
1959 {
1960
1961 com_common_putc(comconstag, comconsioh, c);
1962 }
1963
1964 void
1965 comcnpollc(dev, on)
1966 dev_t dev;
1967 int on;
1968 {
1969
1970 }
1971
1972 #ifdef KGDB
1973 int
1974 com_kgdb_attach(iot, iobase, rate, frequency, cflag)
1975 bus_space_tag_t iot;
1976 int iobase;
1977 int rate, frequency;
1978 tcflag_t cflag;
1979 {
1980 int res;
1981
1982 if (iot == comconstag && iobase == comconsaddr)
1983 return (EBUSY); /* cannot share with console */
1984
1985 res = cominit(iot, iobase, rate, frequency, cflag, &com_kgdb_ioh);
1986 if (res)
1987 return (res);
1988
1989 kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL);
1990 kgdb_dev = 123; /* unneeded, only to satisfy some tests */
1991
1992 com_kgdb_iot = iot;
1993 com_kgdb_addr = iobase;
1994
1995 return (0);
1996 }
1997
1998 /* ARGSUSED */
1999 int
2000 com_kgdb_getc(arg)
2001 void *arg;
2002 {
2003
2004 return (com_common_getc(com_kgdb_iot, com_kgdb_ioh));
2005 }
2006
2007 /* ARGSUSED */
2008 void
2009 com_kgdb_putc(arg, c)
2010 void *arg;
2011 int c;
2012 {
2013
2014 return (com_common_putc(com_kgdb_iot, com_kgdb_ioh, c));
2015 }
2016 #endif /* KGDB */
2017
2018 /* helper function to identify the com ports used by
2019 console or KGDB (and not yet autoconf attached) */
2020 int
2021 com_is_console(iot, iobase, ioh)
2022 bus_space_tag_t iot;
2023 int iobase;
2024 bus_space_handle_t *ioh;
2025 {
2026 bus_space_handle_t help;
2027
2028 if (!comconsattached &&
2029 iot == comconstag && iobase == comconsaddr)
2030 help = comconsioh;
2031 #ifdef KGDB
2032 else if (!com_kgdb_attached &&
2033 iot == com_kgdb_iot && iobase == com_kgdb_addr)
2034 help = com_kgdb_ioh;
2035 #endif
2036 else
2037 return (0);
2038
2039 if (ioh)
2040 *ioh = help;
2041 return (1);
2042 }
2043