com.c revision 1.196 1 /* $NetBSD: com.c,v 1.196 2002/04/13 17:05:16 christos Exp $ */
2
3 /*-
4 * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum.
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 the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * Copyright (c) 1991 The Regents of the University of California.
41 * All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. All advertising materials mentioning features or use of this software
52 * must display the following acknowledgement:
53 * This product includes software developed by the University of
54 * California, Berkeley and its contributors.
55 * 4. Neither the name of the University nor the names of its contributors
56 * may be used to endorse or promote products derived from this software
57 * without specific prior written permission.
58 *
59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE.
70 *
71 * @(#)com.c 7.5 (Berkeley) 5/16/91
72 */
73
74 /*
75 * COM driver, uses National Semiconductor NS16450/NS16550AF UART
76 * Supports automatic hardware flow control on StarTech ST16C650A UART
77 */
78
79 #include <sys/cdefs.h>
80 __KERNEL_RCSID(0, "$NetBSD: com.c,v 1.196 2002/04/13 17:05:16 christos Exp $");
81
82 #include "opt_com.h"
83 #include "opt_ddb.h"
84 #include "opt_kgdb.h"
85
86 #include "rnd.h"
87 #if NRND > 0 && defined(RND_COM)
88 #include <sys/rnd.h>
89 #endif
90
91 /*
92 * Override cnmagic(9) macro before including <sys/systm.h>.
93 * We need to know if cn_check_magic triggered debugger, so set a flag.
94 * Callers of cn_check_magic must declare int cn_trapped = 0;
95 * XXX: this is *ugly*!
96 */
97 #define cn_trap() \
98 do { \
99 console_debugger(); \
100 cn_trapped = 1; \
101 } while (/* CONSTCOND */ 0)
102
103 #include <sys/param.h>
104 #include <sys/systm.h>
105 #include <sys/ioctl.h>
106 #include <sys/select.h>
107 #include <sys/tty.h>
108 #include <sys/proc.h>
109 #include <sys/user.h>
110 #include <sys/conf.h>
111 #include <sys/file.h>
112 #include <sys/uio.h>
113 #include <sys/kernel.h>
114 #include <sys/syslog.h>
115 #include <sys/device.h>
116 #include <sys/malloc.h>
117 #include <sys/timepps.h>
118 #include <sys/vnode.h>
119
120 #include <machine/intr.h>
121 #include <machine/bus.h>
122
123 #include <dev/ic/comreg.h>
124 #include <dev/ic/comvar.h>
125 #include <dev/ic/ns16550reg.h>
126 #include <dev/ic/st16650reg.h>
127 #ifdef COM_HAYESP
128 #include <dev/ic/hayespreg.h>
129 #endif
130 #define com_lcr com_cfcr
131 #include <dev/cons.h>
132
133 #ifdef COM_HAYESP
134 int comprobeHAYESP __P((bus_space_handle_t hayespioh, struct com_softc *sc));
135 #endif
136
137 static void com_enable_debugport __P((struct com_softc *));
138
139 void com_config __P((struct com_softc *));
140 void com_shutdown __P((struct com_softc *));
141 int comspeed __P((long, long));
142 static u_char cflag2lcr __P((tcflag_t));
143 int comparam __P((struct tty *, struct termios *));
144 void comstart __P((struct tty *));
145 int comhwiflow __P((struct tty *, int));
146
147 void com_loadchannelregs __P((struct com_softc *));
148 void com_hwiflow __P((struct com_softc *));
149 void com_break __P((struct com_softc *, int));
150 void com_modem __P((struct com_softc *, int));
151 void tiocm_to_com __P((struct com_softc *, u_long, int));
152 int com_to_tiocm __P((struct com_softc *));
153 void com_iflush __P((struct com_softc *));
154
155 int com_common_getc __P((dev_t, bus_space_tag_t, bus_space_handle_t));
156 void com_common_putc __P((dev_t, bus_space_tag_t, bus_space_handle_t, int));
157
158 int cominit __P((bus_space_tag_t, bus_addr_t, int, int, tcflag_t,
159 bus_space_handle_t *));
160
161 /* XXX: This belongs elsewhere */
162 cdev_decl(com);
163
164 int comcngetc __P((dev_t));
165 void comcnputc __P((dev_t, int));
166 void comcnpollc __P((dev_t, int));
167
168 #define integrate static inline
169 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
170 void comsoft __P((void *));
171 #else
172 #ifndef __NO_SOFT_SERIAL_INTERRUPT
173 void comsoft __P((void));
174 #else
175 void comsoft __P((void *));
176 struct callout comsoft_callout = CALLOUT_INITIALIZER;
177 #endif
178 #endif
179 integrate void com_rxsoft __P((struct com_softc *, struct tty *));
180 integrate void com_txsoft __P((struct com_softc *, struct tty *));
181 integrate void com_stsoft __P((struct com_softc *, struct tty *));
182 integrate void com_schedrx __P((struct com_softc *));
183 void comdiag __P((void *));
184
185 extern struct cfdriver com_cd;
186
187 /*
188 * Make this an option variable one can patch.
189 * But be warned: this must be a power of 2!
190 */
191 u_int com_rbuf_size = COM_RING_SIZE;
192
193 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
194 u_int com_rbuf_hiwat = (COM_RING_SIZE * 1) / 4;
195 u_int com_rbuf_lowat = (COM_RING_SIZE * 3) / 4;
196
197 static bus_addr_t comconsaddr;
198 static bus_space_tag_t comconstag;
199 static bus_space_handle_t comconsioh;
200 static int comconsattached;
201 static int comconsrate;
202 static tcflag_t comconscflag;
203 static struct cnm_state com_cnm_state;
204
205 static int ppscap =
206 PPS_TSFMT_TSPEC |
207 PPS_CAPTUREASSERT |
208 PPS_CAPTURECLEAR |
209 #ifdef PPS_SYNC
210 PPS_HARDPPSONASSERT | PPS_HARDPPSONCLEAR |
211 #endif /* PPS_SYNC */
212 PPS_OFFSETASSERT | PPS_OFFSETCLEAR;
213
214 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
215 #ifdef __NO_SOFT_SERIAL_INTERRUPT
216 volatile int com_softintr_scheduled;
217 #endif
218 #endif
219
220 #ifdef KGDB
221 #include <sys/kgdb.h>
222
223 static bus_addr_t com_kgdb_addr;
224 static bus_space_tag_t com_kgdb_iot;
225 static bus_space_handle_t com_kgdb_ioh;
226 static int com_kgdb_attached;
227
228 int com_kgdb_getc __P((void *));
229 void com_kgdb_putc __P((void *, int));
230 #endif /* KGDB */
231
232 #define COMUNIT_MASK 0x7ffff
233 #define COMDIALOUT_MASK 0x80000
234
235 #define COMUNIT(x) (minor(x) & COMUNIT_MASK)
236 #define COMDIALOUT(x) (minor(x) & COMDIALOUT_MASK)
237
238 #define COM_ISALIVE(sc) ((sc)->enabled != 0 && \
239 ISSET((sc)->sc_dev.dv_flags, DVF_ACTIVE))
240
241 #define BR BUS_SPACE_BARRIER_READ
242 #define BW BUS_SPACE_BARRIER_WRITE
243 #define COM_BARRIER(t, h, f) bus_space_barrier((t), (h), 0, COM_NPORTS, (f))
244
245 #if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(COM_MPLOCK)
246
247 #define COM_LOCK(sc) simple_lock(&(sc)->sc_lock)
248 #define COM_UNLOCK(sc) simple_unlock(&(sc)->sc_lock)
249
250 #else
251
252 #define COM_LOCK(sc)
253 #define COM_UNLOCK(sc)
254
255 #endif
256
257 int
258 comspeed(speed, frequency)
259 long speed, frequency;
260 {
261 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
262
263 int x, err;
264
265 #if 0
266 if (speed == 0)
267 return (0);
268 #endif
269 if (speed <= 0)
270 return (-1);
271 x = divrnd(frequency / 16, speed);
272 if (x <= 0)
273 return (-1);
274 err = divrnd(((quad_t)frequency) * 1000 / 16, speed * x) - 1000;
275 if (err < 0)
276 err = -err;
277 if (err > COM_TOLERANCE)
278 return (-1);
279 return (x);
280
281 #undef divrnd
282 }
283
284 #ifdef COM_DEBUG
285 int com_debug = 0;
286
287 void comstatus __P((struct com_softc *, char *));
288 void
289 comstatus(sc, str)
290 struct com_softc *sc;
291 char *str;
292 {
293 struct tty *tp = sc->sc_tty;
294
295 printf("%s: %s %sclocal %sdcd %sts_carr_on %sdtr %stx_stopped\n",
296 sc->sc_dev.dv_xname, str,
297 ISSET(tp->t_cflag, CLOCAL) ? "+" : "-",
298 ISSET(sc->sc_msr, MSR_DCD) ? "+" : "-",
299 ISSET(tp->t_state, TS_CARR_ON) ? "+" : "-",
300 ISSET(sc->sc_mcr, MCR_DTR) ? "+" : "-",
301 sc->sc_tx_stopped ? "+" : "-");
302
303 printf("%s: %s %scrtscts %scts %sts_ttstop %srts %xrx_flags\n",
304 sc->sc_dev.dv_xname, str,
305 ISSET(tp->t_cflag, CRTSCTS) ? "+" : "-",
306 ISSET(sc->sc_msr, MSR_CTS) ? "+" : "-",
307 ISSET(tp->t_state, TS_TTSTOP) ? "+" : "-",
308 ISSET(sc->sc_mcr, MCR_RTS) ? "+" : "-",
309 sc->sc_rx_flags);
310 }
311 #endif
312
313 int
314 comprobe1(iot, ioh)
315 bus_space_tag_t iot;
316 bus_space_handle_t ioh;
317 {
318
319 /* force access to id reg */
320 bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS);
321 bus_space_write_1(iot, ioh, com_iir, 0);
322 if ((bus_space_read_1(iot, ioh, com_lcr) != LCR_8BITS) ||
323 (bus_space_read_1(iot, ioh, com_iir) & 0x38))
324 return (0);
325
326 return (1);
327 }
328
329 #ifdef COM_HAYESP
330 int
331 comprobeHAYESP(hayespioh, sc)
332 bus_space_handle_t hayespioh;
333 struct com_softc *sc;
334 {
335 char val, dips;
336 int combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
337 bus_space_tag_t iot = sc->sc_iot;
338
339 /*
340 * Hayes ESP cards have two iobases. One is for compatibility with
341 * 16550 serial chips, and at the same ISA PC base addresses. The
342 * other is for ESP-specific enhanced features, and lies at a
343 * different addressing range entirely (0x140, 0x180, 0x280, or 0x300).
344 */
345
346 /* Test for ESP signature */
347 if ((bus_space_read_1(iot, hayespioh, 0) & 0xf3) == 0)
348 return (0);
349
350 /*
351 * ESP is present at ESP enhanced base address; unknown com port
352 */
353
354 /* Get the dip-switch configurations */
355 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETDIPS);
356 dips = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1);
357
358 /* Determine which com port this ESP card services: bits 0,1 of */
359 /* dips is the port # (0-3); combaselist[val] is the com_iobase */
360 if (sc->sc_iobase != combaselist[dips & 0x03])
361 return (0);
362
363 printf(": ESP");
364
365 /* Check ESP Self Test bits. */
366 /* Check for ESP version 2.0: bits 4,5,6 == 010 */
367 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETTEST);
368 val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1); /* Clear reg1 */
369 val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS2);
370 if ((val & 0x70) < 0x20) {
371 printf("-old (%o)", val & 0x70);
372 /* we do not support the necessary features */
373 return (0);
374 }
375
376 /* Check for ability to emulate 16550: bit 8 == 1 */
377 if ((dips & 0x80) == 0) {
378 printf(" slave");
379 /* XXX Does slave really mean no 16550 support?? */
380 return (0);
381 }
382
383 /*
384 * If we made it this far, we are a full-featured ESP v2.0 (or
385 * better), at the correct com port address.
386 */
387
388 SET(sc->sc_hwflags, COM_HW_HAYESP);
389 printf(", 1024 byte fifo\n");
390 return (1);
391 }
392 #endif
393
394 static void
395 com_enable_debugport(sc)
396 struct com_softc *sc;
397 {
398 int s;
399
400 /* Turn on line break interrupt, set carrier. */
401 s = splserial();
402 COM_LOCK(sc);
403 sc->sc_ier = IER_ERXRDY;
404 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
405 SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
406 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
407 COM_UNLOCK(sc);
408 splx(s);
409 }
410
411 void
412 com_attach_subr(sc)
413 struct com_softc *sc;
414 {
415 bus_addr_t iobase = sc->sc_iobase;
416 bus_space_tag_t iot = sc->sc_iot;
417 bus_space_handle_t ioh = sc->sc_ioh;
418 struct tty *tp;
419 #ifdef COM16650
420 u_int8_t lcr;
421 #endif
422 #ifdef COM_HAYESP
423 int hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 };
424 int *hayespp;
425 #endif
426
427 callout_init(&sc->sc_diag_callout);
428 #if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(COM_MPLOCK)
429 simple_lock_init(&sc->sc_lock);
430 #endif
431
432 /* Disable interrupts before configuring the device. */
433 sc->sc_ier = 0;
434 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
435
436 if (iot == comconstag && iobase == comconsaddr) {
437 comconsattached = 1;
438
439 /* Make sure the console is always "hardwired". */
440 delay(1000); /* wait for output to finish */
441 SET(sc->sc_hwflags, COM_HW_CONSOLE);
442 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
443 }
444
445 #ifdef COM_HAYESP
446 sc->sc_prescaler = 0; /* set prescaler to x1. */
447
448 /* Look for a Hayes ESP board. */
449 for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) {
450 bus_space_handle_t hayespioh;
451
452 #define HAYESP_NPORTS 8 /* XXX XXX XXX ??? ??? ??? */
453 if (bus_space_map(iot, *hayespp, HAYESP_NPORTS, 0, &hayespioh))
454 continue;
455 if (comprobeHAYESP(hayespioh, sc)) {
456 sc->sc_hayespioh = hayespioh;
457 sc->sc_fifolen = 1024;
458
459 break;
460 }
461 bus_space_unmap(iot, hayespioh, HAYESP_NPORTS);
462 }
463 /* No ESP; look for other things. */
464 if (!ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
465 #endif
466 sc->sc_fifolen = 1;
467 /* look for a NS 16550AF UART with FIFOs */
468 bus_space_write_1(iot, ioh, com_fifo,
469 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
470 delay(100);
471 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_FIFO_MASK)
472 == IIR_FIFO_MASK)
473 if (ISSET(bus_space_read_1(iot, ioh, com_fifo), FIFO_TRIGGER_14)
474 == FIFO_TRIGGER_14) {
475 SET(sc->sc_hwflags, COM_HW_FIFO);
476
477 #ifdef COM16650
478 /*
479 * IIR changes into the EFR if LCR is set to LCR_EERS
480 * on 16650s. We also know IIR != 0 at this point.
481 * Write 0 into the EFR, and read it. If the result
482 * is 0, we have a 16650.
483 *
484 * Older 16650s were broken; the test to detect them
485 * is taken from the Linux driver. Apparently
486 * setting DLAB enable gives access to the EFR on
487 * these chips.
488 */
489 lcr = bus_space_read_1(iot, ioh, com_lcr);
490 bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
491 bus_space_write_1(iot, ioh, com_efr, 0);
492 if (bus_space_read_1(iot, ioh, com_efr) == 0) {
493 bus_space_write_1(iot, ioh, com_lcr,
494 lcr | LCR_DLAB);
495 if (bus_space_read_1(iot, ioh, com_efr) == 0) {
496 CLR(sc->sc_hwflags, COM_HW_FIFO);
497 sc->sc_fifolen = 0;
498 } else {
499 SET(sc->sc_hwflags, COM_HW_FLOW);
500 sc->sc_fifolen = 32;
501 }
502 } else
503 #endif
504 sc->sc_fifolen = 16;
505
506 #ifdef COM16650
507 bus_space_write_1(iot, ioh, com_lcr, lcr);
508 if (sc->sc_fifolen == 0)
509 printf(": st16650, broken fifo\n");
510 else if (sc->sc_fifolen == 32)
511 printf(": st16650a, working fifo\n");
512 else
513 #endif
514 printf(": ns16550a, working fifo\n");
515 } else
516 printf(": ns16550, broken fifo\n");
517 else
518 printf(": ns8250 or ns16450, no fifo\n");
519 bus_space_write_1(iot, ioh, com_fifo, 0);
520 if (ISSET(sc->sc_hwflags, COM_HW_TXFIFO_DISABLE)) {
521 sc->sc_fifolen = 1;
522 printf("%s: txfifo disabled\n", sc->sc_dev.dv_xname);
523 }
524 #ifdef COM_HAYESP
525 }
526 #endif
527
528 tp = ttymalloc();
529 tp->t_oproc = comstart;
530 tp->t_param = comparam;
531 tp->t_hwiflow = comhwiflow;
532
533 sc->sc_tty = tp;
534 sc->sc_rbuf = malloc(com_rbuf_size << 1, M_DEVBUF, M_NOWAIT);
535 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
536 sc->sc_rbavail = com_rbuf_size;
537 if (sc->sc_rbuf == NULL) {
538 printf("%s: unable to allocate ring buffer\n",
539 sc->sc_dev.dv_xname);
540 return;
541 }
542 sc->sc_ebuf = sc->sc_rbuf + (com_rbuf_size << 1);
543
544 tty_attach(tp);
545
546 if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
547 SET(sc->sc_mcr, MCR_IENABLE);
548
549 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
550 int maj;
551
552 /* locate the major number */
553 for (maj = 0; maj < nchrdev; maj++)
554 if (cdevsw[maj].d_open == comopen)
555 break;
556
557 cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
558
559 printf("%s: console\n", sc->sc_dev.dv_xname);
560 }
561
562 #ifdef KGDB
563 /*
564 * Allow kgdb to "take over" this port. If this is
565 * the kgdb device, it has exclusive use.
566 */
567 if (iot == com_kgdb_iot && iobase == com_kgdb_addr) {
568 com_kgdb_attached = 1;
569
570 SET(sc->sc_hwflags, COM_HW_KGDB);
571 printf("%s: kgdb\n", sc->sc_dev.dv_xname);
572 }
573 #endif
574
575 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
576 sc->sc_si = softintr_establish(IPL_SOFTSERIAL, comsoft, sc);
577 #endif
578
579 #if NRND > 0 && defined(RND_COM)
580 rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
581 RND_TYPE_TTY, 0);
582 #endif
583
584 /* if there are no enable/disable functions, assume the device
585 is always enabled */
586 if (!sc->enable)
587 sc->enabled = 1;
588
589 com_config(sc);
590
591 SET(sc->sc_hwflags, COM_HW_DEV_OK);
592 }
593
594 void
595 com_config(sc)
596 struct com_softc *sc;
597 {
598 bus_space_tag_t iot = sc->sc_iot;
599 bus_space_handle_t ioh = sc->sc_ioh;
600
601 /* Disable interrupts before configuring the device. */
602 sc->sc_ier = 0;
603 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
604
605 #ifdef COM_HAYESP
606 /* Look for a Hayes ESP board. */
607 if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
608 sc->sc_fifolen = 1024;
609
610 /* Set 16550 compatibility mode */
611 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
612 HAYESP_SETMODE);
613 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
614 HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
615 HAYESP_MODE_SCALE);
616
617 /* Set RTS/CTS flow control */
618 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
619 HAYESP_SETFLOWTYPE);
620 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
621 HAYESP_FLOW_RTS);
622 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
623 HAYESP_FLOW_CTS);
624
625 /* Set flow control levels */
626 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
627 HAYESP_SETRXFLOW);
628 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
629 HAYESP_HIBYTE(HAYESP_RXHIWMARK));
630 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
631 HAYESP_LOBYTE(HAYESP_RXHIWMARK));
632 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
633 HAYESP_HIBYTE(HAYESP_RXLOWMARK));
634 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
635 HAYESP_LOBYTE(HAYESP_RXLOWMARK));
636 }
637 #endif
638
639 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE|COM_HW_KGDB))
640 com_enable_debugport(sc);
641 }
642
643 int
644 com_detach(self, flags)
645 struct device *self;
646 int flags;
647 {
648 struct com_softc *sc = (struct com_softc *)self;
649 int maj, mn;
650
651 /* locate the major number */
652 for (maj = 0; maj < nchrdev; maj++)
653 if (cdevsw[maj].d_open == comopen)
654 break;
655
656 /* Nuke the vnodes for any open instances. */
657 mn = self->dv_unit;
658 vdevgone(maj, mn, mn, VCHR);
659
660 mn |= COMDIALOUT_MASK;
661 vdevgone(maj, mn, mn, VCHR);
662
663 if (sc->sc_rbuf == NULL) {
664 /*
665 * Ring buffer allocation failed in the com_attach_subr,
666 * only the tty is allocated, and nothing else.
667 */
668 ttyfree(sc->sc_tty);
669 return 0;
670 }
671
672 /* Free the receive buffer. */
673 free(sc->sc_rbuf, M_DEVBUF);
674
675 /* Detach and free the tty. */
676 tty_detach(sc->sc_tty);
677 ttyfree(sc->sc_tty);
678
679 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
680 /* Unhook the soft interrupt handler. */
681 softintr_disestablish(sc->sc_si);
682 #endif
683
684 #if NRND > 0 && defined(RND_COM)
685 /* Unhook the entropy source. */
686 rnd_detach_source(&sc->rnd_source);
687 #endif
688
689 return (0);
690 }
691
692 int
693 com_activate(self, act)
694 struct device *self;
695 enum devact act;
696 {
697 struct com_softc *sc = (struct com_softc *)self;
698 int s, rv = 0;
699
700 s = splserial();
701 COM_LOCK(sc);
702 switch (act) {
703 case DVACT_ACTIVATE:
704 rv = EOPNOTSUPP;
705 break;
706
707 case DVACT_DEACTIVATE:
708 if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) {
709 rv = EBUSY;
710 break;
711 }
712
713 if (sc->disable != NULL && sc->enabled != 0) {
714 (*sc->disable)(sc);
715 sc->enabled = 0;
716 }
717 break;
718 }
719
720 COM_UNLOCK(sc);
721 splx(s);
722 return (rv);
723 }
724
725 void
726 com_shutdown(sc)
727 struct com_softc *sc;
728 {
729 struct tty *tp = sc->sc_tty;
730 int s;
731
732 s = splserial();
733 COM_LOCK(sc);
734
735 /* If we were asserting flow control, then deassert it. */
736 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
737 com_hwiflow(sc);
738
739 /* Clear any break condition set with TIOCSBRK. */
740 com_break(sc, 0);
741
742 /* Turn off PPS capture on last close. */
743 sc->sc_ppsmask = 0;
744 sc->ppsparam.mode = 0;
745
746 /*
747 * Hang up if necessary. Wait a bit, so the other side has time to
748 * notice even if we immediately open the port again.
749 * Avoid tsleeping above splhigh().
750 */
751 if (ISSET(tp->t_cflag, HUPCL)) {
752 com_modem(sc, 0);
753 COM_UNLOCK(sc);
754 splx(s);
755 /* XXX tsleep will only timeout */
756 (void) tsleep(sc, TTIPRI, ttclos, hz);
757 s = splserial();
758 COM_LOCK(sc);
759 }
760
761 /* Turn off interrupts. */
762 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
763 sc->sc_ier = IER_ERXRDY; /* interrupt on break */
764 else
765 sc->sc_ier = 0;
766 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
767
768 if (sc->disable) {
769 #ifdef DIAGNOSTIC
770 if (!sc->enabled)
771 panic("com_shutdown: not enabled?");
772 #endif
773 (*sc->disable)(sc);
774 sc->enabled = 0;
775 }
776 COM_UNLOCK(sc);
777 splx(s);
778 }
779
780 int
781 comopen(dev, flag, mode, p)
782 dev_t dev;
783 int flag, mode;
784 struct proc *p;
785 {
786 struct com_softc *sc;
787 struct tty *tp;
788 int s, s2;
789 int error;
790
791 sc = device_lookup(&com_cd, COMUNIT(dev));
792 if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK) ||
793 sc->sc_rbuf == NULL)
794 return (ENXIO);
795
796 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
797 return (ENXIO);
798
799 #ifdef KGDB
800 /*
801 * If this is the kgdb port, no other use is permitted.
802 */
803 if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
804 return (EBUSY);
805 #endif
806
807 tp = sc->sc_tty;
808
809 if (ISSET(tp->t_state, TS_ISOPEN) &&
810 ISSET(tp->t_state, TS_XCLUDE) &&
811 p->p_ucred->cr_uid != 0)
812 return (EBUSY);
813
814 s = spltty();
815
816 /*
817 * Do the following iff this is a first open.
818 */
819 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
820 struct termios t;
821
822 tp->t_dev = dev;
823
824 s2 = splserial();
825 COM_LOCK(sc);
826
827 if (sc->enable) {
828 if ((*sc->enable)(sc)) {
829 COM_UNLOCK(sc);
830 splx(s2);
831 splx(s);
832 printf("%s: device enable failed\n",
833 sc->sc_dev.dv_xname);
834 return (EIO);
835 }
836 sc->enabled = 1;
837 com_config(sc);
838 }
839
840 /* Turn on interrupts. */
841 sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
842 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
843
844 /* Fetch the current modem control status, needed later. */
845 sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr);
846
847 /* Clear PPS capture state on first open. */
848 sc->sc_ppsmask = 0;
849 sc->ppsparam.mode = 0;
850
851 COM_UNLOCK(sc);
852 splx(s2);
853
854 /*
855 * Initialize the termios status to the defaults. Add in the
856 * sticky bits from TIOCSFLAGS.
857 */
858 t.c_ispeed = 0;
859 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
860 t.c_ospeed = comconsrate;
861 t.c_cflag = comconscflag;
862 } else {
863 t.c_ospeed = TTYDEF_SPEED;
864 t.c_cflag = TTYDEF_CFLAG;
865 }
866 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
867 SET(t.c_cflag, CLOCAL);
868 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
869 SET(t.c_cflag, CRTSCTS);
870 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
871 SET(t.c_cflag, MDMBUF);
872 /* Make sure comparam() will do something. */
873 tp->t_ospeed = 0;
874 (void) comparam(tp, &t);
875 tp->t_iflag = TTYDEF_IFLAG;
876 tp->t_oflag = TTYDEF_OFLAG;
877 tp->t_lflag = TTYDEF_LFLAG;
878 ttychars(tp);
879 ttsetwater(tp);
880
881 s2 = splserial();
882 COM_LOCK(sc);
883
884 /*
885 * Turn on DTR. We must always do this, even if carrier is not
886 * present, because otherwise we'd have to use TIOCSDTR
887 * immediately after setting CLOCAL, which applications do not
888 * expect. We always assert DTR while the device is open
889 * unless explicitly requested to deassert it.
890 */
891 com_modem(sc, 1);
892
893 /* Clear the input ring, and unblock. */
894 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
895 sc->sc_rbavail = com_rbuf_size;
896 com_iflush(sc);
897 CLR(sc->sc_rx_flags, RX_ANY_BLOCK);
898 com_hwiflow(sc);
899
900 #ifdef COM_DEBUG
901 if (com_debug)
902 comstatus(sc, "comopen ");
903 #endif
904
905 COM_UNLOCK(sc);
906 splx(s2);
907 }
908
909 splx(s);
910
911 error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK));
912 if (error)
913 goto bad;
914
915 error = (*tp->t_linesw->l_open)(dev, tp);
916 if (error)
917 goto bad;
918
919 return (0);
920
921 bad:
922 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
923 /*
924 * We failed to open the device, and nobody else had it opened.
925 * Clean up the state as appropriate.
926 */
927 com_shutdown(sc);
928 }
929
930 return (error);
931 }
932
933 int
934 comclose(dev, flag, mode, p)
935 dev_t dev;
936 int flag, mode;
937 struct proc *p;
938 {
939 struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
940 struct tty *tp = sc->sc_tty;
941
942 /* XXX This is for cons.c. */
943 if (!ISSET(tp->t_state, TS_ISOPEN))
944 return (0);
945
946 (*tp->t_linesw->l_close)(tp, flag);
947 ttyclose(tp);
948
949 if (COM_ISALIVE(sc) == 0)
950 return (0);
951
952 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
953 /*
954 * Although we got a last close, the device may still be in
955 * use; e.g. if this was the dialout node, and there are still
956 * processes waiting for carrier on the non-dialout node.
957 */
958 com_shutdown(sc);
959 }
960
961 return (0);
962 }
963
964 int
965 comread(dev, uio, flag)
966 dev_t dev;
967 struct uio *uio;
968 int flag;
969 {
970 struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
971 struct tty *tp = sc->sc_tty;
972
973 if (COM_ISALIVE(sc) == 0)
974 return (EIO);
975
976 return ((*tp->t_linesw->l_read)(tp, uio, flag));
977 }
978
979 int
980 comwrite(dev, uio, flag)
981 dev_t dev;
982 struct uio *uio;
983 int flag;
984 {
985 struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
986 struct tty *tp = sc->sc_tty;
987
988 if (COM_ISALIVE(sc) == 0)
989 return (EIO);
990
991 return ((*tp->t_linesw->l_write)(tp, uio, flag));
992 }
993
994 int
995 compoll(dev, events, p)
996 dev_t dev;
997 int events;
998 struct proc *p;
999 {
1000 struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
1001 struct tty *tp = sc->sc_tty;
1002
1003 if (COM_ISALIVE(sc) == 0)
1004 return (EIO);
1005
1006 return ((*tp->t_linesw->l_poll)(tp, events, p));
1007 }
1008
1009 struct tty *
1010 comtty(dev)
1011 dev_t dev;
1012 {
1013 struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
1014 struct tty *tp = sc->sc_tty;
1015
1016 return (tp);
1017 }
1018
1019 int
1020 comioctl(dev, cmd, data, flag, p)
1021 dev_t dev;
1022 u_long cmd;
1023 caddr_t data;
1024 int flag;
1025 struct proc *p;
1026 {
1027 struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
1028 struct tty *tp = sc->sc_tty;
1029 int error;
1030 int s;
1031
1032 if (COM_ISALIVE(sc) == 0)
1033 return (EIO);
1034
1035 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p);
1036 if (error != EPASSTHROUGH)
1037 return (error);
1038
1039 error = ttioctl(tp, cmd, data, flag, p);
1040 if (error != EPASSTHROUGH)
1041 return (error);
1042
1043 error = 0;
1044
1045 s = splserial();
1046 COM_LOCK(sc);
1047
1048 switch (cmd) {
1049 case TIOCSBRK:
1050 com_break(sc, 1);
1051 break;
1052
1053 case TIOCCBRK:
1054 com_break(sc, 0);
1055 break;
1056
1057 case TIOCSDTR:
1058 com_modem(sc, 1);
1059 break;
1060
1061 case TIOCCDTR:
1062 com_modem(sc, 0);
1063 break;
1064
1065 case TIOCGFLAGS:
1066 *(int *)data = sc->sc_swflags;
1067 break;
1068
1069 case TIOCSFLAGS:
1070 error = suser(p->p_ucred, &p->p_acflag);
1071 if (error)
1072 break;
1073 sc->sc_swflags = *(int *)data;
1074 break;
1075
1076 case TIOCMSET:
1077 case TIOCMBIS:
1078 case TIOCMBIC:
1079 tiocm_to_com(sc, cmd, *(int *)data);
1080 break;
1081
1082 case TIOCMGET:
1083 *(int *)data = com_to_tiocm(sc);
1084 break;
1085
1086 case PPS_IOC_CREATE:
1087 break;
1088
1089 case PPS_IOC_DESTROY:
1090 break;
1091
1092 case PPS_IOC_GETPARAMS: {
1093 pps_params_t *pp;
1094 pp = (pps_params_t *)data;
1095 *pp = sc->ppsparam;
1096 break;
1097 }
1098
1099 case PPS_IOC_SETPARAMS: {
1100 pps_params_t *pp;
1101 int mode;
1102 pp = (pps_params_t *)data;
1103 if (pp->mode & ~ppscap) {
1104 error = EINVAL;
1105 break;
1106 }
1107 sc->ppsparam = *pp;
1108 /*
1109 * Compute msr masks from user-specified timestamp state.
1110 */
1111 mode = sc->ppsparam.mode;
1112 #ifdef PPS_SYNC
1113 if (mode & PPS_HARDPPSONASSERT) {
1114 mode |= PPS_CAPTUREASSERT;
1115 /* XXX revoke any previous HARDPPS source */
1116 }
1117 if (mode & PPS_HARDPPSONCLEAR) {
1118 mode |= PPS_CAPTURECLEAR;
1119 /* XXX revoke any previous HARDPPS source */
1120 }
1121 #endif /* PPS_SYNC */
1122 switch (mode & PPS_CAPTUREBOTH) {
1123 case 0:
1124 sc->sc_ppsmask = 0;
1125 break;
1126
1127 case PPS_CAPTUREASSERT:
1128 sc->sc_ppsmask = MSR_DCD;
1129 sc->sc_ppsassert = MSR_DCD;
1130 sc->sc_ppsclear = -1;
1131 break;
1132
1133 case PPS_CAPTURECLEAR:
1134 sc->sc_ppsmask = MSR_DCD;
1135 sc->sc_ppsassert = -1;
1136 sc->sc_ppsclear = 0;
1137 break;
1138
1139 case PPS_CAPTUREBOTH:
1140 sc->sc_ppsmask = MSR_DCD;
1141 sc->sc_ppsassert = MSR_DCD;
1142 sc->sc_ppsclear = 0;
1143 break;
1144
1145 default:
1146 error = EINVAL;
1147 break;
1148 }
1149 break;
1150 }
1151
1152 case PPS_IOC_GETCAP:
1153 *(int*)data = ppscap;
1154 break;
1155
1156 case PPS_IOC_FETCH: {
1157 pps_info_t *pi;
1158 pi = (pps_info_t *)data;
1159 *pi = sc->ppsinfo;
1160 break;
1161 }
1162
1163 case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */
1164 /*
1165 * Some GPS clocks models use the falling rather than
1166 * rising edge as the on-the-second signal.
1167 * The old API has no way to specify PPS polarity.
1168 */
1169 sc->sc_ppsmask = MSR_DCD;
1170 #ifndef PPS_TRAILING_EDGE
1171 sc->sc_ppsassert = MSR_DCD;
1172 sc->sc_ppsclear = -1;
1173 TIMESPEC_TO_TIMEVAL((struct timeval *)data,
1174 &sc->ppsinfo.assert_timestamp);
1175 #else
1176 sc->sc_ppsassert = -1
1177 sc->sc_ppsclear = 0;
1178 TIMESPEC_TO_TIMEVAL((struct timeval *)data,
1179 &sc->ppsinfo.clear_timestamp);
1180 #endif
1181 break;
1182
1183 default:
1184 error = EPASSTHROUGH;
1185 break;
1186 }
1187
1188 COM_UNLOCK(sc);
1189 splx(s);
1190
1191 #ifdef COM_DEBUG
1192 if (com_debug)
1193 comstatus(sc, "comioctl ");
1194 #endif
1195
1196 return (error);
1197 }
1198
1199 integrate void
1200 com_schedrx(sc)
1201 struct com_softc *sc;
1202 {
1203
1204 sc->sc_rx_ready = 1;
1205
1206 /* Wake up the poller. */
1207 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
1208 softintr_schedule(sc->sc_si);
1209 #else
1210 #ifndef __NO_SOFT_SERIAL_INTERRUPT
1211 setsoftserial();
1212 #else
1213 if (!com_softintr_scheduled) {
1214 com_softintr_scheduled = 1;
1215 callout_reset(&comsoft_callout, 1, comsoft, NULL);
1216 }
1217 #endif
1218 #endif
1219 }
1220
1221 void
1222 com_break(sc, onoff)
1223 struct com_softc *sc;
1224 int onoff;
1225 {
1226
1227 if (onoff)
1228 SET(sc->sc_lcr, LCR_SBREAK);
1229 else
1230 CLR(sc->sc_lcr, LCR_SBREAK);
1231
1232 if (!sc->sc_heldchange) {
1233 if (sc->sc_tx_busy) {
1234 sc->sc_heldtbc = sc->sc_tbc;
1235 sc->sc_tbc = 0;
1236 sc->sc_heldchange = 1;
1237 } else
1238 com_loadchannelregs(sc);
1239 }
1240 }
1241
1242 void
1243 com_modem(sc, onoff)
1244 struct com_softc *sc;
1245 int onoff;
1246 {
1247
1248 if (sc->sc_mcr_dtr == 0)
1249 return;
1250
1251 if (onoff)
1252 SET(sc->sc_mcr, sc->sc_mcr_dtr);
1253 else
1254 CLR(sc->sc_mcr, sc->sc_mcr_dtr);
1255
1256 if (!sc->sc_heldchange) {
1257 if (sc->sc_tx_busy) {
1258 sc->sc_heldtbc = sc->sc_tbc;
1259 sc->sc_tbc = 0;
1260 sc->sc_heldchange = 1;
1261 } else
1262 com_loadchannelregs(sc);
1263 }
1264 }
1265
1266 void
1267 tiocm_to_com(sc, how, ttybits)
1268 struct com_softc *sc;
1269 u_long how;
1270 int ttybits;
1271 {
1272 u_char combits;
1273
1274 combits = 0;
1275 if (ISSET(ttybits, TIOCM_DTR))
1276 SET(combits, MCR_DTR);
1277 if (ISSET(ttybits, TIOCM_RTS))
1278 SET(combits, MCR_RTS);
1279
1280 switch (how) {
1281 case TIOCMBIC:
1282 CLR(sc->sc_mcr, combits);
1283 break;
1284
1285 case TIOCMBIS:
1286 SET(sc->sc_mcr, combits);
1287 break;
1288
1289 case TIOCMSET:
1290 CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
1291 SET(sc->sc_mcr, combits);
1292 break;
1293 }
1294
1295 if (!sc->sc_heldchange) {
1296 if (sc->sc_tx_busy) {
1297 sc->sc_heldtbc = sc->sc_tbc;
1298 sc->sc_tbc = 0;
1299 sc->sc_heldchange = 1;
1300 } else
1301 com_loadchannelregs(sc);
1302 }
1303 }
1304
1305 int
1306 com_to_tiocm(sc)
1307 struct com_softc *sc;
1308 {
1309 u_char combits;
1310 int ttybits = 0;
1311
1312 combits = sc->sc_mcr;
1313 if (ISSET(combits, MCR_DTR))
1314 SET(ttybits, TIOCM_DTR);
1315 if (ISSET(combits, MCR_RTS))
1316 SET(ttybits, TIOCM_RTS);
1317
1318 combits = sc->sc_msr;
1319 if (ISSET(combits, MSR_DCD))
1320 SET(ttybits, TIOCM_CD);
1321 if (ISSET(combits, MSR_CTS))
1322 SET(ttybits, TIOCM_CTS);
1323 if (ISSET(combits, MSR_DSR))
1324 SET(ttybits, TIOCM_DSR);
1325 if (ISSET(combits, MSR_RI | MSR_TERI))
1326 SET(ttybits, TIOCM_RI);
1327
1328 if (sc->sc_ier != 0)
1329 SET(ttybits, TIOCM_LE);
1330
1331 return (ttybits);
1332 }
1333
1334 static u_char
1335 cflag2lcr(cflag)
1336 tcflag_t cflag;
1337 {
1338 u_char lcr = 0;
1339
1340 switch (ISSET(cflag, CSIZE)) {
1341 case CS5:
1342 SET(lcr, LCR_5BITS);
1343 break;
1344 case CS6:
1345 SET(lcr, LCR_6BITS);
1346 break;
1347 case CS7:
1348 SET(lcr, LCR_7BITS);
1349 break;
1350 case CS8:
1351 SET(lcr, LCR_8BITS);
1352 break;
1353 }
1354 if (ISSET(cflag, PARENB)) {
1355 SET(lcr, LCR_PENAB);
1356 if (!ISSET(cflag, PARODD))
1357 SET(lcr, LCR_PEVEN);
1358 }
1359 if (ISSET(cflag, CSTOPB))
1360 SET(lcr, LCR_STOPB);
1361
1362 return (lcr);
1363 }
1364
1365 int
1366 comparam(tp, t)
1367 struct tty *tp;
1368 struct termios *t;
1369 {
1370 struct com_softc *sc = device_lookup(&com_cd, COMUNIT(tp->t_dev));
1371 int ospeed;
1372 u_char lcr;
1373 int s;
1374
1375 if (COM_ISALIVE(sc) == 0)
1376 return (EIO);
1377
1378 #ifdef COM_HAYESP
1379 if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
1380 int prescaler, speed;
1381
1382 /*
1383 * Calculate UART clock prescaler. It should be in
1384 * range of 0 .. 3.
1385 */
1386 for (prescaler = 0, speed = t->c_ospeed; prescaler < 4;
1387 prescaler++, speed /= 2)
1388 if ((ospeed = comspeed(speed, sc->sc_frequency)) > 0)
1389 break;
1390
1391 if (prescaler == 4)
1392 return (EINVAL);
1393 sc->sc_prescaler = prescaler;
1394 } else
1395 #endif
1396 ospeed = comspeed(t->c_ospeed, sc->sc_frequency);
1397
1398 /* Check requested parameters. */
1399 if (ospeed < 0)
1400 return (EINVAL);
1401 if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
1402 return (EINVAL);
1403
1404 /*
1405 * For the console, always force CLOCAL and !HUPCL, so that the port
1406 * is always active.
1407 */
1408 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) ||
1409 ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
1410 SET(t->c_cflag, CLOCAL);
1411 CLR(t->c_cflag, HUPCL);
1412 }
1413
1414 /*
1415 * If there were no changes, don't do anything. This avoids dropping
1416 * input and improves performance when all we did was frob things like
1417 * VMIN and VTIME.
1418 */
1419 if (tp->t_ospeed == t->c_ospeed &&
1420 tp->t_cflag == t->c_cflag)
1421 return (0);
1422
1423 lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag);
1424
1425 s = splserial();
1426 COM_LOCK(sc);
1427
1428 sc->sc_lcr = lcr;
1429
1430 /*
1431 * If we're not in a mode that assumes a connection is present, then
1432 * ignore carrier changes.
1433 */
1434 if (ISSET(t->c_cflag, CLOCAL | MDMBUF))
1435 sc->sc_msr_dcd = 0;
1436 else
1437 sc->sc_msr_dcd = MSR_DCD;
1438 /*
1439 * Set the flow control pins depending on the current flow control
1440 * mode.
1441 */
1442 if (ISSET(t->c_cflag, CRTSCTS)) {
1443 sc->sc_mcr_dtr = MCR_DTR;
1444 sc->sc_mcr_rts = MCR_RTS;
1445 sc->sc_msr_cts = MSR_CTS;
1446 sc->sc_efr = EFR_AUTORTS | EFR_AUTOCTS;
1447 } else if (ISSET(t->c_cflag, MDMBUF)) {
1448 /*
1449 * For DTR/DCD flow control, make sure we don't toggle DTR for
1450 * carrier detection.
1451 */
1452 sc->sc_mcr_dtr = 0;
1453 sc->sc_mcr_rts = MCR_DTR;
1454 sc->sc_msr_cts = MSR_DCD;
1455 sc->sc_efr = 0;
1456 } else {
1457 /*
1458 * If no flow control, then always set RTS. This will make
1459 * the other side happy if it mistakenly thinks we're doing
1460 * RTS/CTS flow control.
1461 */
1462 sc->sc_mcr_dtr = MCR_DTR | MCR_RTS;
1463 sc->sc_mcr_rts = 0;
1464 sc->sc_msr_cts = 0;
1465 sc->sc_efr = 0;
1466 if (ISSET(sc->sc_mcr, MCR_DTR))
1467 SET(sc->sc_mcr, MCR_RTS);
1468 else
1469 CLR(sc->sc_mcr, MCR_RTS);
1470 }
1471 sc->sc_msr_mask = sc->sc_msr_cts | sc->sc_msr_dcd;
1472
1473 #if 0
1474 if (ospeed == 0)
1475 CLR(sc->sc_mcr, sc->sc_mcr_dtr);
1476 else
1477 SET(sc->sc_mcr, sc->sc_mcr_dtr);
1478 #endif
1479
1480 sc->sc_dlbl = ospeed;
1481 sc->sc_dlbh = ospeed >> 8;
1482
1483 /*
1484 * Set the FIFO threshold based on the receive speed.
1485 *
1486 * * If it's a low speed, it's probably a mouse or some other
1487 * interactive device, so set the threshold low.
1488 * * If it's a high speed, trim the trigger level down to prevent
1489 * overflows.
1490 * * Otherwise set it a bit higher.
1491 */
1492 if (ISSET(sc->sc_hwflags, COM_HW_HAYESP))
1493 sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8;
1494 else if (ISSET(sc->sc_hwflags, COM_HW_FIFO))
1495 sc->sc_fifo = FIFO_ENABLE |
1496 (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 :
1497 t->c_ospeed <= 38400 ? FIFO_TRIGGER_8 : FIFO_TRIGGER_4);
1498 else
1499 sc->sc_fifo = 0;
1500
1501 /* And copy to tty. */
1502 tp->t_ispeed = 0;
1503 tp->t_ospeed = t->c_ospeed;
1504 tp->t_cflag = t->c_cflag;
1505
1506 if (!sc->sc_heldchange) {
1507 if (sc->sc_tx_busy) {
1508 sc->sc_heldtbc = sc->sc_tbc;
1509 sc->sc_tbc = 0;
1510 sc->sc_heldchange = 1;
1511 } else
1512 com_loadchannelregs(sc);
1513 }
1514
1515 if (!ISSET(t->c_cflag, CHWFLOW)) {
1516 /* Disable the high water mark. */
1517 sc->sc_r_hiwat = 0;
1518 sc->sc_r_lowat = 0;
1519 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
1520 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1521 com_schedrx(sc);
1522 }
1523 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
1524 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
1525 com_hwiflow(sc);
1526 }
1527 } else {
1528 sc->sc_r_hiwat = com_rbuf_hiwat;
1529 sc->sc_r_lowat = com_rbuf_lowat;
1530 }
1531
1532 COM_UNLOCK(sc);
1533 splx(s);
1534
1535 /*
1536 * Update the tty layer's idea of the carrier bit, in case we changed
1537 * CLOCAL or MDMBUF. We don't hang up here; we only do that by
1538 * explicit request.
1539 */
1540 (void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, MSR_DCD));
1541
1542 #ifdef COM_DEBUG
1543 if (com_debug)
1544 comstatus(sc, "comparam ");
1545 #endif
1546
1547 if (!ISSET(t->c_cflag, CHWFLOW)) {
1548 if (sc->sc_tx_stopped) {
1549 sc->sc_tx_stopped = 0;
1550 comstart(tp);
1551 }
1552 }
1553
1554 return (0);
1555 }
1556
1557 void
1558 com_iflush(sc)
1559 struct com_softc *sc;
1560 {
1561 bus_space_tag_t iot = sc->sc_iot;
1562 bus_space_handle_t ioh = sc->sc_ioh;
1563 #ifdef DIAGNOSTIC
1564 int reg;
1565 #endif
1566 int timo;
1567
1568 #ifdef DIAGNOSTIC
1569 reg = 0xffff;
1570 #endif
1571 timo = 50000;
1572 /* flush any pending I/O */
1573 while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)
1574 && --timo)
1575 #ifdef DIAGNOSTIC
1576 reg =
1577 #else
1578 (void)
1579 #endif
1580 bus_space_read_1(iot, ioh, com_data);
1581 #ifdef DIAGNOSTIC
1582 if (!timo)
1583 printf("%s: com_iflush timeout %02x\n", sc->sc_dev.dv_xname,
1584 reg);
1585 #endif
1586 }
1587
1588 void
1589 com_loadchannelregs(sc)
1590 struct com_softc *sc;
1591 {
1592 bus_space_tag_t iot = sc->sc_iot;
1593 bus_space_handle_t ioh = sc->sc_ioh;
1594
1595 /* XXXXX necessary? */
1596 com_iflush(sc);
1597
1598 bus_space_write_1(iot, ioh, com_ier, 0);
1599
1600 if (ISSET(sc->sc_hwflags, COM_HW_FLOW)) {
1601 bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
1602 bus_space_write_1(iot, ioh, com_efr, sc->sc_efr);
1603 }
1604 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr | LCR_DLAB);
1605 bus_space_write_1(iot, ioh, com_dlbl, sc->sc_dlbl);
1606 bus_space_write_1(iot, ioh, com_dlbh, sc->sc_dlbh);
1607 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
1608 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active = sc->sc_mcr);
1609 bus_space_write_1(iot, ioh, com_fifo, sc->sc_fifo);
1610 #ifdef COM_HAYESP
1611 if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
1612 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
1613 HAYESP_SETPRESCALER);
1614 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
1615 sc->sc_prescaler);
1616 }
1617 #endif
1618
1619 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1620 }
1621
1622 int
1623 comhwiflow(tp, block)
1624 struct tty *tp;
1625 int block;
1626 {
1627 struct com_softc *sc = device_lookup(&com_cd, COMUNIT(tp->t_dev));
1628 int s;
1629
1630 if (COM_ISALIVE(sc) == 0)
1631 return (0);
1632
1633 if (sc->sc_mcr_rts == 0)
1634 return (0);
1635
1636 s = splserial();
1637 COM_LOCK(sc);
1638
1639 if (block) {
1640 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1641 SET(sc->sc_rx_flags, RX_TTY_BLOCKED);
1642 com_hwiflow(sc);
1643 }
1644 } else {
1645 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
1646 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1647 com_schedrx(sc);
1648 }
1649 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1650 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED);
1651 com_hwiflow(sc);
1652 }
1653 }
1654
1655 COM_UNLOCK(sc);
1656 splx(s);
1657 return (1);
1658 }
1659
1660 /*
1661 * (un)block input via hw flowcontrol
1662 */
1663 void
1664 com_hwiflow(sc)
1665 struct com_softc *sc;
1666 {
1667 bus_space_tag_t iot = sc->sc_iot;
1668 bus_space_handle_t ioh = sc->sc_ioh;
1669
1670 if (sc->sc_mcr_rts == 0)
1671 return;
1672
1673 if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) {
1674 CLR(sc->sc_mcr, sc->sc_mcr_rts);
1675 CLR(sc->sc_mcr_active, sc->sc_mcr_rts);
1676 } else {
1677 SET(sc->sc_mcr, sc->sc_mcr_rts);
1678 SET(sc->sc_mcr_active, sc->sc_mcr_rts);
1679 }
1680 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active);
1681 }
1682
1683
1684 void
1685 comstart(tp)
1686 struct tty *tp;
1687 {
1688 struct com_softc *sc = device_lookup(&com_cd, COMUNIT(tp->t_dev));
1689 bus_space_tag_t iot = sc->sc_iot;
1690 bus_space_handle_t ioh = sc->sc_ioh;
1691 int s;
1692
1693 if (COM_ISALIVE(sc) == 0)
1694 return;
1695
1696 s = spltty();
1697 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
1698 goto out;
1699 if (sc->sc_tx_stopped)
1700 goto out;
1701
1702 if (tp->t_outq.c_cc <= tp->t_lowat) {
1703 if (ISSET(tp->t_state, TS_ASLEEP)) {
1704 CLR(tp->t_state, TS_ASLEEP);
1705 wakeup(&tp->t_outq);
1706 }
1707 selwakeup(&tp->t_wsel);
1708 if (tp->t_outq.c_cc == 0)
1709 goto out;
1710 }
1711
1712 /* Grab the first contiguous region of buffer space. */
1713 {
1714 u_char *tba;
1715 int tbc;
1716
1717 tba = tp->t_outq.c_cf;
1718 tbc = ndqb(&tp->t_outq, 0);
1719
1720 (void)splserial();
1721 COM_LOCK(sc);
1722
1723 sc->sc_tba = tba;
1724 sc->sc_tbc = tbc;
1725 }
1726
1727 SET(tp->t_state, TS_BUSY);
1728 sc->sc_tx_busy = 1;
1729
1730 /* Enable transmit completion interrupts if necessary. */
1731 if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
1732 SET(sc->sc_ier, IER_ETXRDY);
1733 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1734 }
1735
1736 /* Output the first chunk of the contiguous buffer. */
1737 if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) {
1738 int n;
1739
1740 n = sc->sc_tbc;
1741 if (n > sc->sc_fifolen)
1742 n = sc->sc_fifolen;
1743 bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n);
1744 sc->sc_tbc -= n;
1745 sc->sc_tba += n;
1746 }
1747 COM_UNLOCK(sc);
1748 out:
1749 splx(s);
1750 return;
1751 }
1752
1753 /*
1754 * Stop output on a line.
1755 */
1756 void
1757 comstop(tp, flag)
1758 struct tty *tp;
1759 int flag;
1760 {
1761 struct com_softc *sc = device_lookup(&com_cd, COMUNIT(tp->t_dev));
1762 int s;
1763
1764 s = splserial();
1765 COM_LOCK(sc);
1766 if (ISSET(tp->t_state, TS_BUSY)) {
1767 /* Stop transmitting at the next chunk. */
1768 sc->sc_tbc = 0;
1769 sc->sc_heldtbc = 0;
1770 if (!ISSET(tp->t_state, TS_TTSTOP))
1771 SET(tp->t_state, TS_FLUSH);
1772 }
1773 COM_UNLOCK(sc);
1774 splx(s);
1775 }
1776
1777 void
1778 comdiag(arg)
1779 void *arg;
1780 {
1781 struct com_softc *sc = arg;
1782 int overflows, floods;
1783 int s;
1784
1785 s = splserial();
1786 COM_LOCK(sc);
1787 overflows = sc->sc_overflows;
1788 sc->sc_overflows = 0;
1789 floods = sc->sc_floods;
1790 sc->sc_floods = 0;
1791 sc->sc_errors = 0;
1792 COM_UNLOCK(sc);
1793 splx(s);
1794
1795 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
1796 sc->sc_dev.dv_xname,
1797 overflows, overflows == 1 ? "" : "s",
1798 floods, floods == 1 ? "" : "s");
1799 }
1800
1801 integrate void
1802 com_rxsoft(sc, tp)
1803 struct com_softc *sc;
1804 struct tty *tp;
1805 {
1806 int (*rint) __P((int c, struct tty *tp)) = tp->t_linesw->l_rint;
1807 u_char *get, *end;
1808 u_int cc, scc;
1809 u_char lsr;
1810 int code;
1811 int s;
1812
1813 end = sc->sc_ebuf;
1814 get = sc->sc_rbget;
1815 scc = cc = com_rbuf_size - sc->sc_rbavail;
1816
1817 if (cc == com_rbuf_size) {
1818 sc->sc_floods++;
1819 if (sc->sc_errors++ == 0)
1820 callout_reset(&sc->sc_diag_callout, 60 * hz,
1821 comdiag, sc);
1822 }
1823
1824 while (cc) {
1825 code = get[0];
1826 lsr = get[1];
1827 if (ISSET(lsr, LSR_OE | LSR_BI | LSR_FE | LSR_PE)) {
1828 if (ISSET(lsr, LSR_OE)) {
1829 sc->sc_overflows++;
1830 if (sc->sc_errors++ == 0)
1831 callout_reset(&sc->sc_diag_callout,
1832 60 * hz, comdiag, sc);
1833 }
1834 if (ISSET(lsr, LSR_BI | LSR_FE))
1835 SET(code, TTY_FE);
1836 if (ISSET(lsr, LSR_PE))
1837 SET(code, TTY_PE);
1838 }
1839 if ((*rint)(code, tp) == -1) {
1840 /*
1841 * The line discipline's buffer is out of space.
1842 */
1843 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1844 /*
1845 * We're either not using flow control, or the
1846 * line discipline didn't tell us to block for
1847 * some reason. Either way, we have no way to
1848 * know when there's more space available, so
1849 * just drop the rest of the data.
1850 */
1851 get += cc << 1;
1852 if (get >= end)
1853 get -= com_rbuf_size << 1;
1854 cc = 0;
1855 } else {
1856 /*
1857 * Don't schedule any more receive processing
1858 * until the line discipline tells us there's
1859 * space available (through comhwiflow()).
1860 * Leave the rest of the data in the input
1861 * buffer.
1862 */
1863 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1864 }
1865 break;
1866 }
1867 get += 2;
1868 if (get >= end)
1869 get = sc->sc_rbuf;
1870 cc--;
1871 }
1872
1873 if (cc != scc) {
1874 sc->sc_rbget = get;
1875 s = splserial();
1876 COM_LOCK(sc);
1877
1878 cc = sc->sc_rbavail += scc - cc;
1879 /* Buffers should be ok again, release possible block. */
1880 if (cc >= sc->sc_r_lowat) {
1881 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
1882 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
1883 SET(sc->sc_ier, IER_ERXRDY);
1884 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
1885 }
1886 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
1887 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
1888 com_hwiflow(sc);
1889 }
1890 }
1891 COM_UNLOCK(sc);
1892 splx(s);
1893 }
1894 }
1895
1896 integrate void
1897 com_txsoft(sc, tp)
1898 struct com_softc *sc;
1899 struct tty *tp;
1900 {
1901
1902 CLR(tp->t_state, TS_BUSY);
1903 if (ISSET(tp->t_state, TS_FLUSH))
1904 CLR(tp->t_state, TS_FLUSH);
1905 else
1906 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
1907 (*tp->t_linesw->l_start)(tp);
1908 }
1909
1910 integrate void
1911 com_stsoft(sc, tp)
1912 struct com_softc *sc;
1913 struct tty *tp;
1914 {
1915 u_char msr, delta;
1916 int s;
1917
1918 s = splserial();
1919 COM_LOCK(sc);
1920 msr = sc->sc_msr;
1921 delta = sc->sc_msr_delta;
1922 sc->sc_msr_delta = 0;
1923 COM_UNLOCK(sc);
1924 splx(s);
1925
1926 if (ISSET(delta, sc->sc_msr_dcd)) {
1927 /*
1928 * Inform the tty layer that carrier detect changed.
1929 */
1930 (void) (*tp->t_linesw->l_modem)(tp, ISSET(msr, MSR_DCD));
1931 }
1932
1933 if (ISSET(delta, sc->sc_msr_cts)) {
1934 /* Block or unblock output according to flow control. */
1935 if (ISSET(msr, sc->sc_msr_cts)) {
1936 sc->sc_tx_stopped = 0;
1937 (*tp->t_linesw->l_start)(tp);
1938 } else {
1939 sc->sc_tx_stopped = 1;
1940 }
1941 }
1942
1943 #ifdef COM_DEBUG
1944 if (com_debug)
1945 comstatus(sc, "com_stsoft");
1946 #endif
1947 }
1948
1949 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
1950 void
1951 comsoft(arg)
1952 void *arg;
1953 {
1954 struct com_softc *sc = arg;
1955 struct tty *tp;
1956
1957 if (COM_ISALIVE(sc) == 0)
1958 return;
1959
1960 {
1961 #else
1962 void
1963 #ifndef __NO_SOFT_SERIAL_INTERRUPT
1964 comsoft()
1965 #else
1966 comsoft(arg)
1967 void *arg;
1968 #endif
1969 {
1970 struct com_softc *sc;
1971 struct tty *tp;
1972 int unit;
1973 #ifdef __NO_SOFT_SERIAL_INTERRUPT
1974 int s;
1975
1976 s = splsoftserial();
1977 com_softintr_scheduled = 0;
1978 #endif
1979
1980 for (unit = 0; unit < com_cd.cd_ndevs; unit++) {
1981 sc = device_lookup(&com_cd, unit);
1982 if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK))
1983 continue;
1984
1985 if (COM_ISALIVE(sc) == 0)
1986 continue;
1987
1988 tp = sc->sc_tty;
1989 if (tp == NULL)
1990 continue;
1991 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0)
1992 continue;
1993 #endif
1994 tp = sc->sc_tty;
1995
1996 if (sc->sc_rx_ready) {
1997 sc->sc_rx_ready = 0;
1998 com_rxsoft(sc, tp);
1999 }
2000
2001 if (sc->sc_st_check) {
2002 sc->sc_st_check = 0;
2003 com_stsoft(sc, tp);
2004 }
2005
2006 if (sc->sc_tx_done) {
2007 sc->sc_tx_done = 0;
2008 com_txsoft(sc, tp);
2009 }
2010 }
2011
2012 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
2013 #ifdef __NO_SOFT_SERIAL_INTERRUPT
2014 splx(s);
2015 #endif
2016 #endif
2017 }
2018
2019 #ifdef __ALIGN_BRACKET_LEVEL_FOR_CTAGS
2020 /* there has got to be a better way to do comsoft() */
2021 }}
2022 #endif
2023
2024 int
2025 comintr(arg)
2026 void *arg;
2027 {
2028 struct com_softc *sc = arg;
2029 bus_space_tag_t iot = sc->sc_iot;
2030 bus_space_handle_t ioh = sc->sc_ioh;
2031 u_char *put, *end;
2032 u_int cc;
2033 u_char lsr, iir;
2034
2035 if (COM_ISALIVE(sc) == 0)
2036 return (0);
2037
2038 COM_LOCK(sc);
2039 iir = bus_space_read_1(iot, ioh, com_iir);
2040 if (ISSET(iir, IIR_NOPEND)) {
2041 COM_UNLOCK(sc);
2042 return (0);
2043 }
2044
2045 end = sc->sc_ebuf;
2046 put = sc->sc_rbput;
2047 cc = sc->sc_rbavail;
2048
2049 again: do {
2050 u_char msr, delta;
2051
2052 lsr = bus_space_read_1(iot, ioh, com_lsr);
2053 if (ISSET(lsr, LSR_BI)) {
2054 int cn_trapped = 0;
2055 cn_check_magic(sc->sc_tty->t_dev,
2056 CNC_BREAK, com_cnm_state);
2057 if (cn_trapped)
2058 continue;
2059 #if defined(KGDB)
2060 if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) {
2061 kgdb_connect(1);
2062 continue;
2063 }
2064 #endif
2065 }
2066
2067 if (ISSET(lsr, LSR_RCV_MASK) &&
2068 !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
2069 while (cc > 0) {
2070 int cn_trapped = 0;
2071 put[0] = bus_space_read_1(iot, ioh, com_data);
2072 put[1] = lsr;
2073 cn_check_magic(sc->sc_tty->t_dev,
2074 put[0], com_cnm_state);
2075 if (cn_trapped) {
2076 lsr = bus_space_read_1(iot, ioh, com_lsr);
2077 if (!ISSET(lsr, LSR_RCV_MASK))
2078 break;
2079
2080 continue;
2081 }
2082 put += 2;
2083 if (put >= end)
2084 put = sc->sc_rbuf;
2085 cc--;
2086
2087 lsr = bus_space_read_1(iot, ioh, com_lsr);
2088 if (!ISSET(lsr, LSR_RCV_MASK))
2089 break;
2090 }
2091
2092 /*
2093 * Current string of incoming characters ended because
2094 * no more data was available or we ran out of space.
2095 * Schedule a receive event if any data was received.
2096 * If we're out of space, turn off receive interrupts.
2097 */
2098 sc->sc_rbput = put;
2099 sc->sc_rbavail = cc;
2100 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
2101 sc->sc_rx_ready = 1;
2102
2103 /*
2104 * See if we are in danger of overflowing a buffer. If
2105 * so, use hardware flow control to ease the pressure.
2106 */
2107 if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) &&
2108 cc < sc->sc_r_hiwat) {
2109 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
2110 com_hwiflow(sc);
2111 }
2112
2113 /*
2114 * If we're out of space, disable receive interrupts
2115 * until the queue has drained a bit.
2116 */
2117 if (!cc) {
2118 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
2119 CLR(sc->sc_ier, IER_ERXRDY);
2120 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
2121 }
2122 } else {
2123 if ((iir & IIR_IMASK) == IIR_RXRDY) {
2124 bus_space_write_1(iot, ioh, com_ier, 0);
2125 delay(10);
2126 bus_space_write_1(iot, ioh, com_ier,sc->sc_ier);
2127 continue;
2128 }
2129 }
2130
2131 msr = bus_space_read_1(iot, ioh, com_msr);
2132 delta = msr ^ sc->sc_msr;
2133 sc->sc_msr = msr;
2134 /*
2135 * Pulse-per-second (PSS) signals on edge of DCD?
2136 * Process these even if line discipline is ignoring DCD.
2137 */
2138 if (delta & sc->sc_ppsmask) {
2139 struct timeval tv;
2140 if ((msr & sc->sc_ppsmask) == sc->sc_ppsassert) {
2141 /* XXX nanotime() */
2142 microtime(&tv);
2143 TIMEVAL_TO_TIMESPEC(&tv,
2144 &sc->ppsinfo.assert_timestamp);
2145 if (sc->ppsparam.mode & PPS_OFFSETASSERT) {
2146 timespecadd(&sc->ppsinfo.assert_timestamp,
2147 &sc->ppsparam.assert_offset,
2148 &sc->ppsinfo.assert_timestamp);
2149 }
2150
2151 #ifdef PPS_SYNC
2152 if (sc->ppsparam.mode & PPS_HARDPPSONASSERT)
2153 hardpps(&tv, tv.tv_usec);
2154 #endif
2155 sc->ppsinfo.assert_sequence++;
2156 sc->ppsinfo.current_mode = sc->ppsparam.mode;
2157
2158 } else if ((msr & sc->sc_ppsmask) == sc->sc_ppsclear) {
2159 /* XXX nanotime() */
2160 microtime(&tv);
2161 TIMEVAL_TO_TIMESPEC(&tv,
2162 &sc->ppsinfo.clear_timestamp);
2163 if (sc->ppsparam.mode & PPS_OFFSETCLEAR) {
2164 timespecadd(&sc->ppsinfo.clear_timestamp,
2165 &sc->ppsparam.clear_offset,
2166 &sc->ppsinfo.clear_timestamp);
2167 }
2168
2169 #ifdef PPS_SYNC
2170 if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR)
2171 hardpps(&tv, tv.tv_usec);
2172 #endif
2173 sc->ppsinfo.clear_sequence++;
2174 sc->ppsinfo.current_mode = sc->ppsparam.mode;
2175 }
2176 }
2177
2178 /*
2179 * Process normal status changes
2180 */
2181 if (ISSET(delta, sc->sc_msr_mask)) {
2182 SET(sc->sc_msr_delta, delta);
2183
2184 /*
2185 * Stop output immediately if we lose the output
2186 * flow control signal or carrier detect.
2187 */
2188 if (ISSET(~msr, sc->sc_msr_mask)) {
2189 sc->sc_tbc = 0;
2190 sc->sc_heldtbc = 0;
2191 #ifdef COM_DEBUG
2192 if (com_debug)
2193 comstatus(sc, "comintr ");
2194 #endif
2195 }
2196
2197 sc->sc_st_check = 1;
2198 }
2199 } while (ISSET((iir = bus_space_read_1(iot, ioh, com_iir)), IIR_RXRDY)
2200 || ((iir & IIR_IMASK) == 0));
2201
2202 /*
2203 * Done handling any receive interrupts. See if data can be
2204 * transmitted as well. Schedule tx done event if no data left
2205 * and tty was marked busy.
2206 */
2207 if (ISSET(lsr, LSR_TXRDY)) {
2208 /*
2209 * If we've delayed a parameter change, do it now, and restart
2210 * output.
2211 */
2212 if (sc->sc_heldchange) {
2213 com_loadchannelregs(sc);
2214 sc->sc_heldchange = 0;
2215 sc->sc_tbc = sc->sc_heldtbc;
2216 sc->sc_heldtbc = 0;
2217 }
2218
2219 /* Output the next chunk of the contiguous buffer, if any. */
2220 if (sc->sc_tbc > 0) {
2221 int n;
2222
2223 n = sc->sc_tbc;
2224 if (n > sc->sc_fifolen)
2225 n = sc->sc_fifolen;
2226 bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n);
2227 sc->sc_tbc -= n;
2228 sc->sc_tba += n;
2229 } else {
2230 /* Disable transmit completion interrupts if necessary. */
2231 if (ISSET(sc->sc_ier, IER_ETXRDY)) {
2232 CLR(sc->sc_ier, IER_ETXRDY);
2233 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
2234 }
2235 if (sc->sc_tx_busy) {
2236 sc->sc_tx_busy = 0;
2237 sc->sc_tx_done = 1;
2238 }
2239 }
2240 }
2241
2242 if (!ISSET((iir = bus_space_read_1(iot, ioh, com_iir)), IIR_NOPEND))
2243 goto again;
2244
2245 COM_UNLOCK(sc);
2246
2247 /* Wake up the poller. */
2248 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
2249 softintr_schedule(sc->sc_si);
2250 #else
2251 #ifndef __NO_SOFT_SERIAL_INTERRUPT
2252 setsoftserial();
2253 #else
2254 if (!com_softintr_scheduled) {
2255 com_softintr_scheduled = 1;
2256 callout_reset(&comsoft_callout, 1, comsoft, NULL);
2257 }
2258 #endif
2259 #endif
2260
2261 #if NRND > 0 && defined(RND_COM)
2262 rnd_add_uint32(&sc->rnd_source, iir | lsr);
2263 #endif
2264
2265 return (1);
2266 }
2267
2268 /*
2269 * The following functions are polled getc and putc routines, shared
2270 * by the console and kgdb glue.
2271 *
2272 * The read-ahead code is so that you can detect pending in-band
2273 * cn_magic in polled mode while doing output rather than having to
2274 * wait until the kernel decides it needs input.
2275 */
2276
2277 #define MAX_READAHEAD 20
2278 static int com_readahead[MAX_READAHEAD];
2279 static int com_readaheadcount = 0;
2280
2281 int
2282 com_common_getc(dev, iot, ioh)
2283 dev_t dev;
2284 bus_space_tag_t iot;
2285 bus_space_handle_t ioh;
2286 {
2287 int s = splserial();
2288 u_char stat, c;
2289
2290 /* got a character from reading things earlier */
2291 if (com_readaheadcount > 0) {
2292 int i;
2293
2294 c = com_readahead[0];
2295 for (i = 1; i < com_readaheadcount; i++) {
2296 com_readahead[i-1] = com_readahead[i];
2297 }
2298 com_readaheadcount--;
2299 splx(s);
2300 return (c);
2301 }
2302
2303 /* block until a character becomes available */
2304 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
2305 ;
2306
2307 c = bus_space_read_1(iot, ioh, com_data);
2308 stat = bus_space_read_1(iot, ioh, com_iir);
2309 {
2310 int cn_trapped = 0; /* unused */
2311 #ifdef DDB
2312 extern int db_active;
2313 if (!db_active)
2314 #endif
2315 cn_check_magic(dev, c, com_cnm_state);
2316 }
2317 splx(s);
2318 return (c);
2319 }
2320
2321 void
2322 com_common_putc(dev, iot, ioh, c)
2323 dev_t dev;
2324 bus_space_tag_t iot;
2325 bus_space_handle_t ioh;
2326 int c;
2327 {
2328 int s = splserial();
2329 int timo;
2330
2331 int cin, stat;
2332 if (com_readaheadcount < MAX_READAHEAD
2333 && ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)) {
2334 int cn_trapped = 0;
2335 cin = bus_space_read_1(iot, ioh, com_data);
2336 stat = bus_space_read_1(iot, ioh, com_iir);
2337 cn_check_magic(dev, cin, com_cnm_state);
2338 com_readahead[com_readaheadcount++] = cin;
2339 }
2340
2341 /* wait for any pending transmission to finish */
2342 timo = 150000;
2343 while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
2344 continue;
2345
2346 bus_space_write_1(iot, ioh, com_data, c);
2347 COM_BARRIER(iot, ioh, BR | BW);
2348
2349 /* wait for this transmission to complete */
2350 timo = 1500000;
2351 while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
2352 continue;
2353
2354 splx(s);
2355 }
2356
2357 /*
2358 * Initialize UART for use as console or KGDB line.
2359 */
2360 int
2361 cominit(iot, iobase, rate, frequency, cflag, iohp)
2362 bus_space_tag_t iot;
2363 bus_addr_t iobase;
2364 int rate, frequency;
2365 tcflag_t cflag;
2366 bus_space_handle_t *iohp;
2367 {
2368 bus_space_handle_t ioh;
2369
2370 if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh))
2371 return (ENOMEM); /* ??? */
2372
2373 bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
2374 bus_space_write_1(iot, ioh, com_efr, 0);
2375 bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);
2376 rate = comspeed(rate, frequency);
2377 bus_space_write_1(iot, ioh, com_dlbl, rate);
2378 bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
2379 bus_space_write_1(iot, ioh, com_lcr, cflag2lcr(cflag));
2380 bus_space_write_1(iot, ioh, com_mcr, MCR_DTR | MCR_RTS);
2381 bus_space_write_1(iot, ioh, com_fifo,
2382 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
2383 bus_space_write_1(iot, ioh, com_ier, 0);
2384
2385 *iohp = ioh;
2386 return (0);
2387 }
2388
2389 /*
2390 * Following are all routines needed for COM to act as console
2391 */
2392 struct consdev comcons = {
2393 NULL, NULL, comcngetc, comcnputc, comcnpollc, NULL,
2394 NODEV, CN_NORMAL
2395 };
2396
2397
2398 int
2399 comcnattach(iot, iobase, rate, frequency, cflag)
2400 bus_space_tag_t iot;
2401 bus_addr_t iobase;
2402 int rate, frequency;
2403 tcflag_t cflag;
2404 {
2405 int res;
2406
2407 res = cominit(iot, iobase, rate, frequency, cflag, &comconsioh);
2408 if (res)
2409 return (res);
2410
2411 cn_tab = &comcons;
2412 cn_init_magic(&com_cnm_state);
2413 cn_set_magic("\047\001"); /* default magic is BREAK */
2414
2415 comconstag = iot;
2416 comconsaddr = iobase;
2417 comconsrate = rate;
2418 comconscflag = cflag;
2419
2420 return (0);
2421 }
2422
2423 int
2424 comcngetc(dev)
2425 dev_t dev;
2426 {
2427 return (com_common_getc(dev, comconstag, comconsioh));
2428 }
2429
2430 /*
2431 * Console kernel output character routine.
2432 */
2433 void
2434 comcnputc(dev, c)
2435 dev_t dev;
2436 int c;
2437 {
2438 com_common_putc(dev, comconstag, comconsioh, c);
2439 }
2440
2441 void
2442 comcnpollc(dev, on)
2443 dev_t dev;
2444 int on;
2445 {
2446
2447 }
2448
2449 #ifdef KGDB
2450 int
2451 com_kgdb_attach(iot, iobase, rate, frequency, cflag)
2452 bus_space_tag_t iot;
2453 bus_addr_t iobase;
2454 int rate, frequency;
2455 tcflag_t cflag;
2456 {
2457 int res;
2458
2459 if (iot == comconstag && iobase == comconsaddr)
2460 return (EBUSY); /* cannot share with console */
2461
2462 res = cominit(iot, iobase, rate, frequency, cflag, &com_kgdb_ioh);
2463 if (res)
2464 return (res);
2465
2466 /*
2467 * XXXfvdl this shouldn't be needed, but the cn_magic goo
2468 * expects this to be initialized
2469 */
2470 cn_init_magic(&com_cnm_state);
2471 cn_set_magic("\047\001");
2472
2473 kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL);
2474 kgdb_dev = 123; /* unneeded, only to satisfy some tests */
2475
2476 com_kgdb_iot = iot;
2477 com_kgdb_addr = iobase;
2478
2479 return (0);
2480 }
2481
2482 /* ARGSUSED */
2483 int
2484 com_kgdb_getc(arg)
2485 void *arg;
2486 {
2487 return (com_common_getc(NODEV, com_kgdb_iot, com_kgdb_ioh));
2488 }
2489
2490 /* ARGSUSED */
2491 void
2492 com_kgdb_putc(arg, c)
2493 void *arg;
2494 int c;
2495 {
2496 com_common_putc(NODEV, com_kgdb_iot, com_kgdb_ioh, c);
2497 }
2498 #endif /* KGDB */
2499
2500 /* helper function to identify the com ports used by
2501 console or KGDB (and not yet autoconf attached) */
2502 int
2503 com_is_console(iot, iobase, ioh)
2504 bus_space_tag_t iot;
2505 bus_addr_t iobase;
2506 bus_space_handle_t *ioh;
2507 {
2508 bus_space_handle_t help;
2509
2510 if (!comconsattached &&
2511 iot == comconstag && iobase == comconsaddr)
2512 help = comconsioh;
2513 #ifdef KGDB
2514 else if (!com_kgdb_attached &&
2515 iot == com_kgdb_iot && iobase == com_kgdb_addr)
2516 help = com_kgdb_ioh;
2517 #endif
2518 else
2519 return (0);
2520
2521 if (ioh)
2522 *ioh = help;
2523 return (1);
2524 }
2525