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