xref: /openbsd/sys/dev/ic/com.c (revision db3296cf)
1 /*	$OpenBSD: com.c,v 1.91 2003/07/15 03:15:58 jason Exp $	*/
2 /*	$NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $	*/
3 
4 /*
5  * Copyright (c) 1997 - 1999, Jason Downs.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 /*-
29  * Copyright (c) 1993, 1994, 1995, 1996
30  *	Charles M. Hannum.  All rights reserved.
31  * Copyright (c) 1991 The Regents of the University of California.
32  * All rights reserved.
33  *
34  * Redistribution and use in source and binary forms, with or without
35  * modification, are permitted provided that the following conditions
36  * are met:
37  * 1. Redistributions of source code must retain the above copyright
38  *    notice, this list of conditions and the following disclaimer.
39  * 2. Redistributions in binary form must reproduce the above copyright
40  *    notice, this list of conditions and the following disclaimer in the
41  *    documentation and/or other materials provided with the distribution.
42  * 3. Neither the name of the University nor the names of its contributors
43  *    may be used to endorse or promote products derived from this software
44  *    without specific prior written permission.
45  *
46  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56  * SUCH DAMAGE.
57  *
58  *	@(#)com.c	7.5 (Berkeley) 5/16/91
59  */
60 
61 /*
62  * COM driver, based on HP dca driver
63  * uses National Semiconductor NS16450/NS16550AF UART
64  */
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/ioctl.h>
68 #include <sys/select.h>
69 #include <sys/tty.h>
70 #include <sys/proc.h>
71 #include <sys/user.h>
72 #include <sys/conf.h>
73 #include <sys/file.h>
74 #include <sys/uio.h>
75 #include <sys/kernel.h>
76 #include <sys/syslog.h>
77 #include <sys/types.h>
78 #include <sys/device.h>
79 #include <sys/vnode.h>
80 #ifdef DDB
81 #include <ddb/db_var.h>
82 #endif
83 
84 #include <machine/bus.h>
85 #include <machine/intr.h>
86 
87 #include <dev/cons.h>
88 
89 #include <dev/ic/comreg.h>
90 #include <dev/ic/comvar.h>
91 #include <dev/ic/ns16550reg.h>
92 #define	com_lcr	com_cfcr
93 
94 #include "com.h"
95 
96 /* XXX: These belong elsewhere */
97 cdev_decl(com);
98 
99 static u_char tiocm_xxx2mcr(int);
100 
101 void	compwroff(struct com_softc *);
102 void	com_enable_debugport(struct com_softc *);
103 
104 struct cfdriver com_cd = {
105 	NULL, "com", DV_TTY
106 };
107 
108 int	comdefaultrate = TTYDEF_SPEED;
109 int	comconsinit;
110 int	comconsaddr;
111 int	comconsattached;
112 bus_space_tag_t comconsiot;
113 bus_space_handle_t comconsioh;
114 tcflag_t comconscflag = TTYDEF_CFLAG;
115 
116 int	commajor;
117 
118 #ifdef KGDB
119 #include <sys/kgdb.h>
120 
121 int com_kgdb_addr;
122 bus_space_tag_t com_kgdb_iot;
123 bus_space_handle_t com_kgdb_ioh;
124 
125 int    com_kgdb_getc(void *);
126 void   com_kgdb_putc(void *, int);
127 #endif /* KGDB */
128 
129 #define	DEVUNIT(x)	(minor(x) & 0x7f)
130 #define	DEVCUA(x)	(minor(x) & 0x80)
131 
132 int
133 comspeed(freq, speed)
134 	long freq;
135 	long speed;
136 {
137 #define	divrnd(n, q)	(((n)*2/(q)+1)/2)	/* divide and round off */
138 
139 	int x, err;
140 
141 	if (speed == 0)
142 		return 0;
143 	if (speed < 0)
144 		return -1;
145 	x = divrnd((freq / 16), speed);
146 	if (x <= 0)
147 		return -1;
148 	err = divrnd((freq / 16) * 1000, speed * x) - 1000;
149 	if (err < 0)
150 		err = -err;
151 	if (err > COM_TOLERANCE)
152 		return -1;
153 	return x;
154 
155 #undef	divrnd
156 }
157 
158 int
159 comprobe1(iot, ioh)
160 	bus_space_tag_t iot;
161 	bus_space_handle_t ioh;
162 {
163 	int i, k;
164 
165 	/* force access to id reg */
166 	bus_space_write_1(iot, ioh, com_lcr, 0);
167 	bus_space_write_1(iot, ioh, com_iir, 0);
168 	for (i = 0; i < 32; i++) {
169 		k = bus_space_read_1(iot, ioh, com_iir);
170 		if (k & 0x38) {
171 			bus_space_read_1(iot, ioh, com_data); /* cleanup */
172 		} else
173 			break;
174 	}
175 	if (i >= 32)
176 		return 0;
177 
178 	return 1;
179 }
180 
181 void
182 com_attach_subr(sc)
183 	struct com_softc *sc;
184 {
185 	bus_space_tag_t iot = sc->sc_iot;
186 	bus_space_handle_t ioh = sc->sc_ioh;
187 	u_int8_t lcr;
188 
189 	sc->sc_ier = 0;
190 	/* disable interrupts */
191 	bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
192 
193 	if (sc->sc_iobase == comconsaddr) {
194 		comconsattached = 1;
195 
196 		/*
197 		 * Need to reset baud rate, etc. of next print so reset
198 		 * comconsinit.  Also make sure console is always "hardwired".
199 		 */
200 		delay(10000);			/* wait for output to finish */
201 		SET(sc->sc_hwflags, COM_HW_CONSOLE);
202 		SET(sc->sc_swflags, COM_SW_SOFTCAR);
203 	}
204 
205 	/*
206 	 * Probe for all known forms of UART.
207 	 */
208 	lcr = bus_space_read_1(iot, ioh, com_lcr);
209 	bus_space_write_1(iot, ioh, com_lcr, 0xbf);
210 	bus_space_write_1(iot, ioh, com_efr, 0);
211 	bus_space_write_1(iot, ioh, com_lcr, 0);
212 
213 	bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
214 	delay(100);
215 
216 	switch(bus_space_read_1(iot, ioh, com_iir) >> 6) {
217 	case 0:
218 		sc->sc_uarttype = COM_UART_16450;
219 		break;
220 	case 2:
221 		sc->sc_uarttype = COM_UART_16550;
222 		break;
223 	case 3:
224 		sc->sc_uarttype = COM_UART_16550A;
225 		break;
226 	default:
227 		sc->sc_uarttype = COM_UART_UNKNOWN;
228 		break;
229 	}
230 
231 	if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */
232 		bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
233 		if (bus_space_read_1(iot, ioh, com_efr) == 0) {
234 			sc->sc_uarttype = COM_UART_ST16650;
235 		} else {
236 			bus_space_write_1(iot, ioh, com_lcr, 0xbf);
237 			if (bus_space_read_1(iot, ioh, com_efr) == 0)
238 				sc->sc_uarttype = COM_UART_ST16650V2;
239 		}
240 	}
241 
242 	if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for TI16750s */
243 		bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
244 		bus_space_write_1(iot, ioh, com_fifo,
245 		    FIFO_ENABLE | FIFO_ENABLE_64BYTE);
246 		if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 7) {
247 #if 0
248 			bus_space_write_1(iot, ioh, com_lcr, 0);
249 			if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 6)
250 #endif
251 				sc->sc_uarttype = COM_UART_TI16750;
252 		}
253 		bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
254 	}
255 	bus_space_write_1(iot, ioh, com_lcr, lcr);
256 	if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */
257 		u_int8_t scr0, scr1, scr2;
258 
259 		scr0 = bus_space_read_1(iot, ioh, com_scratch);
260 		bus_space_write_1(iot, ioh, com_scratch, 0xa5);
261 		scr1 = bus_space_read_1(iot, ioh, com_scratch);
262 		bus_space_write_1(iot, ioh, com_scratch, 0x5a);
263 		scr2 = bus_space_read_1(iot, ioh, com_scratch);
264 		bus_space_write_1(iot, ioh, com_scratch, scr0);
265 
266 		if ((scr1 != 0xa5) || (scr2 != 0x5a))
267 			sc->sc_uarttype = COM_UART_8250;
268 	}
269 
270 	/*
271 	 * Print UART type and initialize ourself.
272 	 */
273 	sc->sc_fifolen = 1;	/* default */
274 	switch (sc->sc_uarttype) {
275 	case COM_UART_UNKNOWN:
276 		printf(": unknown uart\n");
277 		break;
278 	case COM_UART_8250:
279 		printf(": ns8250, no fifo\n");
280 		break;
281 	case COM_UART_16450:
282 		printf(": ns16450, no fifo\n");
283 		break;
284 	case COM_UART_16550:
285 		printf(": ns16550, no working fifo\n");
286 		break;
287 	case COM_UART_16550A:
288 		printf(": ns16550a, 16 byte fifo\n");
289 		SET(sc->sc_hwflags, COM_HW_FIFO);
290 		sc->sc_fifolen = 16;
291 		break;
292 	case COM_UART_ST16650:
293 		printf(": st16650, no working fifo\n");
294 		break;
295 	case COM_UART_ST16650V2:
296 		printf(": st16650, 32 byte fifo\n");
297 		SET(sc->sc_hwflags, COM_HW_FIFO);
298 		sc->sc_fifolen = 32;
299 		break;
300 	case COM_UART_TI16750:
301 		printf(": ti16750, 64 byte fifo\n");
302 		SET(sc->sc_hwflags, COM_HW_FIFO);
303 		sc->sc_fifolen = 64;
304 		break;
305 	default:
306 		panic("comattach: bad fifo type");
307 	}
308 
309 	/* clear and disable fifo */
310 	bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST);
311 	(void)bus_space_read_1(iot, ioh, com_data);
312 	bus_space_write_1(iot, ioh, com_fifo, 0);
313 
314 	sc->sc_mcr = 0;
315 	bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
316 
317 #ifdef KGDB
318 	/*
319 	 * Allow kgdb to "take over" this port.  If this is
320 	 * the kgdb device, it has exclusive use.
321 	 */
322 
323 	if (iot == com_kgdb_iot && sc->sc_iobase == com_kgdb_addr &&
324 	    !ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
325 		printf("%s: kgdb\n", sc->sc_dev.dv_xname);
326 		SET(sc->sc_hwflags, COM_HW_KGDB);
327 	}
328 #endif /* KGDB */
329 
330 	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
331 		int maj;
332 
333 		/* locate the major number */
334 		for (maj = 0; maj < nchrdev; maj++)
335 			if (cdevsw[maj].d_open == comopen)
336 				break;
337 
338 		if (maj < nchrdev && cn_tab->cn_dev == NODEV)
339 			cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
340 
341 		printf("%s: console\n", sc->sc_dev.dv_xname);
342 	}
343 
344 	timeout_set(&sc->sc_diag_tmo, comdiag, sc);
345 	timeout_set(&sc->sc_dtr_tmo, com_raisedtr, sc);
346 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
347 	sc->sc_si = softintr_establish(IPL_TTY, compoll, sc);
348 	if (sc->sc_si == NULL)
349 		panic("%s: can't establish soft interrupt.", sc->sc_dev.dv_xname);
350 #else
351 	timeout_set(&sc->sc_poll_tmo, compoll, sc);
352 #endif
353 
354 	/*
355 	 * If there are no enable/disable functions, assume the device
356 	 * is always enabled.
357 	 */
358 	if (!sc->enable)
359 		sc->enabled = 1;
360 
361 	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE|COM_HW_KGDB))
362 		com_enable_debugport(sc);
363 }
364 
365 void
366 com_enable_debugport(sc)
367 	struct com_softc *sc;
368 {
369 	int s;
370 
371 	/* Turn on line break interrupt, set carrier. */
372 	s = splhigh();
373 #ifdef KGDB
374 	SET(sc->sc_ier, IER_ERXRDY);
375 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
376 #endif
377 	SET(sc->sc_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE);
378 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
379 
380 	splx(s);
381 }
382 
383 int
384 com_detach(self, flags)
385 	struct device *self;
386 	int flags;
387 {
388 	struct com_softc *sc = (struct com_softc *)self;
389 	int maj, mn;
390 
391 	/* locate the major number */
392 	for (maj = 0; maj < nchrdev; maj++)
393 		if (cdevsw[maj].d_open == comopen)
394 			break;
395 
396 	/* Nuke the vnodes for any open instances. */
397 	mn = self->dv_unit;
398 	vdevgone(maj, mn, mn, VCHR);
399 
400 	/* XXX a symbolic constant for the cua bit would be nicer. */
401 	mn |= 0x80;
402 	vdevgone(maj, mn, mn, VCHR);
403 
404 	/* Detach and free the tty. */
405 	if (sc->sc_tty) {
406 		tty_detach(sc->sc_tty);
407 		ttyfree(sc->sc_tty);
408 	}
409 
410 	timeout_del(&sc->sc_dtr_tmo);
411 	timeout_del(&sc->sc_diag_tmo);
412 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
413 	softintr_disestablish(sc->sc_si);
414 #else
415 	timeout_del(&sc->sc_poll_tmo);
416 #endif
417 
418 	return (0);
419 }
420 
421 int
422 com_activate(self, act)
423 	struct device *self;
424 	enum devact act;
425 {
426 	struct com_softc *sc = (struct com_softc *)self;
427 	int s, rv = 0;
428 
429 	s = spltty();
430 	switch (act) {
431 	case DVACT_ACTIVATE:
432 		rv = EOPNOTSUPP;
433 		break;
434 
435 	case DVACT_DEACTIVATE:
436 #ifdef KGDB
437 		if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) {
438 #else
439 		if (sc->sc_hwflags & COM_HW_CONSOLE) {
440 #endif /* KGDB */
441 			rv = EBUSY;
442 			break;
443 		}
444 
445 		if (sc->disable != NULL && sc->enabled != 0) {
446 			(*sc->disable)(sc);
447 			sc->enabled = 0;
448 		}
449 		break;
450 	}
451 	splx(s);
452 	return (rv);
453 }
454 
455 int
456 comopen(dev, flag, mode, p)
457 	dev_t dev;
458 	int flag, mode;
459 	struct proc *p;
460 {
461 	int unit = DEVUNIT(dev);
462 	struct com_softc *sc;
463 	bus_space_tag_t iot;
464 	bus_space_handle_t ioh;
465 	struct tty *tp;
466 	int s;
467 	int error = 0;
468 
469 	if (unit >= com_cd.cd_ndevs)
470 		return ENXIO;
471 	sc = com_cd.cd_devs[unit];
472 	if (!sc)
473 		return ENXIO;
474 
475 #ifdef KGDB
476 	/*
477 	 * If this is the kgdb port, no other use is permitted.
478 	 */
479 	if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
480 		return (EBUSY);
481 #endif /* KGDB */
482 
483 	s = spltty();
484 	if (!sc->sc_tty) {
485 		tp = sc->sc_tty = ttymalloc();
486 		tty_attach(tp);
487 	} else
488 		tp = sc->sc_tty;
489 	splx(s);
490 
491 	tp->t_oproc = comstart;
492 	tp->t_param = comparam;
493 	tp->t_dev = dev;
494 	if (!ISSET(tp->t_state, TS_ISOPEN)) {
495 		SET(tp->t_state, TS_WOPEN);
496 		ttychars(tp);
497 		tp->t_iflag = TTYDEF_IFLAG;
498 		tp->t_oflag = TTYDEF_OFLAG;
499 		if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
500 			tp->t_cflag = comconscflag;
501 		else
502 			tp->t_cflag = TTYDEF_CFLAG;
503 		if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
504 			SET(tp->t_cflag, CLOCAL);
505 		if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
506 			SET(tp->t_cflag, CRTSCTS);
507 		if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
508 			SET(tp->t_cflag, MDMBUF);
509 		tp->t_lflag = TTYDEF_LFLAG;
510 		tp->t_ispeed = tp->t_ospeed = comdefaultrate;
511 
512 		s = spltty();
513 
514 		sc->sc_initialize = 1;
515 		comparam(tp, &tp->t_termios);
516 		ttsetwater(tp);
517 
518 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
519 		timeout_add(&sc->sc_poll_tmo, 1);
520 #endif
521 
522 		sc->sc_ibufp = sc->sc_ibuf = sc->sc_ibufs[0];
523 		sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER;
524 		sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;
525 
526 		iot = sc->sc_iot;
527 		ioh = sc->sc_ioh;
528 
529 		/*
530 		 * Wake up the sleepy heads.
531 		 */
532 		switch (sc->sc_uarttype) {
533 		case COM_UART_ST16650:
534 		case COM_UART_ST16650V2:
535 			bus_space_write_1(iot, ioh, com_lcr, 0xbf);
536 			bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
537 			bus_space_write_1(iot, ioh, com_ier, 0);
538 			bus_space_write_1(iot, ioh, com_efr, 0);
539 			bus_space_write_1(iot, ioh, com_lcr, 0);
540 			break;
541 		case COM_UART_TI16750:
542 			bus_space_write_1(iot, ioh, com_ier, 0);
543 			break;
544 		}
545 
546 		if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
547 			u_int8_t fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST;
548 			u_int8_t lcr;
549 
550 			if (tp->t_ispeed <= 1200)
551 				fifo |= FIFO_TRIGGER_1;
552 			else
553 				fifo |= FIFO_TRIGGER_8;
554 			if (sc->sc_uarttype == COM_UART_TI16750) {
555 				fifo |= FIFO_ENABLE_64BYTE;
556 				lcr = bus_space_read_1(iot, ioh, com_lcr);
557 				bus_space_write_1(iot, ioh, com_lcr,
558 				    lcr | LCR_DLAB);
559 			}
560 
561 			/*
562 			 * (Re)enable and drain FIFOs.
563 			 *
564 			 * Certain SMC chips cause problems if the FIFOs are
565 			 * enabled while input is ready. Turn off the FIFO
566 			 * if necessary to clear the input. Test the input
567 			 * ready bit after enabling the FIFOs to handle races
568 			 * between enabling and fresh input.
569 			 *
570 			 * Set the FIFO threshold based on the receive speed.
571 			 */
572 			for (;;) {
573 				bus_space_write_1(iot, ioh, com_fifo, 0);
574 				delay(100);
575 				(void) bus_space_read_1(iot, ioh, com_data);
576 				bus_space_write_1(iot, ioh, com_fifo, fifo |
577 				    FIFO_RCV_RST | FIFO_XMT_RST);
578 				delay(100);
579 				if(!ISSET(bus_space_read_1(iot, ioh,
580 				    com_lsr), LSR_RXRDY))
581 					break;
582 			}
583 			if (sc->sc_uarttype == COM_UART_TI16750)
584 				bus_space_write_1(iot, ioh, com_lcr, lcr);
585 		}
586 
587 		/* flush any pending I/O */
588 		while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
589 			(void) bus_space_read_1(iot, ioh, com_data);
590 		/* you turn me on, baby */
591 		sc->sc_mcr = MCR_DTR | MCR_RTS;
592 		if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
593 			SET(sc->sc_mcr, MCR_IENABLE);
594 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
595 		sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
596 		bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
597 
598 		sc->sc_msr = bus_space_read_1(iot, ioh, com_msr);
599 		if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || DEVCUA(dev) ||
600 		    ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF))
601 			SET(tp->t_state, TS_CARR_ON);
602 		else
603 			CLR(tp->t_state, TS_CARR_ON);
604 	} else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0)
605 		return EBUSY;
606 	else
607 		s = spltty();
608 
609 	if (DEVCUA(dev)) {
610 		if (ISSET(tp->t_state, TS_ISOPEN)) {
611 			/* Ah, but someone already is dialed in... */
612 			splx(s);
613 			return EBUSY;
614 		}
615 		sc->sc_cua = 1;		/* We go into CUA mode */
616 	} else {
617 		/* tty (not cua) device; wait for carrier if necessary */
618 		if (ISSET(flag, O_NONBLOCK)) {
619 			if (sc->sc_cua) {
620 				/* Opening TTY non-blocking... but the CUA is busy */
621 				splx(s);
622 				return EBUSY;
623 			}
624 		} else {
625 			while (sc->sc_cua ||
626 			    (!ISSET(tp->t_cflag, CLOCAL) &&
627 				!ISSET(tp->t_state, TS_CARR_ON))) {
628 				SET(tp->t_state, TS_WOPEN);
629 				error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
630 				/*
631 				 * If TS_WOPEN has been reset, that means the cua device
632 				 * has been closed.  We don't want to fail in that case,
633 				 * so just go around again.
634 				 */
635 				if (error && ISSET(tp->t_state, TS_WOPEN)) {
636 					CLR(tp->t_state, TS_WOPEN);
637 					if (!sc->sc_cua && !ISSET(tp->t_state, TS_ISOPEN))
638 						compwroff(sc);
639 					splx(s);
640 					return error;
641 				}
642 			}
643 		}
644 	}
645 	splx(s);
646 
647 	return (*linesw[tp->t_line].l_open)(dev, tp);
648 }
649 
650 int
651 comclose(dev, flag, mode, p)
652 	dev_t dev;
653 	int flag, mode;
654 	struct proc *p;
655 {
656 	int unit = DEVUNIT(dev);
657 	struct com_softc *sc = com_cd.cd_devs[unit];
658 	bus_space_tag_t iot = sc->sc_iot;
659 	bus_space_handle_t ioh = sc->sc_ioh;
660 	struct tty *tp = sc->sc_tty;
661 	int s;
662 
663 	/* XXX This is for cons.c. */
664 	if (!ISSET(tp->t_state, TS_ISOPEN))
665 		return 0;
666 
667 	(*linesw[tp->t_line].l_close)(tp, flag);
668 	s = spltty();
669 	if (ISSET(tp->t_state, TS_WOPEN)) {
670 		/* tty device is waiting for carrier; drop dtr then re-raise */
671 		CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
672 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
673 		timeout_add(&sc->sc_dtr_tmo, hz * 2);
674 	} else {
675 		/* no one else waiting; turn off the uart */
676 		compwroff(sc);
677 	}
678 	CLR(tp->t_state, TS_BUSY | TS_FLUSH);
679 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
680 	timeout_del(&sc->sc_poll_tmo);
681 #endif
682 	sc->sc_cua = 0;
683 	splx(s);
684 	ttyclose(tp);
685 
686 #ifdef notyet /* XXXX */
687 	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
688 		ttyfree(tp);
689 		sc->sc_tty = 0;
690 	}
691 #endif
692 	return 0;
693 }
694 
695 void
696 compwroff(sc)
697 	struct com_softc *sc;
698 {
699 	bus_space_tag_t iot = sc->sc_iot;
700 	bus_space_handle_t ioh = sc->sc_ioh;
701 	struct tty *tp = sc->sc_tty;
702 
703 	CLR(sc->sc_lcr, LCR_SBREAK);
704 	bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
705 	bus_space_write_1(iot, ioh, com_ier, 0);
706 	if (ISSET(tp->t_cflag, HUPCL) &&
707 	    !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
708 		/* XXX perhaps only clear DTR */
709 		sc->sc_mcr = 0;
710 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
711 	}
712 
713 	/*
714 	 * Turn FIFO off; enter sleep mode if possible.
715 	 */
716 	bus_space_write_1(iot, ioh, com_fifo, 0);
717 	delay(100);
718 	(void) bus_space_read_1(iot, ioh, com_data);
719 	delay(100);
720 	bus_space_write_1(iot, ioh, com_fifo,
721 			  FIFO_RCV_RST | FIFO_XMT_RST);
722 
723 	switch (sc->sc_uarttype) {
724 	case COM_UART_ST16650:
725 	case COM_UART_ST16650V2:
726 		bus_space_write_1(iot, ioh, com_lcr, 0xbf);
727 		bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
728 		bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
729 		bus_space_write_1(iot, ioh, com_lcr, 0);
730 		break;
731 	case COM_UART_TI16750:
732 		bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
733 		break;
734 	}
735 }
736 
737 void
738 com_raisedtr(arg)
739 	void *arg;
740 {
741 	struct com_softc *sc = arg;
742 
743 	SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
744 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
745 }
746 
747 int
748 comread(dev, uio, flag)
749 	dev_t dev;
750 	struct uio *uio;
751 	int flag;
752 {
753 	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)];
754 	struct tty *tp = sc->sc_tty;
755 
756 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
757 }
758 
759 int
760 comwrite(dev, uio, flag)
761 	dev_t dev;
762 	struct uio *uio;
763 	int flag;
764 {
765 	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)];
766 	struct tty *tp = sc->sc_tty;
767 
768 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
769 }
770 
771 struct tty *
772 comtty(dev)
773 	dev_t dev;
774 {
775 	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)];
776 	struct tty *tp = sc->sc_tty;
777 
778 	return (tp);
779 }
780 
781 static u_char
782 tiocm_xxx2mcr(data)
783 	int data;
784 {
785 	u_char m = 0;
786 
787 	if (ISSET(data, TIOCM_DTR))
788 		SET(m, MCR_DTR);
789 	if (ISSET(data, TIOCM_RTS))
790 		SET(m, MCR_RTS);
791 	return m;
792 }
793 
794 int
795 comioctl(dev, cmd, data, flag, p)
796 	dev_t dev;
797 	u_long cmd;
798 	caddr_t data;
799 	int flag;
800 	struct proc *p;
801 {
802 	int unit = DEVUNIT(dev);
803 	struct com_softc *sc = com_cd.cd_devs[unit];
804 	struct tty *tp = sc->sc_tty;
805 	bus_space_tag_t iot = sc->sc_iot;
806 	bus_space_handle_t ioh = sc->sc_ioh;
807 	int error;
808 
809 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
810 	if (error >= 0)
811 		return error;
812 	error = ttioctl(tp, cmd, data, flag, p);
813 	if (error >= 0)
814 		return error;
815 
816 	switch (cmd) {
817 	case TIOCSBRK:
818 		SET(sc->sc_lcr, LCR_SBREAK);
819 		bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
820 		break;
821 	case TIOCCBRK:
822 		CLR(sc->sc_lcr, LCR_SBREAK);
823 		bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
824 		break;
825 	case TIOCSDTR:
826 		SET(sc->sc_mcr, sc->sc_dtr);
827 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
828 		break;
829 	case TIOCCDTR:
830 		CLR(sc->sc_mcr, sc->sc_dtr);
831 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
832 		break;
833 	case TIOCMSET:
834 		CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
835 	case TIOCMBIS:
836 		SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
837 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
838 		break;
839 	case TIOCMBIC:
840 		CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
841 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
842 		break;
843 	case TIOCMGET: {
844 		u_char m;
845 		int bits = 0;
846 
847 		m = sc->sc_mcr;
848 		if (ISSET(m, MCR_DTR))
849 			SET(bits, TIOCM_DTR);
850 		if (ISSET(m, MCR_RTS))
851 			SET(bits, TIOCM_RTS);
852 		m = sc->sc_msr;
853 		if (ISSET(m, MSR_DCD))
854 			SET(bits, TIOCM_CD);
855 		if (ISSET(m, MSR_CTS))
856 			SET(bits, TIOCM_CTS);
857 		if (ISSET(m, MSR_DSR))
858 			SET(bits, TIOCM_DSR);
859 		if (ISSET(m, MSR_RI | MSR_TERI))
860 			SET(bits, TIOCM_RI);
861 		if (bus_space_read_1(iot, ioh, com_ier))
862 			SET(bits, TIOCM_LE);
863 		*(int *)data = bits;
864 		break;
865 	}
866 	case TIOCGFLAGS: {
867 		int driverbits, userbits = 0;
868 
869 		driverbits = sc->sc_swflags;
870 		if (ISSET(driverbits, COM_SW_SOFTCAR))
871 			SET(userbits, TIOCFLAG_SOFTCAR);
872 		if (ISSET(driverbits, COM_SW_CLOCAL))
873 			SET(userbits, TIOCFLAG_CLOCAL);
874 		if (ISSET(driverbits, COM_SW_CRTSCTS))
875 			SET(userbits, TIOCFLAG_CRTSCTS);
876 		if (ISSET(driverbits, COM_SW_MDMBUF))
877 			SET(userbits, TIOCFLAG_MDMBUF);
878 		if (ISSET(driverbits, COM_SW_PPS))
879 			SET(userbits, TIOCFLAG_PPS);
880 
881 		*(int *)data = userbits;
882 		break;
883 	}
884 	case TIOCSFLAGS: {
885 		int userbits, driverbits = 0;
886 
887 		error = suser(p->p_ucred, &p->p_acflag);
888 		if (error != 0)
889 			return(EPERM);
890 
891 		userbits = *(int *)data;
892 		if (ISSET(userbits, TIOCFLAG_SOFTCAR) ||
893 		    ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
894 			SET(driverbits, COM_SW_SOFTCAR);
895 		if (ISSET(userbits, TIOCFLAG_CLOCAL))
896 			SET(driverbits, COM_SW_CLOCAL);
897 		if (ISSET(userbits, TIOCFLAG_CRTSCTS))
898 			SET(driverbits, COM_SW_CRTSCTS);
899 		if (ISSET(userbits, TIOCFLAG_MDMBUF))
900 			SET(driverbits, COM_SW_MDMBUF);
901 		if (ISSET(userbits, TIOCFLAG_PPS))
902 			SET(driverbits, COM_SW_PPS);
903 
904 		sc->sc_swflags = driverbits;
905 		break;
906 	}
907 	default:
908 		return ENOTTY;
909 	}
910 
911 	return 0;
912 }
913 
914 /* already called at spltty */
915 int
916 comparam(tp, t)
917 	struct tty *tp;
918 	struct termios *t;
919 {
920 	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(tp->t_dev)];
921 	bus_space_tag_t iot = sc->sc_iot;
922 	bus_space_handle_t ioh = sc->sc_ioh;
923 	int ospeed = comspeed(sc->sc_frequency, t->c_ospeed);
924 	u_char lcr;
925 	tcflag_t oldcflag;
926 
927 	/* check requested parameters */
928 	if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
929 		return EINVAL;
930 
931 	lcr = ISSET(sc->sc_lcr, LCR_SBREAK);
932 
933 	switch (ISSET(t->c_cflag, CSIZE)) {
934 	case CS5:
935 		SET(lcr, LCR_5BITS);
936 		break;
937 	case CS6:
938 		SET(lcr, LCR_6BITS);
939 		break;
940 	case CS7:
941 		SET(lcr, LCR_7BITS);
942 		break;
943 	case CS8:
944 		SET(lcr, LCR_8BITS);
945 		break;
946 	}
947 	if (ISSET(t->c_cflag, PARENB)) {
948 		SET(lcr, LCR_PENAB);
949 		if (!ISSET(t->c_cflag, PARODD))
950 			SET(lcr, LCR_PEVEN);
951 	}
952 	if (ISSET(t->c_cflag, CSTOPB))
953 		SET(lcr, LCR_STOPB);
954 
955 	sc->sc_lcr = lcr;
956 
957 	if (ospeed == 0) {
958 		CLR(sc->sc_mcr, MCR_DTR);
959 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
960 	}
961 
962 	/*
963 	 * Set the FIFO threshold based on the receive speed, if we are
964 	 * changing it.
965 	 */
966 	if (sc->sc_initialize || (tp->t_ispeed != t->c_ispeed)) {
967 		sc->sc_initialize = 0;
968 
969 		if (ospeed != 0) {
970 			/*
971 			 * Make sure the transmit FIFO is empty before
972 			 * proceeding.  If we don't do this, some revisions
973 			 * of the UART will hang.  Interestingly enough,
974 			 * even if we do this while the last character is
975 			 * still being pushed out, they don't hang.  This
976 			 * seems good enough.
977 			 */
978 			while (ISSET(tp->t_state, TS_BUSY)) {
979 				int error;
980 
981 				++sc->sc_halt;
982 				error = ttysleep(tp, &tp->t_outq,
983 				    TTOPRI | PCATCH, "comprm", 0);
984 				--sc->sc_halt;
985 				if (error) {
986 					comstart(tp);
987 					return (error);
988 				}
989 			}
990 
991 			bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
992 			bus_space_write_1(iot, ioh, com_dlbl, ospeed);
993 			bus_space_write_1(iot, ioh, com_dlbh, ospeed >> 8);
994 			bus_space_write_1(iot, ioh, com_lcr, lcr);
995 			SET(sc->sc_mcr, MCR_DTR);
996 			bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
997 		} else
998 			bus_space_write_1(iot, ioh, com_lcr, lcr);
999 
1000 		if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
1001 			if (sc->sc_uarttype == COM_UART_TI16750) {
1002 				bus_space_write_1(iot, ioh, com_lcr,
1003 				    lcr | LCR_DLAB);
1004 				bus_space_write_1(iot, ioh, com_fifo,
1005 				    FIFO_ENABLE | FIFO_ENABLE_64BYTE |
1006 				    (t->c_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8));
1007 				bus_space_write_1(iot, ioh, com_lcr, lcr);
1008 			} else
1009 				bus_space_write_1(iot, ioh, com_fifo,
1010 				    FIFO_ENABLE |
1011 				    (t->c_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8));
1012 		}
1013 	} else
1014 		bus_space_write_1(iot, ioh, com_lcr, lcr);
1015 
1016 	/* When not using CRTSCTS, RTS follows DTR. */
1017 	if (!ISSET(t->c_cflag, CRTSCTS)) {
1018 		if (ISSET(sc->sc_mcr, MCR_DTR)) {
1019 			if (!ISSET(sc->sc_mcr, MCR_RTS)) {
1020 				SET(sc->sc_mcr, MCR_RTS);
1021 				bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1022 			}
1023 		} else {
1024 			if (ISSET(sc->sc_mcr, MCR_RTS)) {
1025 				CLR(sc->sc_mcr, MCR_RTS);
1026 				bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1027 			}
1028 		}
1029 		sc->sc_dtr = MCR_DTR | MCR_RTS;
1030 	} else
1031 		sc->sc_dtr = MCR_DTR;
1032 
1033 	/* and copy to tty */
1034 	tp->t_ispeed = t->c_ispeed;
1035 	tp->t_ospeed = t->c_ospeed;
1036 	oldcflag = tp->t_cflag;
1037 	tp->t_cflag = t->c_cflag;
1038 
1039 	/*
1040 	 * If DCD is off and MDMBUF is changed, ask the tty layer if we should
1041 	 * stop the device.
1042 	 */
1043 	if (!ISSET(sc->sc_msr, MSR_DCD) &&
1044 	    !ISSET(sc->sc_swflags, COM_SW_SOFTCAR) &&
1045 	    ISSET(oldcflag, MDMBUF) != ISSET(tp->t_cflag, MDMBUF) &&
1046 	    (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
1047 		CLR(sc->sc_mcr, sc->sc_dtr);
1048 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1049 	}
1050 
1051 	/* Just to be sure... */
1052 	comstart(tp);
1053 	return 0;
1054 }
1055 
1056 void
1057 comstart(tp)
1058 	struct tty *tp;
1059 {
1060 	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(tp->t_dev)];
1061 	bus_space_tag_t iot = sc->sc_iot;
1062 	bus_space_handle_t ioh = sc->sc_ioh;
1063 	int s;
1064 
1065 	s = spltty();
1066 	if (ISSET(tp->t_state, TS_BUSY))
1067 		goto out;
1068 	if (ISSET(tp->t_state, TS_TIMEOUT | TS_TTSTOP) || sc->sc_halt > 0)
1069 		goto stopped;
1070 	if (ISSET(tp->t_cflag, CRTSCTS) && !ISSET(sc->sc_msr, MSR_CTS))
1071 		goto stopped;
1072 	if (tp->t_outq.c_cc <= tp->t_lowat) {
1073 		if (ISSET(tp->t_state, TS_ASLEEP)) {
1074 			CLR(tp->t_state, TS_ASLEEP);
1075 			wakeup(&tp->t_outq);
1076 		}
1077 		if (tp->t_outq.c_cc == 0)
1078 			goto stopped;
1079 		selwakeup(&tp->t_wsel);
1080 	}
1081 	SET(tp->t_state, TS_BUSY);
1082 
1083 	/* Enable transmit completion interrupts. */
1084 	if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
1085 		SET(sc->sc_ier, IER_ETXRDY);
1086 		bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1087 	}
1088 
1089 	if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
1090 		u_char buffer[64];	/* XXX: largest fifo */
1091 
1092 		int n = q_to_b(&tp->t_outq, buffer, sc->sc_fifolen);
1093 		int i;
1094 
1095 		for (i = 0; i < n; i++) {
1096 			bus_space_write_1(iot, ioh, com_data, buffer[i]);
1097 		}
1098 	} else
1099 		bus_space_write_1(iot, ioh, com_data, getc(&tp->t_outq));
1100 out:
1101 	splx(s);
1102 	return;
1103 stopped:
1104 	if (ISSET(sc->sc_ier, IER_ETXRDY)) {
1105 		CLR(sc->sc_ier, IER_ETXRDY);
1106 		bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1107 	}
1108 	splx(s);
1109 }
1110 
1111 /*
1112  * Stop output on a line.
1113  */
1114 int
1115 comstop(tp, flag)
1116 	struct tty *tp;
1117 	int flag;
1118 {
1119 	int s;
1120 
1121 	s = spltty();
1122 	if (ISSET(tp->t_state, TS_BUSY))
1123 		if (!ISSET(tp->t_state, TS_TTSTOP))
1124 			SET(tp->t_state, TS_FLUSH);
1125 	splx(s);
1126 	return 0;
1127 }
1128 
1129 void
1130 comdiag(arg)
1131 	void *arg;
1132 {
1133 	struct com_softc *sc = arg;
1134 	int overflows, floods;
1135 	int s;
1136 
1137 	s = spltty();
1138 	sc->sc_errors = 0;
1139 	overflows = sc->sc_overflows;
1140 	sc->sc_overflows = 0;
1141 	floods = sc->sc_floods;
1142 	sc->sc_floods = 0;
1143 	splx(s);
1144 	log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf overflow%s\n",
1145 	    sc->sc_dev.dv_xname,
1146 	    overflows, overflows == 1 ? "" : "s",
1147 	    floods, floods == 1 ? "" : "s");
1148 }
1149 
1150 void
1151 compoll(arg)
1152 	void *arg;
1153 {
1154 	struct com_softc *sc = (struct com_softc *)arg;
1155 	struct tty *tp;
1156 	register u_char *ibufp;
1157 	u_char *ibufend;
1158 	register int c;
1159 	int s;
1160 	static int lsrmap[8] = {
1161 		0,      TTY_PE,
1162 		TTY_FE, TTY_PE|TTY_FE,
1163 		TTY_FE, TTY_PE|TTY_FE,
1164 		TTY_FE, TTY_PE|TTY_FE
1165 	};
1166 
1167 	if (sc == NULL || sc->sc_ibufp == sc->sc_ibuf)
1168 		goto out;
1169 
1170 	tp = sc->sc_tty;
1171 
1172 	s = spltty();
1173 
1174 	ibufp = sc->sc_ibuf;
1175 	ibufend = sc->sc_ibufp;
1176 
1177 	if (ibufp == ibufend) {
1178 		splx(s);
1179 		goto out;
1180 	}
1181 
1182 	sc->sc_ibufp = sc->sc_ibuf = (ibufp == sc->sc_ibufs[0]) ?
1183 				     sc->sc_ibufs[1] : sc->sc_ibufs[0];
1184 	sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER;
1185 	sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;
1186 
1187 	if (tp == NULL || !ISSET(tp->t_state, TS_ISOPEN)) {
1188 		splx(s);
1189 		goto out;
1190 	}
1191 
1192 	if (ISSET(tp->t_cflag, CRTSCTS) &&
1193 	    !ISSET(sc->sc_mcr, MCR_RTS)) {
1194 		/* XXX */
1195 		SET(sc->sc_mcr, MCR_RTS);
1196 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr,
1197 		    sc->sc_mcr);
1198 	}
1199 
1200 	splx(s);
1201 
1202 	while (ibufp < ibufend) {
1203 		c = *ibufp++;
1204 		if (ISSET(*ibufp, LSR_OE)) {
1205 			sc->sc_overflows++;
1206 			if (sc->sc_errors++ == 0)
1207 				timeout_add(&sc->sc_diag_tmo, 60 * hz);
1208 		}
1209 		/* This is ugly, but fast. */
1210 		c |= lsrmap[(*ibufp++ & (LSR_BI|LSR_FE|LSR_PE)) >> 2];
1211 		(*linesw[tp->t_line].l_rint)(c, tp);
1212 	}
1213 
1214 out:
1215 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
1216 	timeout_add(&sc->sc_poll_tmo, 1);
1217 #else
1218 	;
1219 #endif
1220 }
1221 
1222 #ifdef KGDB
1223 
1224 /*
1225  * If a line break is set, or data matches one of the characters
1226  * gdb uses to signal a connection, then start up kgdb. Just gobble
1227  * any other data. Done in a stand alone function because comintr
1228  * does tty stuff and we don't have one.
1229  */
1230 
1231 int
1232 kgdbintr(arg)
1233 	void *arg;
1234 {
1235 	struct com_softc *sc = arg;
1236 	bus_space_tag_t iot = sc->sc_iot;
1237 	bus_space_handle_t ioh = sc->sc_ioh;
1238 	u_char lsr, data, msr, delta;
1239 
1240 	if (!ISSET(sc->sc_hwflags, COM_HW_KGDB))
1241 		return(0);
1242 
1243 	for (;;) {
1244 		lsr = bus_space_read_1(iot, ioh, com_lsr);
1245 		if (ISSET(lsr, LSR_RXRDY)) {
1246 			do {
1247 				data = bus_space_read_1(iot, ioh, com_data);
1248 				if (data == 3 || data == '$' || data == '+' ||
1249 				    ISSET(lsr, LSR_BI)) {
1250 					kgdb_connect(1);
1251 					data = 0;
1252 				}
1253 				lsr = bus_space_read_1(iot, ioh, com_lsr);
1254 			} while (ISSET(lsr, LSR_RXRDY));
1255 
1256 		}
1257 		if (ISSET(lsr, LSR_BI|LSR_FE|LSR_PE|LSR_OE))
1258 			printf("weird lsr %02x\n", lsr);
1259 
1260 		msr = bus_space_read_1(iot, ioh, com_msr);
1261 
1262 		if (msr != sc->sc_msr) {
1263 			delta = msr ^ sc->sc_msr;
1264 			sc->sc_msr = msr;
1265 			if (ISSET(delta, MSR_DCD)) {
1266 				if (!ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
1267 					CLR(sc->sc_mcr, sc->sc_dtr);
1268 					bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1269 				}
1270 			}
1271 		}
1272 		if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1273 			return (1);
1274 	}
1275 }
1276 #endif /* KGDB */
1277 
1278 int
1279 comintr(arg)
1280 	void *arg;
1281 {
1282 	struct com_softc *sc = arg;
1283 	bus_space_tag_t iot = sc->sc_iot;
1284 	bus_space_handle_t ioh = sc->sc_ioh;
1285 	struct tty *tp;
1286 	u_char lsr, data, msr, delta;
1287 
1288 	if (!sc->sc_tty)
1289 		return (0);		/* can't do squat. */
1290 
1291 	if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1292 		return (0);
1293 
1294 	tp = sc->sc_tty;
1295 
1296 	for (;;) {
1297 		lsr = bus_space_read_1(iot, ioh, com_lsr);
1298 
1299 		if (ISSET(lsr, LSR_RXRDY)) {
1300 			register u_char *p = sc->sc_ibufp;
1301 
1302 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
1303 			softintr_schedule(sc->sc_si);
1304 #endif
1305 			do {
1306 				data = bus_space_read_1(iot, ioh, com_data);
1307 				if (ISSET(lsr, LSR_BI)) {
1308 #ifdef DDB
1309 					if (ISSET(sc->sc_hwflags,
1310 					    COM_HW_CONSOLE)) {
1311 						if (db_console)
1312 							Debugger();
1313 						goto next;
1314 					}
1315 #endif
1316 					data = 0;
1317 				}
1318 				if (p >= sc->sc_ibufend) {
1319 					sc->sc_floods++;
1320 					if (sc->sc_errors++ == 0)
1321 						timeout_add(&sc->sc_diag_tmo, 60 * hz);
1322 				} else {
1323 					*p++ = data;
1324 					*p++ = lsr;
1325 					if (p == sc->sc_ibufhigh &&
1326 					    ISSET(tp->t_cflag, CRTSCTS)) {
1327 						/* XXX */
1328 						CLR(sc->sc_mcr, MCR_RTS);
1329 						bus_space_write_1(iot, ioh, com_mcr,
1330 						    sc->sc_mcr);
1331 					}
1332 				}
1333 #ifdef DDB
1334 			next:
1335 #endif
1336 				lsr = bus_space_read_1(iot, ioh, com_lsr);
1337 			} while (ISSET(lsr, LSR_RXRDY));
1338 
1339 			sc->sc_ibufp = p;
1340 		}
1341 		msr = bus_space_read_1(iot, ioh, com_msr);
1342 
1343 		if (msr != sc->sc_msr) {
1344 			delta = msr ^ sc->sc_msr;
1345 			sc->sc_msr = msr;
1346 			if (ISSET(delta, MSR_DCD)) {
1347 				if (!ISSET(sc->sc_swflags, COM_SW_SOFTCAR) &&
1348 				    (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)) == 0) {
1349 					CLR(sc->sc_mcr, sc->sc_dtr);
1350 					bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1351 				}
1352 			}
1353 			if (ISSET(delta & msr, MSR_CTS) &&
1354 			    ISSET(tp->t_cflag, CRTSCTS)) {
1355 				/* the line is up and we want to do rts/cts flow control */
1356 				(*linesw[tp->t_line].l_start)(tp);
1357 			}
1358 		}
1359 
1360 		if (ISSET(lsr, LSR_TXRDY) && ISSET(tp->t_state, TS_BUSY)) {
1361 			CLR(tp->t_state, TS_BUSY | TS_FLUSH);
1362 			if (sc->sc_halt > 0)
1363 				wakeup(&tp->t_outq);
1364 			(*linesw[tp->t_line].l_start)(tp);
1365 		}
1366 
1367 		if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1368 			return (1);
1369 	}
1370 }
1371 
1372 /*
1373  * Following are all routines needed for COM to act as console
1374  */
1375 
1376 #if defined(arc)
1377 #undef CONADDR
1378 	extern int CONADDR;
1379 #endif
1380 
1381 /*
1382  * The following functions are polled getc and putc routines, shared
1383  * by the console and kgdb glue.
1384  */
1385 
1386 int
1387 com_common_getc(iot, ioh)
1388 	bus_space_tag_t iot;
1389 	bus_space_handle_t ioh;
1390 {
1391 	int s = splhigh();
1392 	u_char stat, c;
1393 
1394 	/* block until a character becomes available */
1395 	while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
1396 		continue;
1397 
1398 	c = bus_space_read_1(iot, ioh, com_data);
1399 	/* clear any interrupts generated by this transmission */
1400 	stat = bus_space_read_1(iot, ioh, com_iir);
1401 	splx(s);
1402 	return (c);
1403 }
1404 
1405 void
1406 com_common_putc(iot, ioh, c)
1407 	bus_space_tag_t iot;
1408 	bus_space_handle_t ioh;
1409 	int c;
1410 {
1411 	int s = spltty();
1412 	int timo;
1413 
1414 	/* wait for any pending transmission to finish */
1415 	timo = 2000;
1416 	while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
1417 		delay(1);
1418 
1419 	bus_space_write_1(iot, ioh, com_data, c);
1420 	bus_space_barrier(iot, ioh, 0, COM_NPORTS,
1421 	    (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE));
1422 
1423 	/* wait for this transmission to complete */
1424 	timo = 2000;
1425 	while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
1426 		delay(1);
1427 
1428 	splx(s);
1429 }
1430 
1431 /*
1432  * Following are all routines needed for COM to act as console
1433  */
1434 void
1435 cominit(iot, ioh, rate)
1436 	bus_space_tag_t iot;
1437 	bus_space_handle_t ioh;
1438 	int rate;
1439 {
1440 	int s = splhigh();
1441 	u_char stat;
1442 
1443 	bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);
1444 	rate = comspeed(COM_FREQ, rate); /* XXX not comdefaultrate? */
1445 	bus_space_write_1(iot, ioh, com_dlbl, rate);
1446 	bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
1447 	bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS);
1448 	bus_space_write_1(iot, ioh, com_mcr, MCR_DTR | MCR_RTS);
1449 	bus_space_write_1(iot, ioh, com_ier, 0);  /* Make sure they are off */
1450 	bus_space_write_1(iot, ioh, com_fifo,
1451 	    FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
1452 	stat = bus_space_read_1(iot, ioh, com_iir);
1453 	splx(s);
1454 }
1455 
1456 void
1457 comcnprobe(cp)
1458 	struct consdev *cp;
1459 {
1460 	/* XXX NEEDS TO BE FIXED XXX */
1461 #if defined(arc)
1462 	bus_space_tag_t iot = &arc_bus_io;
1463 #elif defined(hppa)
1464 	bus_space_tag_t iot = &hppa_bustag;
1465 #else
1466 	bus_space_tag_t iot = 0;
1467 #endif
1468 	bus_space_handle_t ioh;
1469 	int found;
1470 
1471 	if(CONADDR == 0) {
1472 		cp->cn_pri = CN_DEAD;
1473 		return;
1474 	}
1475 
1476 	comconsiot = iot;
1477 	if (bus_space_map(iot, CONADDR, COM_NPORTS, 0, &ioh)) {
1478 		cp->cn_pri = CN_DEAD;
1479 		return;
1480 	}
1481 #ifdef __hppa__
1482 	found = 1;
1483 #else
1484 	found = comprobe1(iot, ioh);
1485 #endif
1486 	bus_space_unmap(iot, ioh, COM_NPORTS);
1487 	if (!found) {
1488 		cp->cn_pri = CN_DEAD;
1489 		return;
1490 	}
1491 
1492 	/* locate the major number */
1493 	for (commajor = 0; commajor < nchrdev; commajor++)
1494 		if (cdevsw[commajor].d_open == comopen)
1495 			break;
1496 
1497 	/* initialize required fields */
1498 	cp->cn_dev = makedev(commajor, CONUNIT);
1499 	cp->cn_pri = CN_REMOTE;
1500 }
1501 
1502 void
1503 comcninit(cp)
1504 	struct consdev *cp;
1505 {
1506 	comconsaddr = CONADDR;
1507 
1508 	if (bus_space_map(comconsiot, comconsaddr, COM_NPORTS, 0, &comconsioh))
1509 		panic("comcninit: mapping failed");
1510 
1511 	cominit(comconsiot, comconsioh, comdefaultrate);
1512 	comconsinit = 0;
1513 }
1514 
1515 
1516 int
1517 comcnattach(iot, iobase, rate, frequency, cflag)
1518 	bus_space_tag_t iot;
1519 	int iobase;
1520 	int rate, frequency;
1521 	tcflag_t cflag;
1522 {
1523 	static struct consdev comcons = {
1524 		NULL, NULL, comcngetc, comcnputc, comcnpollc, NULL,
1525 		NODEV, CN_NORMAL
1526 	};
1527 
1528 #ifndef __sparc64__
1529 	if (bus_space_map(iot, iobase, COM_NPORTS, 0, &comconsioh))
1530 		return ENOMEM;
1531 #endif
1532 
1533 	cominit(iot, comconsioh, rate);
1534 
1535 	cn_tab = &comcons;
1536 
1537 	comconsiot = iot;
1538 	comconsaddr = iobase;
1539 	comconscflag = cflag;
1540 
1541 	return (0);
1542 }
1543 
1544 int
1545 comcngetc(dev)
1546 	dev_t dev;
1547 {
1548 	return (com_common_getc(comconsiot, comconsioh));
1549 }
1550 
1551 /*
1552  * Console kernel output character routine.
1553  */
1554 void
1555 comcnputc(dev, c)
1556 	dev_t dev;
1557 	int c;
1558 {
1559 	com_common_putc(comconsiot, comconsioh, c);
1560 }
1561 
1562 void
1563 comcnpollc(dev, on)
1564 	dev_t dev;
1565 	int on;
1566 {
1567 
1568 }
1569 
1570 #ifdef KGDB
1571 int
1572 com_kgdb_attach(iot, iobase, rate, frequency, cflag)
1573 	bus_space_tag_t iot;
1574 	int iobase;
1575 	int rate, frequency;
1576 	tcflag_t cflag;
1577 {
1578 	if (iot == comconsiot && iobase == comconsaddr) {
1579 		return (EBUSY); /* cannot share with console */
1580 	}
1581 
1582 	com_kgdb_iot = iot;
1583 	com_kgdb_addr = iobase;
1584 
1585 	if (bus_space_map(com_kgdb_iot, com_kgdb_addr, COM_NPORTS, 0,
1586 	    &com_kgdb_ioh))
1587 		panic("com_kgdb_attach: mapping failed");
1588 
1589 	/* XXX We currently don't respect KGDBMODE? */
1590 	cominit(com_kgdb_iot, com_kgdb_ioh, rate);
1591 
1592 	kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL);
1593 	kgdb_dev = 123; /* unneeded, only to satisfy some tests */
1594 
1595 	return (0);
1596 }
1597 
1598 /* ARGSUSED */
1599 int
1600 com_kgdb_getc(arg)
1601 	void *arg;
1602 {
1603 
1604 	return (com_common_getc(com_kgdb_iot, com_kgdb_ioh));
1605 }
1606 
1607 /* ARGSUSED */
1608 void
1609 com_kgdb_putc(arg, c)
1610 	void *arg;
1611 	int c;
1612 {
1613 
1614 	return (com_common_putc(com_kgdb_iot, com_kgdb_ioh, c));
1615 }
1616 #endif /* KGDB */
1617