xref: /openbsd-src/sys/dev/ic/com.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: com.c,v 1.63 2001/04/17 04:30:49 aaron 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  * 3. Neither the name(s) of the author(s) nor the name OpenBSD
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 /*-
32  * Copyright (c) 1993, 1994, 1995, 1996
33  *	Charles M. Hannum.  All rights reserved.
34  * Copyright (c) 1991 The Regents of the University of California.
35  * All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. All advertising materials mentioning features or use of this software
46  *    must display the following acknowledgement:
47  *	This product includes software developed by the University of
48  *	California, Berkeley and its contributors.
49  * 4. Neither the name of the University nor the names of its contributors
50  *    may be used to endorse or promote products derived from this software
51  *    without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63  * SUCH DAMAGE.
64  *
65  *	@(#)com.c	7.5 (Berkeley) 5/16/91
66  */
67 
68 /*
69  * COM driver, based on HP dca driver
70  * uses National Semiconductor NS16450/NS16550AF UART
71  */
72 #include <sys/param.h>
73 #include <sys/systm.h>
74 #include <sys/ioctl.h>
75 #include <sys/select.h>
76 #include <sys/tty.h>
77 #include <sys/proc.h>
78 #include <sys/user.h>
79 #include <sys/conf.h>
80 #include <sys/file.h>
81 #include <sys/uio.h>
82 #include <sys/kernel.h>
83 #include <sys/syslog.h>
84 #include <sys/types.h>
85 #include <sys/device.h>
86 #include <sys/vnode.h>
87 #ifdef DDB
88 #include <ddb/db_var.h>
89 #endif
90 
91 #include <machine/bus.h>
92 #include <machine/intr.h>
93 
94 #include <dev/cons.h>
95 
96 #include <dev/ic/comreg.h>
97 #include <dev/ic/comvar.h>
98 #include <dev/ic/ns16550reg.h>
99 #ifdef COM_HAYESP
100 #include <dev/ic/hayespreg.h>
101 #endif
102 #define	com_lcr	com_cfcr
103 
104 #include "com.h"
105 
106 #if NCOM_ISA || NCOM_ISAPNP
107 #include <dev/isa/isavar.h>	/* XXX */
108 #endif
109 
110 /* XXX: These belong elsewhere */
111 cdev_decl(com);
112 bdev_decl(com);
113 
114 static u_char tiocm_xxx2mcr __P((int));
115 
116 /*
117  * XXX the following two cfattach structs should be different, and possibly
118  * XXX elsewhere.
119  */
120 int	comprobe __P((struct device *, void *, void *));
121 void	comattach __P((struct device *, struct device *, void *));
122 void	compwroff __P((struct com_softc *));
123 void	com_raisedtr __P((void *));
124 
125 #if NCOM_ISA
126 struct cfattach com_isa_ca = {
127 	sizeof(struct com_softc), comprobe, comattach
128 };
129 #endif
130 
131 #if NCOM_ISAPNP
132 struct cfattach com_isapnp_ca = {
133 	sizeof(struct com_softc), comprobe, comattach
134 };
135 #endif
136 
137 #if NCOM_COMMULTI
138 struct cfattach com_commulti_ca = {
139 	sizeof(struct com_softc), comprobe, comattach
140 };
141 #endif
142 
143 struct cfdriver com_cd = {
144 	NULL, "com", DV_TTY
145 };
146 
147 #ifndef CONSPEED
148 #define	CONSPEED B9600
149 #endif
150 
151 #ifdef COMCONSOLE
152 int	comdefaultrate = CONSPEED;		/* XXX why set default? */
153 #else
154 int	comdefaultrate = TTYDEF_SPEED;
155 #endif
156 int	comconsaddr;
157 int	comconsinit;
158 int	comconsattached;
159 int	comconsrate;
160 bus_space_tag_t comconsiot;
161 bus_space_handle_t comconsioh;
162 tcflag_t comconscflag = TTYDEF_CFLAG;
163 
164 struct timeout compoll_to;
165 
166 int	commajor;
167 int	comsopen = 0;
168 int	comevents = 0;
169 
170 #ifdef KGDB
171 #include <sys/kgdb.h>
172 
173 static int com_kgdb_addr;
174 static bus_space_tag_t com_kgdb_iot;
175 static bus_space_handle_t com_kgdb_ioh;
176 static int com_kgdb_attached;
177 
178 int    com_kgdb_getc __P((void *));
179 void   com_kgdb_putc __P((void *, int));
180 #endif /* KGDB */
181 
182 #define	DEVUNIT(x)	(minor(x) & 0x7f)
183 #define	DEVCUA(x)	(minor(x) & 0x80)
184 
185 /* Macros to clear/set/test flags. */
186 #define	SET(t, f)	(t) |= (f)
187 #define	CLR(t, f)	(t) &= ~(f)
188 #define	ISSET(t, f)	((t) & (f))
189 
190 /* Macros for determining bus type. */
191 #if NCOM_ISA
192 #define IS_ISA(parent) \
193     (strcmp((parent)->dv_cfdata->cf_driver->cd_name, "isa") == 0)
194 #else
195 #define IS_ISA(parent) 0
196 #endif
197 
198 #if NCOM_ISAPNP
199 #define IS_ISAPNP(parent) \
200     (strcmp((parent)->dv_cfdata->cf_driver->cd_name, "isapnp") == 0)
201 #else
202 #define IS_ISAPNP(parent) 0
203 #endif
204 
205 int
206 comspeed(freq, speed)
207 	long freq;
208 	long speed;
209 {
210 #define	divrnd(n, q)	(((n)*2/(q)+1)/2)	/* divide and round off */
211 
212 	int x, err;
213 
214 	if (speed == 0)
215 		return 0;
216 	if (speed < 0)
217 		return -1;
218 	x = divrnd((freq / 16), speed);
219 	if (x <= 0)
220 		return -1;
221 	err = divrnd((freq / 16) * 1000, speed * x) - 1000;
222 	if (err < 0)
223 		err = -err;
224 	if (err > COM_TOLERANCE)
225 		return -1;
226 	return x;
227 
228 #undef	divrnd
229 }
230 
231 int
232 comprobe1(iot, ioh)
233 	bus_space_tag_t iot;
234 	bus_space_handle_t ioh;
235 {
236 	int i, k;
237 
238 	/* force access to id reg */
239 	bus_space_write_1(iot, ioh, com_lcr, 0);
240 	bus_space_write_1(iot, ioh, com_iir, 0);
241 	for (i = 0; i < 32; i++) {
242 	    k = bus_space_read_1(iot, ioh, com_iir);
243 	    if (k & 0x38) {
244 		bus_space_read_1(iot, ioh, com_data); /* cleanup */
245 	    } else
246 		break;
247 	}
248 	if (i >= 32)
249 	    return 0;
250 
251 	return 1;
252 }
253 
254 #ifdef COM_HAYESP
255 int
256 comprobeHAYESP(hayespioh, sc)
257 	bus_space_handle_t hayespioh;
258 	struct com_softc *sc;
259 {
260 	char	val, dips;
261 	int	combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
262 	bus_space_tag_t iot = sc->sc_iot;
263 
264 	/*
265 	 * Hayes ESP cards have two iobases.  One is for compatibility with
266 	 * 16550 serial chips, and at the same ISA PC base addresses.  The
267 	 * other is for ESP-specific enhanced features, and lies at a
268 	 * different addressing range entirely (0x140, 0x180, 0x280, or 0x300).
269 	 */
270 
271 	/* Test for ESP signature */
272 	if ((bus_space_read_1(iot, hayespioh, 0) & 0xf3) == 0)
273 		return 0;
274 
275 	/*
276 	 * ESP is present at ESP enhanced base address; unknown com port
277 	 */
278 
279 	/* Get the dip-switch configurations */
280 	bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETDIPS);
281 	dips = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1);
282 
283 	/* Determine which com port this ESP card services: bits 0,1 of  */
284 	/*  dips is the port # (0-3); combaselist[val] is the com_iobase */
285 	if (sc->sc_iobase != combaselist[dips & 0x03])
286 		return 0;
287 
288 	printf(": ESP");
289 
290 	/* Check ESP Self Test bits. */
291 	/* Check for ESP version 2.0: bits 4,5,6 == 010 */
292 	bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETTEST);
293 	val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1); /* Clear reg 1 */
294 	val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS2);
295 	if ((val & 0x70) < 0x20) {
296 		printf("-old (%o)", val & 0x70);
297 		/* we do not support the necessary features */
298 		return 0;
299 	}
300 
301 	/* Check for ability to emulate 16550: bit 8 == 1 */
302 	if ((dips & 0x80) == 0) {
303 		printf(" slave");
304 		/* XXX Does slave really mean no 16550 support?? */
305 		return 0;
306 	}
307 
308 	/*
309 	 * If we made it this far, we are a full-featured ESP v2.0 (or
310 	 * better), at the correct com port address.
311 	 */
312 
313 	SET(sc->sc_hwflags, COM_HW_HAYESP);
314 	printf(", 1024 byte fifo\n");
315 	return 1;
316 }
317 #endif
318 
319 int
320 comprobe(parent, match, aux)
321 	struct device *parent;
322 	void *match, *aux;
323 {
324 	bus_space_tag_t iot;
325 	bus_space_handle_t ioh;
326 	int iobase, needioh;
327 	int rv = 1;
328 
329 	/*
330 	 * XXX should be broken out into functions for isa probe and
331 	 * XXX for commulti probe, with a helper function that contains
332 	 * XXX most of the interesting stuff.
333 	 */
334 #if NCOM_ISA || NCOM_ISAPNP
335 	if (IS_ISA(parent) || IS_ISAPNP(parent)) {
336 		struct isa_attach_args *ia = aux;
337 
338 		iot = ia->ia_iot;
339 		iobase = ia->ia_iobase;
340 		if (IS_ISAPNP(parent)) {
341 			ioh = ia->ia_ioh;
342 			needioh = 0;
343 		} else
344 			needioh = 1;
345 	} else
346 #endif
347 #if NCOM_COMMULTI
348 	if (1) {
349 		struct cfdata *cf = match;
350 		struct commulti_attach_args *ca = aux;
351 
352 		if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ca->ca_slave)
353 			return (0);
354 
355 		iot = ca->ca_iot;
356 		iobase = ca->ca_iobase;
357 		ioh = ca->ca_ioh;
358 		needioh = 0;
359 	} else
360 #endif
361 		return(0);			/* This cannot happen */
362 
363 #ifdef KGDB
364 	if (iobase == com_kgdb_addr)
365 		goto out;
366 #endif
367 	/* if it's in use as console, it's there. */
368 	if (iobase == comconsaddr && !comconsattached)
369 		goto out;
370 
371 	if (needioh && bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh)) {
372 		rv = 0;
373 		goto out;
374 	}
375 	rv = comprobe1(iot, ioh);
376 	if (needioh)
377 		bus_space_unmap(iot, ioh, COM_NPORTS);
378 
379 out:
380 #if NCOM_ISA
381 	if (rv && IS_ISA(parent)) {
382 		struct isa_attach_args *ia = aux;
383 
384 		ia->ia_iosize = COM_NPORTS;
385 		ia->ia_msize = 0;
386 	}
387 #endif
388 	return (rv);
389 }
390 
391 void
392 comattach(parent, self, aux)
393 	struct device *parent, *self;
394 	void *aux;
395 {
396 	struct com_softc *sc = (void *)self;
397 	int iobase;
398 #if NCOM_ISA || NCOM_ISAPNP || NCOM_COMMULTI
399 	int irq;
400 #endif
401 	bus_space_tag_t iot;
402 	bus_space_handle_t ioh;
403 #ifdef COM_HAYESP
404 	int	hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 };
405 	int	*hayespp;
406 #endif
407 	u_int8_t lcr;
408 
409 	/*
410 	 * XXX should be broken out into functions for isa attach and
411 	 * XXX for commulti attach, with a helper function that contains
412 	 * XXX most of the interesting stuff.
413 	 */
414 	sc->sc_hwflags = 0;
415 	sc->sc_swflags = 0;
416 #if NCOM_ISA || NCOM_ISAPNP
417 	if (IS_ISA(parent) || IS_ISAPNP(parent)) {
418 		struct isa_attach_args *ia = aux;
419 
420 		/*
421 		 * We're living on an isa.
422 		 */
423 		iobase = ia->ia_iobase;
424 		iot = ia->ia_iot;
425 		if (IS_ISAPNP(parent)) {
426 			/* No console support! */
427 			ioh = ia->ia_ioh;
428 		} else {
429 #ifdef KGDB
430 			if ((iobase != comconsaddr) &&
431 			    (iobase != com_kgdb_addr)) {
432 #else
433 			if (iobase != comconsaddr) {
434 #endif
435 				if (bus_space_map(iot, iobase, COM_NPORTS, 0,
436 				    &ioh))
437 					panic("comattach: io mapping failed");
438 			} else
439 #ifdef KGDB
440 				if (iobase == comconsaddr) {
441 					ioh = comconsioh;
442 				} else {
443 					ioh = com_kgdb_ioh;
444 				}
445 #else
446 				ioh = comconsioh;
447 #endif
448 		}
449 		irq = ia->ia_irq;
450 	} else
451 #endif
452 #if NCOM_COMMULTI
453 	if (1) {
454 		struct commulti_attach_args *ca = aux;
455 
456 		/*
457 		 * We're living on a commulti.
458 		 */
459 		iobase = ca->ca_iobase;
460 		iot = ca->ca_iot;
461 		ioh = ca->ca_ioh;
462 		irq = IRQUNK;
463 
464 		if (ca->ca_noien)
465 			SET(sc->sc_hwflags, COM_HW_NOIEN);
466 	} else
467 #endif
468 		panic("comattach: impossible");
469 
470 	sc->sc_iot = iot;
471 	sc->sc_ioh = ioh;
472 	sc->sc_iobase = iobase;
473 	sc->sc_frequency = COM_FREQ;
474 
475 	if (iobase == comconsaddr) {
476 		comconsattached = 1;
477 
478 		/*
479 		 * Need to reset baud rate, etc. of next print so reset
480 		 * comconsinit.  Also make sure console is always "hardwired".
481 		 */
482 		delay(1000);			/* wait for output to finish */
483 		comconsinit = 0;
484 		SET(sc->sc_hwflags, COM_HW_CONSOLE);
485 		SET(sc->sc_swflags, COM_SW_SOFTCAR);
486 	}
487 
488 #ifdef COM_HAYESP
489 	/* Look for a Hayes ESP board. */
490 	for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) {
491 		bus_space_handle_t hayespioh;
492 
493 #define	HAYESP_NPORTS	8			/* XXX XXX XXX ??? ??? ??? */
494 		if (bus_space_map(iot, *hayespp, HAYESP_NPORTS, 0, &hayespioh))
495 			continue;
496 		if (comprobeHAYESP(hayespioh, sc)) {
497 			sc->sc_hayespbase = *hayespp;
498 			sc->sc_hayespioh = hayespioh;
499 			sc->sc_fifolen = 1024;
500 			break;
501 		}
502 		bus_space_unmap(iot, hayespioh, HAYESP_NPORTS);
503 	}
504 	/* No ESP; look for other things. */
505 	if (*hayespp == 0) {
506 #endif
507 
508 	/*
509 	 * Probe for all known forms of UART.
510 	 */
511 	lcr = bus_space_read_1(iot, ioh, com_lcr);
512 
513 	bus_space_write_1(iot, ioh, com_lcr, 0xbf);
514 	bus_space_write_1(iot, ioh, com_efr, 0);
515 	bus_space_write_1(iot, ioh, com_lcr, 0);
516 
517 	bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
518 	delay(100);
519 
520 	switch(bus_space_read_1(iot, ioh, com_iir) >> 6) {
521 	case 0:
522 		sc->sc_uarttype = COM_UART_16450;
523 		break;
524 	case 2:
525 		sc->sc_uarttype = COM_UART_16550;
526 		break;
527 	case 3:
528 		sc->sc_uarttype = COM_UART_16550A;
529 		break;
530 	default:
531 		sc->sc_uarttype = COM_UART_UNKNOWN;
532 		break;
533 	}
534 
535 	if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */
536 		bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
537 		if (bus_space_read_1(iot, ioh, com_efr) == 0) {
538 			sc->sc_uarttype = COM_UART_ST16650;
539 		} else {
540 			bus_space_write_1(iot, ioh, com_lcr, 0xbf);
541 			if (bus_space_read_1(iot, ioh, com_efr) == 0)
542 				sc->sc_uarttype = COM_UART_ST16650V2;
543 		}
544 	}
545 
546 	if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for TI16750s */
547 		bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
548 		bus_space_write_1(iot, ioh, com_fifo,
549 		    FIFO_ENABLE | FIFO_ENABLE_64BYTE);
550 		if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 7) {
551 #if 0
552 			bus_space_write_1(iot, ioh, com_lcr, 0);
553 			if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 6)
554 #endif
555 				sc->sc_uarttype = COM_UART_TI16750;
556 		}
557 		bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
558 	}
559 
560 	bus_space_write_1(iot, ioh, com_lcr, lcr);
561 	if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */
562 		u_int8_t scr0, scr1, scr2;
563 
564 		scr0 = bus_space_read_1(iot, ioh, com_scratch);
565 		bus_space_write_1(iot, ioh, com_scratch, 0xa5);
566 		scr1 = bus_space_read_1(iot, ioh, com_scratch);
567 		bus_space_write_1(iot, ioh, com_scratch, 0x5a);
568 		scr2 = bus_space_read_1(iot, ioh, com_scratch);
569 		bus_space_write_1(iot, ioh, com_scratch, scr0);
570 
571 		if ((scr1 != 0xa5) || (scr2 != 0x5a))
572 			sc->sc_uarttype = COM_UART_8250;
573 	}
574 
575 	/*
576 	 * Print UART type and initialize ourself.
577 	 */
578 	sc->sc_fifolen = 1;	/* default */
579 	switch (sc->sc_uarttype) {
580 	case COM_UART_UNKNOWN:
581 		printf(": unknown uart\n");
582 		break;
583 	case COM_UART_8250:
584 		printf(": ns8250, no fifo\n");
585 		break;
586 	case COM_UART_16450:
587 		printf(": ns16450, no fifo\n");
588 		break;
589 	case COM_UART_16550:
590 		printf(": ns16550, no working fifo\n");
591 		break;
592 	case COM_UART_16550A:
593 		printf(": ns16550a, 16 byte fifo\n");
594 		SET(sc->sc_hwflags, COM_HW_FIFO);
595 		sc->sc_fifolen = 16;
596 		break;
597 	case COM_UART_ST16650:
598 		printf(": st16650, no working fifo\n");
599 		break;
600 	case COM_UART_ST16650V2:
601 		printf(": st16650, 32 byte fifo\n");
602 		SET(sc->sc_hwflags, COM_HW_FIFO);
603 		sc->sc_fifolen = 32;
604 		break;
605 	case COM_UART_TI16750:
606 		printf(": ti16750, 64 byte fifo\n");
607 		SET(sc->sc_hwflags, COM_HW_FIFO);
608 		sc->sc_fifolen = 64;
609 		break;
610 	default:
611 		panic("comattach: bad fifo type");
612 	}
613 
614 	/* clear and disable fifo */
615 	bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST);
616 	(void)bus_space_read_1(iot, ioh, com_data);
617 	bus_space_write_1(iot, ioh, com_fifo, 0);
618 #ifdef COM_HAYESP
619 	}
620 #endif
621 
622 	/* disable interrupts */
623 	bus_space_write_1(iot, ioh, com_ier, 0);
624 	bus_space_write_1(iot, ioh, com_mcr, 0);
625 
626 #if NCOM_ISA || NCOM_ISAPNP || NCOM_COMMULTI
627 	if (irq != IRQUNK) {
628 #if NCOM_ISA || NCOM_ISAPNP
629 		if (IS_ISA(parent) || IS_ISAPNP(parent)) {
630 			struct isa_attach_args *ia = aux;
631 
632 #ifdef KGDB
633 			if (iobase == com_kgdb_addr) {
634 				sc->sc_ih = isa_intr_establish(ia->ia_ic, irq,
635 				    IST_EDGE, IPL_HIGH, kgdbintr, sc,
636 				    sc->sc_dev.dv_xname);
637 			} else {
638 				sc->sc_ih = isa_intr_establish(ia->ia_ic, irq,
639 				    IST_EDGE, IPL_TTY, comintr, sc,
640 				    sc->sc_dev.dv_xname);
641 			}
642 #else
643 			sc->sc_ih = isa_intr_establish(ia->ia_ic, irq,
644 			    IST_EDGE, IPL_TTY, comintr, sc,
645 			    sc->sc_dev.dv_xname);
646 #endif /* KGDB */
647 		} else
648 #endif
649 			panic("comattach: IRQ but can't have one");
650 	}
651 #endif
652 #ifdef KGDB
653 	/*
654 	 * Allow kgdb to "take over" this port.  If this is
655 	 * the kgdb device, it has exclusive use.
656 	 */
657 
658 	if (iot == com_kgdb_iot && iobase == com_kgdb_addr &&
659 	    !ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
660 		printf("%s: kgdb\n", sc->sc_dev.dv_xname);
661 		SET(sc->sc_hwflags, COM_HW_KGDB);
662 		com_enable_debugport(sc);
663 		com_kgdb_attached = 1;
664 	}
665 #endif /* KGDB */
666 
667 	/* XXX maybe move up some? */
668 	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
669 		int maj;
670 
671 		/* locate the major number */
672 		for (maj = 0; maj < nchrdev; maj++)
673 			if (cdevsw[maj].d_open == comopen)
674 				break;
675 
676 		if (maj < nchrdev && cn_tab->cn_dev == NODEV)
677 			cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
678 
679 		printf("%s: console\n", sc->sc_dev.dv_xname);
680 	}
681 
682 	if (!timeout_initialized(&compoll_to))
683 		timeout_set(&compoll_to, compoll, NULL);
684 
685 	timeout_set(&sc->sc_diag_tmo, comdiag, sc);
686 	timeout_set(&sc->sc_dtr_tmo, com_raisedtr, sc);
687 
688 	/*
689 	 * If there are no enable/disable functions, assume the device
690 	 * is always enabled.
691 	 */
692 	if (!sc->enable)
693 		sc->enabled = 1;
694 }
695 
696 #ifdef KGDB
697 void
698 com_enable_debugport(sc)
699 	struct com_softc *sc;
700 {
701 	int s;
702 
703 	/* Turn on line break interrupt, set carrier. */
704 	s = splhigh();
705 	SET(sc->sc_ier, IER_ERXRDY);
706 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
707 	SET(sc->sc_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE);
708 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
709 
710 	splx(s);
711 }
712 #endif /* KGDB */
713 
714 int
715 com_detach(self, flags)
716 	struct device *self;
717 	int flags;
718 {
719 	struct com_softc *sc = (struct com_softc *)self;
720 	int maj, mn;
721 
722 	/* locate the major number */
723 	for (maj = 0; maj < nchrdev; maj++)
724 		if (cdevsw[maj].d_open == comopen)
725 			break;
726 
727 	/* Nuke the vnodes for any open instances. */
728 	mn = self->dv_unit;
729 	vdevgone(maj, mn, mn, VCHR);
730 
731 	/* XXX a symbolic constant for the cua bit would be nicer. */
732 	mn |= 0x80;
733 	vdevgone(maj, mn, mn, VCHR);
734 
735 	/* Detach and free the tty. */
736 	if (sc->sc_tty) {
737 		tty_detach(sc->sc_tty);
738 		ttyfree(sc->sc_tty);
739 	}
740 
741 	timeout_del(&sc->sc_dtr_tmo);
742 	timeout_del(&sc->sc_diag_tmo);
743 
744 	return (0);
745 }
746 
747 int
748 com_activate(self, act)
749 	struct device *self;
750 	enum devact act;
751 {
752 	struct com_softc *sc = (struct com_softc *)self;
753 	int s, rv = 0;
754 
755 	s = spltty();
756 	switch (act) {
757 	case DVACT_ACTIVATE:
758 		rv = EOPNOTSUPP;
759 		break;
760 
761 	case DVACT_DEACTIVATE:
762 #ifdef KGDB
763 		if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) {
764 #else
765 		if (sc->sc_hwflags & COM_HW_CONSOLE) {
766 #endif /* KGDB */
767 			rv = EBUSY;
768 			break;
769 		}
770 
771 		if (sc->disable != NULL && sc->enabled != 0) {
772 			(*sc->disable)(sc);
773 			sc->enabled = 0;
774 		}
775 		break;
776 	}
777 	splx(s);
778 	return (rv);
779 }
780 
781 int
782 comopen(dev, flag, mode, p)
783 	dev_t dev;
784 	int flag, mode;
785 	struct proc *p;
786 {
787 	int unit = DEVUNIT(dev);
788 	struct com_softc *sc;
789 	bus_space_tag_t iot;
790 	bus_space_handle_t ioh;
791 	struct tty *tp;
792 	int s;
793 	int error = 0;
794 
795 	if (unit >= com_cd.cd_ndevs)
796 		return ENXIO;
797 	sc = com_cd.cd_devs[unit];
798 	if (!sc)
799 		return ENXIO;
800 
801 #ifdef KGDB
802 	/*
803 	 * If this is the kgdb port, no other use is permitted.
804 	 */
805 	if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
806 		return (EBUSY);
807 #endif /* KGDB */
808 
809 	s = spltty();
810 	if (!sc->sc_tty) {
811 		tp = sc->sc_tty = ttymalloc();
812 		tty_attach(tp);
813 	} else
814 		tp = sc->sc_tty;
815 	splx(s);
816 
817 	tp->t_oproc = comstart;
818 	tp->t_param = comparam;
819 	tp->t_dev = dev;
820 	if (!ISSET(tp->t_state, TS_ISOPEN)) {
821 		SET(tp->t_state, TS_WOPEN);
822 		ttychars(tp);
823 		tp->t_iflag = TTYDEF_IFLAG;
824 		tp->t_oflag = TTYDEF_OFLAG;
825 		if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
826 			tp->t_cflag = comconscflag;
827 		else
828 			tp->t_cflag = TTYDEF_CFLAG;
829 		if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
830 			SET(tp->t_cflag, CLOCAL);
831 		if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
832 			SET(tp->t_cflag, CRTSCTS);
833 		if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
834 			SET(tp->t_cflag, MDMBUF);
835 		tp->t_lflag = TTYDEF_LFLAG;
836 		tp->t_ispeed = tp->t_ospeed = comdefaultrate;
837 
838 		s = spltty();
839 
840 		sc->sc_initialize = 1;
841 		comparam(tp, &tp->t_termios);
842 		ttsetwater(tp);
843 
844 		if (comsopen++ == 0)
845 			timeout_add(&compoll_to, 1);
846 
847 		sc->sc_ibufp = sc->sc_ibuf = sc->sc_ibufs[0];
848 		sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER;
849 		sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;
850 
851 		iot = sc->sc_iot;
852 		ioh = sc->sc_ioh;
853 
854 		/*
855 		 * Wake up the sleepy heads.
856 		 */
857 		switch (sc->sc_uarttype) {
858 		case COM_UART_ST16650:
859 		case COM_UART_ST16650V2:
860 			bus_space_write_1(iot, ioh, com_lcr, 0xbf);
861 			bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
862 			bus_space_write_1(iot, ioh, com_ier, 0);
863 			bus_space_write_1(iot, ioh, com_efr, 0);
864 			bus_space_write_1(iot, ioh, com_lcr, 0);
865 			break;
866 		case COM_UART_TI16750:
867 			bus_space_write_1(iot, ioh, com_ier, 0);
868 			break;
869 		}
870 
871 #ifdef COM_HAYESP
872 		/* Setup the ESP board */
873 		if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
874 			bus_space_handle_t hayespioh = sc->sc_hayespioh;
875 
876 			bus_space_write_1(iot, ioh, com_fifo,
877 			    FIFO_DMA_MODE|FIFO_ENABLE|
878 			    FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_8);
879 
880 			/* Set 16550 compatibility mode */
881 			bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETMODE);
882 			bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
883 			    HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
884 			    HAYESP_MODE_SCALE);
885 
886 			/* Set RTS/CTS flow control */
887 			bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETFLOWTYPE);
888 			bus_space_write_1(iot, hayespioh, HAYESP_CMD2, HAYESP_FLOW_RTS);
889 			bus_space_write_1(iot, hayespioh, HAYESP_CMD2, HAYESP_FLOW_CTS);
890 
891 			/* Set flow control levels */
892 			bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETRXFLOW);
893 			bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
894 			    HAYESP_HIBYTE(HAYESP_RXHIWMARK));
895 			bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
896 			    HAYESP_LOBYTE(HAYESP_RXHIWMARK));
897 			bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
898 			    HAYESP_HIBYTE(HAYESP_RXLOWMARK));
899 			bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
900 			    HAYESP_LOBYTE(HAYESP_RXLOWMARK));
901 		} else
902 #endif
903 		if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
904 			u_int8_t fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST;
905 			u_int8_t lcr;
906 
907 			if (tp->t_ispeed <= 1200)
908 				fifo |= FIFO_TRIGGER_1;
909 			else
910 				fifo |= FIFO_TRIGGER_8;
911 			if (sc->sc_uarttype == COM_UART_TI16750) {
912 				fifo |= FIFO_ENABLE_64BYTE;
913 				lcr = bus_space_read_1(iot, ioh, com_lcr);
914 				bus_space_write_1(iot, ioh, com_lcr,
915 				    lcr | LCR_DLAB);
916 			}
917 
918 			/*
919 			 * (Re)enable and drain FIFOs.
920 			 *
921 			 * Certain SMC chips cause problems if the FIFOs are
922 			 * enabled while input is ready. Turn off the FIFO
923 			 * if necessary to clear the input. Test the input
924 			 * ready bit after enabling the FIFOs to handle races
925 			 * between enabling and fresh input.
926 			 *
927 			 * Set the FIFO threshold based on the receive speed.
928 			 */
929 			for (;;) {
930 				bus_space_write_1(iot, ioh, com_fifo, 0);
931 				delay(100);
932 				(void) bus_space_read_1(iot, ioh, com_data);
933 				bus_space_write_1(iot, ioh, com_fifo, fifo |
934 				    FIFO_RCV_RST | FIFO_XMT_RST);
935 				delay(100);
936 				if(!ISSET(bus_space_read_1(iot, ioh,
937 				    com_lsr), LSR_RXRDY))
938 					break;
939 			}
940 			if (sc->sc_uarttype == COM_UART_TI16750)
941 				bus_space_write_1(iot, ioh, com_lcr, lcr);
942 		}
943 
944 		/* flush any pending I/O */
945 		while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
946 			(void) bus_space_read_1(iot, ioh, com_data);
947 		/* you turn me on, baby */
948 		sc->sc_mcr = MCR_DTR | MCR_RTS;
949 		if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
950 			SET(sc->sc_mcr, MCR_IENABLE);
951 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
952 		sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
953 		bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
954 
955 		sc->sc_msr = bus_space_read_1(iot, ioh, com_msr);
956 		if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || DEVCUA(dev) ||
957 		    ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF))
958 			SET(tp->t_state, TS_CARR_ON);
959 		else
960 			CLR(tp->t_state, TS_CARR_ON);
961 	} else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0)
962 		return EBUSY;
963 	else
964 		s = spltty();
965 
966 	if (DEVCUA(dev)) {
967 		if (ISSET(tp->t_state, TS_ISOPEN)) {
968 			/* Ah, but someone already is dialed in... */
969 			splx(s);
970 			return EBUSY;
971 		}
972 		sc->sc_cua = 1;		/* We go into CUA mode */
973 	} else {
974 		/* tty (not cua) device; wait for carrier if necessary */
975 		if (ISSET(flag, O_NONBLOCK)) {
976 			if (sc->sc_cua) {
977 				/* Opening TTY non-blocking... but the CUA is busy */
978 				splx(s);
979 				return EBUSY;
980 			}
981 		} else {
982 			while (sc->sc_cua ||
983 			    (!ISSET(tp->t_cflag, CLOCAL) &&
984 				!ISSET(tp->t_state, TS_CARR_ON))) {
985 				SET(tp->t_state, TS_WOPEN);
986 				error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
987 				/*
988 				 * If TS_WOPEN has been reset, that means the cua device
989 				 * has been closed.  We don't want to fail in that case,
990 				 * so just go around again.
991 				 */
992 				if (error && ISSET(tp->t_state, TS_WOPEN)) {
993 					CLR(tp->t_state, TS_WOPEN);
994 					if (!sc->sc_cua && !ISSET(tp->t_state, TS_ISOPEN))
995 						compwroff(sc);
996 					splx(s);
997 					return error;
998 				}
999 			}
1000 		}
1001 	}
1002 	splx(s);
1003 
1004 	return (*linesw[tp->t_line].l_open)(dev, tp);
1005 }
1006 
1007 int
1008 comclose(dev, flag, mode, p)
1009 	dev_t dev;
1010 	int flag, mode;
1011 	struct proc *p;
1012 {
1013 	int unit = DEVUNIT(dev);
1014 	struct com_softc *sc = com_cd.cd_devs[unit];
1015 	bus_space_tag_t iot = sc->sc_iot;
1016 	bus_space_handle_t ioh = sc->sc_ioh;
1017 	struct tty *tp = sc->sc_tty;
1018 	int s;
1019 
1020 	/* XXX This is for cons.c. */
1021 	if (!ISSET(tp->t_state, TS_ISOPEN))
1022 		return 0;
1023 
1024 	(*linesw[tp->t_line].l_close)(tp, flag);
1025 	s = spltty();
1026 	if (ISSET(tp->t_state, TS_WOPEN)) {
1027 		/* tty device is waiting for carrier; drop dtr then re-raise */
1028 		CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
1029 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1030 		timeout_add(&sc->sc_dtr_tmo, hz * 2);
1031 	} else {
1032 		/* no one else waiting; turn off the uart */
1033 		compwroff(sc);
1034 	}
1035 	CLR(tp->t_state, TS_BUSY | TS_FLUSH);
1036 	if (--comsopen == 0)
1037 		timeout_del(&compoll_to);
1038 	sc->sc_cua = 0;
1039 	splx(s);
1040 	ttyclose(tp);
1041 
1042 #ifdef notyet /* XXXX */
1043 	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
1044 		ttyfree(tp);
1045 		sc->sc_tty = 0;
1046 	}
1047 #endif
1048 	return 0;
1049 }
1050 
1051 void
1052 compwroff(sc)
1053 	struct com_softc *sc;
1054 {
1055 	bus_space_tag_t iot = sc->sc_iot;
1056 	bus_space_handle_t ioh = sc->sc_ioh;
1057 	struct tty *tp = sc->sc_tty;
1058 
1059 	CLR(sc->sc_lcr, LCR_SBREAK);
1060 	bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
1061 	bus_space_write_1(iot, ioh, com_ier, 0);
1062 	if (ISSET(tp->t_cflag, HUPCL) &&
1063 	    !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
1064 		/* XXX perhaps only clear DTR */
1065 		sc->sc_mcr = 0;
1066 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1067 	}
1068 
1069 	/*
1070 	 * Turn FIFO off; enter sleep mode if possible.
1071 	 */
1072 	bus_space_write_1(iot, ioh, com_fifo, 0);
1073 	delay(100);
1074 	(void) bus_space_read_1(iot, ioh, com_data);
1075 	delay(100);
1076 	bus_space_write_1(iot, ioh, com_fifo,
1077 			  FIFO_RCV_RST | FIFO_XMT_RST);
1078 
1079 	switch (sc->sc_uarttype) {
1080 	case COM_UART_ST16650:
1081 	case COM_UART_ST16650V2:
1082 		bus_space_write_1(iot, ioh, com_lcr, 0xbf);
1083 		bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
1084 		bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
1085 		bus_space_write_1(iot, ioh, com_lcr, 0);
1086 		break;
1087 	case COM_UART_TI16750:
1088 		bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
1089 		break;
1090 	}
1091 }
1092 
1093 void
1094 com_raisedtr(arg)
1095 	void *arg;
1096 {
1097 	struct com_softc *sc = arg;
1098 
1099 	SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
1100 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
1101 }
1102 
1103 int
1104 comread(dev, uio, flag)
1105 	dev_t dev;
1106 	struct uio *uio;
1107 	int flag;
1108 {
1109 	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)];
1110 	struct tty *tp = sc->sc_tty;
1111 
1112 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
1113 }
1114 
1115 int
1116 comwrite(dev, uio, flag)
1117 	dev_t dev;
1118 	struct uio *uio;
1119 	int flag;
1120 {
1121 	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)];
1122 	struct tty *tp = sc->sc_tty;
1123 
1124 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
1125 }
1126 
1127 struct tty *
1128 comtty(dev)
1129 	dev_t dev;
1130 {
1131 	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)];
1132 	struct tty *tp = sc->sc_tty;
1133 
1134 	return (tp);
1135 }
1136 
1137 static u_char
1138 tiocm_xxx2mcr(data)
1139 	int data;
1140 {
1141 	u_char m = 0;
1142 
1143 	if (ISSET(data, TIOCM_DTR))
1144 		SET(m, MCR_DTR);
1145 	if (ISSET(data, TIOCM_RTS))
1146 		SET(m, MCR_RTS);
1147 	return m;
1148 }
1149 
1150 int
1151 comioctl(dev, cmd, data, flag, p)
1152 	dev_t dev;
1153 	u_long cmd;
1154 	caddr_t data;
1155 	int flag;
1156 	struct proc *p;
1157 {
1158 	int unit = DEVUNIT(dev);
1159 	struct com_softc *sc = com_cd.cd_devs[unit];
1160 	struct tty *tp = sc->sc_tty;
1161 	bus_space_tag_t iot = sc->sc_iot;
1162 	bus_space_handle_t ioh = sc->sc_ioh;
1163 	int error;
1164 
1165 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1166 	if (error >= 0)
1167 		return error;
1168 	error = ttioctl(tp, cmd, data, flag, p);
1169 	if (error >= 0)
1170 		return error;
1171 
1172 	switch (cmd) {
1173 	case TIOCSBRK:
1174 		SET(sc->sc_lcr, LCR_SBREAK);
1175 		bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
1176 		break;
1177 	case TIOCCBRK:
1178 		CLR(sc->sc_lcr, LCR_SBREAK);
1179 		bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
1180 		break;
1181 	case TIOCSDTR:
1182 		SET(sc->sc_mcr, sc->sc_dtr);
1183 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1184 		break;
1185 	case TIOCCDTR:
1186 		CLR(sc->sc_mcr, sc->sc_dtr);
1187 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1188 		break;
1189 	case TIOCMSET:
1190 		CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
1191 	case TIOCMBIS:
1192 		SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
1193 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1194 		break;
1195 	case TIOCMBIC:
1196 		CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
1197 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1198 		break;
1199 	case TIOCMGET: {
1200 		u_char m;
1201 		int bits = 0;
1202 
1203 		m = sc->sc_mcr;
1204 		if (ISSET(m, MCR_DTR))
1205 			SET(bits, TIOCM_DTR);
1206 		if (ISSET(m, MCR_RTS))
1207 			SET(bits, TIOCM_RTS);
1208 		m = sc->sc_msr;
1209 		if (ISSET(m, MSR_DCD))
1210 			SET(bits, TIOCM_CD);
1211 		if (ISSET(m, MSR_CTS))
1212 			SET(bits, TIOCM_CTS);
1213 		if (ISSET(m, MSR_DSR))
1214 			SET(bits, TIOCM_DSR);
1215 		if (ISSET(m, MSR_RI | MSR_TERI))
1216 			SET(bits, TIOCM_RI);
1217 		if (bus_space_read_1(iot, ioh, com_ier))
1218 			SET(bits, TIOCM_LE);
1219 		*(int *)data = bits;
1220 		break;
1221 	}
1222 	case TIOCGFLAGS: {
1223 		int driverbits, userbits = 0;
1224 
1225 		driverbits = sc->sc_swflags;
1226 		if (ISSET(driverbits, COM_SW_SOFTCAR))
1227 			SET(userbits, TIOCFLAG_SOFTCAR);
1228 		if (ISSET(driverbits, COM_SW_CLOCAL))
1229 			SET(userbits, TIOCFLAG_CLOCAL);
1230 		if (ISSET(driverbits, COM_SW_CRTSCTS))
1231 			SET(userbits, TIOCFLAG_CRTSCTS);
1232 		if (ISSET(driverbits, COM_SW_MDMBUF))
1233 			SET(userbits, TIOCFLAG_MDMBUF);
1234 		if (ISSET(driverbits, COM_SW_PPS))
1235 			SET(userbits, TIOCFLAG_PPS);
1236 
1237 		*(int *)data = userbits;
1238 		break;
1239 	}
1240 	case TIOCSFLAGS: {
1241 		int userbits, driverbits = 0;
1242 
1243 		error = suser(p->p_ucred, &p->p_acflag);
1244 		if (error != 0)
1245 			return(EPERM);
1246 
1247 		userbits = *(int *)data;
1248 		if (ISSET(userbits, TIOCFLAG_SOFTCAR) ||
1249 		    ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
1250 			SET(driverbits, COM_SW_SOFTCAR);
1251 		if (ISSET(userbits, TIOCFLAG_CLOCAL))
1252 			SET(driverbits, COM_SW_CLOCAL);
1253 		if (ISSET(userbits, TIOCFLAG_CRTSCTS))
1254 			SET(driverbits, COM_SW_CRTSCTS);
1255 		if (ISSET(userbits, TIOCFLAG_MDMBUF))
1256 			SET(driverbits, COM_SW_MDMBUF);
1257 		if (ISSET(userbits, TIOCFLAG_PPS))
1258 			SET(driverbits, COM_SW_PPS);
1259 
1260 		sc->sc_swflags = driverbits;
1261 		break;
1262 	}
1263 	default:
1264 		return ENOTTY;
1265 	}
1266 
1267 	return 0;
1268 }
1269 
1270 int
1271 comparam(tp, t)
1272 	struct tty *tp;
1273 	struct termios *t;
1274 {
1275 	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(tp->t_dev)];
1276 	bus_space_tag_t iot = sc->sc_iot;
1277 	bus_space_handle_t ioh = sc->sc_ioh;
1278 	int ospeed = comspeed(sc->sc_frequency, t->c_ospeed);
1279 	u_char lcr;
1280 	tcflag_t oldcflag;
1281 	int s;
1282 
1283 	/* check requested parameters */
1284 	if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
1285 		return EINVAL;
1286 
1287 	lcr = ISSET(sc->sc_lcr, LCR_SBREAK);
1288 
1289 	switch (ISSET(t->c_cflag, CSIZE)) {
1290 	case CS5:
1291 		SET(lcr, LCR_5BITS);
1292 		break;
1293 	case CS6:
1294 		SET(lcr, LCR_6BITS);
1295 		break;
1296 	case CS7:
1297 		SET(lcr, LCR_7BITS);
1298 		break;
1299 	case CS8:
1300 		SET(lcr, LCR_8BITS);
1301 		break;
1302 	}
1303 	if (ISSET(t->c_cflag, PARENB)) {
1304 		SET(lcr, LCR_PENAB);
1305 		if (!ISSET(t->c_cflag, PARODD))
1306 			SET(lcr, LCR_PEVEN);
1307 	}
1308 	if (ISSET(t->c_cflag, CSTOPB))
1309 		SET(lcr, LCR_STOPB);
1310 
1311 	sc->sc_lcr = lcr;
1312 
1313 	s = spltty();
1314 
1315 	if (ospeed == 0) {
1316 		CLR(sc->sc_mcr, MCR_DTR);
1317 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1318 	}
1319 
1320 	/*
1321 	 * Set the FIFO threshold based on the receive speed, if we are
1322 	 * changing it.
1323 	 */
1324 	if (sc->sc_initialize || (tp->t_ispeed != t->c_ispeed)) {
1325 		sc->sc_initialize = 0;
1326 
1327 		if (ospeed != 0) {
1328 			/*
1329 			 * Make sure the transmit FIFO is empty before
1330 			 * proceeding.  If we don't do this, some revisions
1331 			 * of the UART will hang.  Interestingly enough,
1332 			 * even if we do this while the last character is
1333 			 * still being pushed out, they don't hang.  This
1334 			 * seems good enough.
1335 			 */
1336 			while (ISSET(tp->t_state, TS_BUSY)) {
1337 				int error;
1338 
1339 				++sc->sc_halt;
1340 				error = ttysleep(tp, &tp->t_outq,
1341 				    TTOPRI | PCATCH, "comprm", 0);
1342 				--sc->sc_halt;
1343 				if (error) {
1344 					splx(s);
1345 					comstart(tp);
1346 					return (error);
1347 				}
1348 			}
1349 
1350 			bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
1351 			bus_space_write_1(iot, ioh, com_dlbl, ospeed);
1352 			bus_space_write_1(iot, ioh, com_dlbh, ospeed >> 8);
1353 			bus_space_write_1(iot, ioh, com_lcr, lcr);
1354 			SET(sc->sc_mcr, MCR_DTR);
1355 			bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1356 		} else
1357 			bus_space_write_1(iot, ioh, com_lcr, lcr);
1358 
1359 		if (!ISSET(sc->sc_hwflags, COM_HW_HAYESP) &&
1360 		    ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
1361 			if (sc->sc_uarttype == COM_UART_TI16750) {
1362 				bus_space_write_1(iot, ioh, com_lcr,
1363 				    lcr | LCR_DLAB);
1364 				bus_space_write_1(iot, ioh, com_fifo,
1365 				    FIFO_ENABLE | FIFO_ENABLE_64BYTE |
1366 				    (t->c_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8));
1367 				bus_space_write_1(iot, ioh, com_lcr, lcr);
1368 			} else
1369 				bus_space_write_1(iot, ioh, com_fifo,
1370 				    FIFO_ENABLE |
1371 				    (t->c_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8));
1372 		}
1373 	} else
1374 		bus_space_write_1(iot, ioh, com_lcr, lcr);
1375 
1376 	/* When not using CRTSCTS, RTS follows DTR. */
1377 	if (!ISSET(t->c_cflag, CRTSCTS)) {
1378 		if (ISSET(sc->sc_mcr, MCR_DTR)) {
1379 			if (!ISSET(sc->sc_mcr, MCR_RTS)) {
1380 				SET(sc->sc_mcr, MCR_RTS);
1381 				bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1382 			}
1383 		} else {
1384 			if (ISSET(sc->sc_mcr, MCR_RTS)) {
1385 				CLR(sc->sc_mcr, MCR_RTS);
1386 				bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1387 			}
1388 		}
1389 		sc->sc_dtr = MCR_DTR | MCR_RTS;
1390 	} else
1391 		sc->sc_dtr = MCR_DTR;
1392 
1393 	/* and copy to tty */
1394 	tp->t_ispeed = t->c_ispeed;
1395 	tp->t_ospeed = t->c_ospeed;
1396 	oldcflag = tp->t_cflag;
1397 	tp->t_cflag = t->c_cflag;
1398 
1399 	/*
1400 	 * If DCD is off and MDMBUF is changed, ask the tty layer if we should
1401 	 * stop the device.
1402 	 */
1403 	if (!ISSET(sc->sc_msr, MSR_DCD) &&
1404 	    !ISSET(sc->sc_swflags, COM_SW_SOFTCAR) &&
1405 	    ISSET(oldcflag, MDMBUF) != ISSET(tp->t_cflag, MDMBUF) &&
1406 	    (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
1407 		CLR(sc->sc_mcr, sc->sc_dtr);
1408 		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1409 	}
1410 
1411 	/* Just to be sure... */
1412 	splx(s);
1413 	comstart(tp);
1414 	return 0;
1415 }
1416 
1417 void
1418 comstart(tp)
1419 	struct tty *tp;
1420 {
1421 	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(tp->t_dev)];
1422 	bus_space_tag_t iot = sc->sc_iot;
1423 	bus_space_handle_t ioh = sc->sc_ioh;
1424 	int s;
1425 
1426 	s = spltty();
1427 	if (ISSET(tp->t_state, TS_BUSY))
1428 		goto out;
1429 	if (ISSET(tp->t_state, TS_TIMEOUT | TS_TTSTOP) || sc->sc_halt > 0)
1430 		goto stopped;
1431 	if (ISSET(tp->t_cflag, CRTSCTS) && !ISSET(sc->sc_msr, MSR_CTS))
1432 		goto stopped;
1433 	if (tp->t_outq.c_cc <= tp->t_lowat) {
1434 		if (ISSET(tp->t_state, TS_ASLEEP)) {
1435 			CLR(tp->t_state, TS_ASLEEP);
1436 			wakeup(&tp->t_outq);
1437 		}
1438 		if (tp->t_outq.c_cc == 0)
1439 			goto stopped;
1440 		selwakeup(&tp->t_wsel);
1441 	}
1442 	SET(tp->t_state, TS_BUSY);
1443 
1444 	if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
1445 		SET(sc->sc_ier, IER_ETXRDY);
1446 		bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1447 	}
1448 	if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
1449 #ifdef COM_HAYESP
1450 		u_char buffer[1024];	/* XXX: largest fifo */
1451 #else
1452 		u_char buffer[64];	/* XXX: largest fifo */
1453 #endif
1454 		u_char *cp = buffer;
1455 		int n = q_to_b(&tp->t_outq, cp, sc->sc_fifolen);
1456 		do {
1457 			bus_space_write_1(iot, ioh, com_data, *cp++);
1458 		} while (--n);
1459 	} else
1460 		bus_space_write_1(iot, ioh, com_data, getc(&tp->t_outq));
1461 out:
1462 	splx(s);
1463 	return;
1464 stopped:
1465 	if (ISSET(sc->sc_ier, IER_ETXRDY)) {
1466 		CLR(sc->sc_ier, IER_ETXRDY);
1467 		bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1468 	}
1469 	splx(s);
1470 }
1471 
1472 /*
1473  * Stop output on a line.
1474  */
1475 int
1476 comstop(tp, flag)
1477 	struct tty *tp;
1478 	int flag;
1479 {
1480 	int s;
1481 
1482 	s = spltty();
1483 	if (ISSET(tp->t_state, TS_BUSY))
1484 		if (!ISSET(tp->t_state, TS_TTSTOP))
1485 			SET(tp->t_state, TS_FLUSH);
1486 	splx(s);
1487 	return 0;
1488 }
1489 
1490 void
1491 comdiag(arg)
1492 	void *arg;
1493 {
1494 	struct com_softc *sc = arg;
1495 	int overflows, floods;
1496 	int s;
1497 
1498 	s = spltty();
1499 	sc->sc_errors = 0;
1500 	overflows = sc->sc_overflows;
1501 	sc->sc_overflows = 0;
1502 	floods = sc->sc_floods;
1503 	sc->sc_floods = 0;
1504 	splx(s);
1505 	log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf overflow%s\n",
1506 	    sc->sc_dev.dv_xname,
1507 	    overflows, overflows == 1 ? "" : "s",
1508 	    floods, floods == 1 ? "" : "s");
1509 }
1510 
1511 void
1512 compoll(arg)
1513 	void *arg;
1514 {
1515 	int unit;
1516 	struct com_softc *sc;
1517 	struct tty *tp;
1518 	register u_char *ibufp;
1519 	u_char *ibufend;
1520 	register int c;
1521 	int s;
1522 	static int lsrmap[8] = {
1523 		0,      TTY_PE,
1524 		TTY_FE, TTY_PE|TTY_FE,
1525 		TTY_FE, TTY_PE|TTY_FE,
1526 		TTY_FE, TTY_PE|TTY_FE
1527 	};
1528 
1529 	s = spltty();
1530 	if (comevents == 0) {
1531 		splx(s);
1532 		goto out;
1533 	}
1534 	comevents = 0;
1535 	splx(s);
1536 
1537 	for (unit = 0; unit < com_cd.cd_ndevs; unit++) {
1538 		sc = com_cd.cd_devs[unit];
1539 		if (sc == 0 || sc->sc_ibufp == sc->sc_ibuf)
1540 			continue;
1541 
1542 		tp = sc->sc_tty;
1543 
1544 		s = spltty();
1545 
1546 		ibufp = sc->sc_ibuf;
1547 		ibufend = sc->sc_ibufp;
1548 
1549 		if (ibufp == ibufend) {
1550 			splx(s);
1551 			continue;
1552 		}
1553 
1554 		sc->sc_ibufp = sc->sc_ibuf = (ibufp == sc->sc_ibufs[0]) ?
1555 					     sc->sc_ibufs[1] : sc->sc_ibufs[0];
1556 		sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER;
1557 		sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;
1558 
1559 		if (tp == 0 || !ISSET(tp->t_state, TS_ISOPEN)) {
1560 			splx(s);
1561 			continue;
1562 		}
1563 
1564 		if (ISSET(tp->t_cflag, CRTSCTS) &&
1565 		    !ISSET(sc->sc_mcr, MCR_RTS)) {
1566 			/* XXX */
1567 			SET(sc->sc_mcr, MCR_RTS);
1568 			bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr,
1569 			    sc->sc_mcr);
1570 		}
1571 
1572 		splx(s);
1573 
1574 		while (ibufp < ibufend) {
1575 			c = *ibufp++;
1576 			if (ISSET(*ibufp, LSR_OE)) {
1577 				sc->sc_overflows++;
1578 				if (sc->sc_errors++ == 0)
1579 					timeout_add(&sc->sc_diag_tmo, 60 * hz);
1580 			}
1581 			/* This is ugly, but fast. */
1582 			c |= lsrmap[(*ibufp++ & (LSR_BI|LSR_FE|LSR_PE)) >> 2];
1583 			(*linesw[tp->t_line].l_rint)(c, tp);
1584 		}
1585 	}
1586 
1587 out:
1588 	timeout_add(&compoll_to, 1);
1589 }
1590 
1591 #ifdef KGDB
1592 
1593 /*
1594  * If a line break is set, or data matches one of the characters
1595  * gdb uses to signal a connection, then start up kgdb. Just gobble
1596  * any other data. Done in a stand alone function because comintr
1597  * does tty stuff and we don't have one.
1598  */
1599 
1600 int
1601 kgdbintr(arg)
1602 	void *arg;
1603 {
1604 	struct com_softc *sc = arg;
1605 	bus_space_tag_t iot = sc->sc_iot;
1606 	bus_space_handle_t ioh = sc->sc_ioh;
1607 	u_char lsr, data, msr, delta;
1608 
1609 	if (!ISSET(sc->sc_hwflags, COM_HW_KGDB))
1610 		return(0);
1611 
1612 	for (;;) {
1613 		lsr = bus_space_read_1(iot, ioh, com_lsr);
1614 		if (ISSET(lsr, LSR_RXRDY)) {
1615 			do {
1616 				data = bus_space_read_1(iot, ioh, com_data);
1617 				if (data == 3 || data == '$' || data == '+' ||
1618 				    ISSET(lsr, LSR_BI)) {
1619 					kgdb_connect(1);
1620 					data = 0;
1621 				}
1622 				lsr = bus_space_read_1(iot, ioh, com_lsr);
1623 			} while (ISSET(lsr, LSR_RXRDY));
1624 
1625 		}
1626 		if (ISSET(lsr, LSR_BI|LSR_FE|LSR_PE|LSR_OE))
1627 			printf("weird lsr %02x\n", lsr);
1628 
1629 		msr = bus_space_read_1(iot, ioh, com_msr);
1630 
1631 		if (msr != sc->sc_msr) {
1632 			delta = msr ^ sc->sc_msr;
1633 			sc->sc_msr = msr;
1634 			if (ISSET(delta, MSR_DCD)) {
1635 				if (!ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
1636 					CLR(sc->sc_mcr, sc->sc_dtr);
1637 					bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1638 				}
1639 			}
1640 		}
1641 		if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1642 			return (1);
1643 	}
1644 }
1645 #endif /* KGDB */
1646 
1647 int
1648 comintr(arg)
1649 	void *arg;
1650 {
1651 	struct com_softc *sc = arg;
1652 	bus_space_tag_t iot = sc->sc_iot;
1653 	bus_space_handle_t ioh = sc->sc_ioh;
1654 	struct tty *tp;
1655 	u_char lsr, data, msr, delta;
1656 #ifdef PPS_SYNC
1657 	struct timeval tv;
1658 	long usec;
1659 #endif /* PPS_SYNC */
1660 #ifdef COM_DEBUG
1661 	int n;
1662 	struct {
1663 		u_char iir, lsr, msr;
1664 	} iter[32];
1665 #endif
1666 
1667 	if (!sc->sc_tty)
1668 		return (0);		/* can't do squat. */
1669 
1670 #ifdef COM_DEBUG
1671 	n = 0;
1672 	if (ISSET(iter[n].iir = bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1673 		return (0);
1674 #else
1675 	if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1676 		return (0);
1677 #endif
1678 
1679 	tp = sc->sc_tty;
1680 
1681 	for (;;) {
1682 #ifdef COM_DEBUG
1683 		iter[n].lsr =
1684 #endif
1685 		lsr = bus_space_read_1(iot, ioh, com_lsr);
1686 
1687 		if (ISSET(lsr, LSR_RXRDY)) {
1688 			register u_char *p = sc->sc_ibufp;
1689 
1690 			comevents = 1;
1691 			do {
1692 				data = bus_space_read_1(iot, ioh, com_data);
1693 				if (ISSET(lsr, LSR_BI)) {
1694 #ifdef notdef
1695 					printf("break %02x %02x %02x %02x\n",
1696 					    sc->sc_msr, sc->sc_mcr, sc->sc_lcr,
1697 					    sc->sc_dtr);
1698 #endif
1699 #ifdef DDB
1700 					if (ISSET(sc->sc_hwflags,
1701 					    COM_HW_CONSOLE)) {
1702 						if (db_console)
1703 							Debugger();
1704 						goto next;
1705 					}
1706 #endif
1707 					data = 0;
1708 				}
1709 				if (p >= sc->sc_ibufend) {
1710 					sc->sc_floods++;
1711 					if (sc->sc_errors++ == 0)
1712 						timeout_add(&sc->sc_diag_tmo, 60 * hz);
1713 				} else {
1714 					*p++ = data;
1715 					*p++ = lsr;
1716 					if (p == sc->sc_ibufhigh &&
1717 					    ISSET(tp->t_cflag, CRTSCTS)) {
1718 						/* XXX */
1719 						CLR(sc->sc_mcr, MCR_RTS);
1720 						bus_space_write_1(iot, ioh, com_mcr,
1721 						    sc->sc_mcr);
1722 					}
1723 				}
1724 #ifdef DDB
1725 			next:
1726 #endif
1727 #ifdef COM_DEBUG
1728 				if (++n >= 32)
1729 					goto ohfudge;
1730 				iter[n].lsr =
1731 #endif
1732 				lsr = bus_space_read_1(iot, ioh, com_lsr);
1733 			} while (ISSET(lsr, LSR_RXRDY));
1734 
1735 			sc->sc_ibufp = p;
1736 		}
1737 #ifdef COM_DEBUG
1738 		else if (ISSET(lsr, LSR_BI|LSR_FE|LSR_PE|LSR_OE))
1739 			printf("weird lsr %02x\n", lsr);
1740 #endif
1741 
1742 #ifdef COM_DEBUG
1743 		iter[n].msr =
1744 #endif
1745 		msr = bus_space_read_1(iot, ioh, com_msr);
1746 
1747 		if (msr != sc->sc_msr) {
1748 			delta = msr ^ sc->sc_msr;
1749 			sc->sc_msr = msr;
1750 			if (ISSET(delta, MSR_DCD)) {
1751 #ifdef PPS_SYNC
1752 				if (ISSET(sc->sc_swflags, COM_SW_PPS)) {
1753 					if (ISSET(msr, MSR_DCD)) {
1754 						usec = time.tv_usec;
1755 						microtime(&tv);
1756 						usec = tv.tv_usec - usec;
1757 						if (usec < 0)
1758 							usec += 1000000;
1759 						hardpps(&tv, usec);
1760 					}
1761 				}
1762 				else
1763 #endif /* PPS_SYNC */
1764 				if (!ISSET(sc->sc_swflags, COM_SW_SOFTCAR) &&
1765 				    (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)) == 0) {
1766 					CLR(sc->sc_mcr, sc->sc_dtr);
1767 					bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1768 				}
1769 			}
1770 			if (ISSET(delta & msr, MSR_CTS) &&
1771 			    ISSET(tp->t_cflag, CRTSCTS)) {
1772 				/* the line is up and we want to do rts/cts flow control */
1773 				(*linesw[tp->t_line].l_start)(tp);
1774 			}
1775 		}
1776 
1777 		if (ISSET(lsr, LSR_TXRDY) && ISSET(tp->t_state, TS_BUSY)) {
1778 			CLR(tp->t_state, TS_BUSY | TS_FLUSH);
1779 			if (sc->sc_halt > 0)
1780 				wakeup(&tp->t_outq);
1781 			(*linesw[tp->t_line].l_start)(tp);
1782 		}
1783 
1784 #ifdef COM_DEBUG
1785 		if (++n >= 32)
1786 			goto ohfudge;
1787 		if (ISSET(iter[n].iir = bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1788 			return (1);
1789 #else
1790 		if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1791 			return (1);
1792 #endif
1793 	}
1794 #ifdef COM_DEBUG
1795 ohfudge:
1796 	printf("comintr: too many iterations");
1797 	for (n = 0; n < 32; n++) {
1798 		if ((n % 4) == 0)
1799 			printf("\ncomintr: iter[%02d]", n);
1800 		printf("  %02x %02x %02x", iter[n].iir, iter[n].lsr, iter[n].msr);
1801 	}
1802 	printf("\n");
1803 	printf("comintr: msr %02x mcr %02x lcr %02x ier %02x\n",
1804 	    sc->sc_msr, sc->sc_mcr, sc->sc_lcr, sc->sc_ier);
1805 	printf("comintr: state %08x cc %d\n", sc->sc_tty->t_state,
1806 	    sc->sc_tty->t_outq.c_cc);
1807 #endif
1808 }
1809 
1810 /*
1811  * Following are all routines needed for COM to act as console
1812  */
1813 
1814 #if defined(arc) || defined(hppa)
1815 #undef CONADDR
1816 	extern int CONADDR;
1817 #endif
1818 
1819 void
1820 comcnprobe(cp)
1821 	struct consdev *cp;
1822 {
1823 	/* XXX NEEDS TO BE FIXED XXX */
1824 #if defined(arc)
1825 	bus_space_tag_t iot = &arc_bus_io;
1826 #elif defined(powerpc)
1827 	bus_space_tag_t iot = &ppc_isa_io;
1828 #elif defined(hppa)
1829 	bus_space_tag_t iot = &hppa_bustag;
1830 #else
1831 	bus_space_tag_t iot = 0;
1832 #endif
1833 	bus_space_handle_t ioh;
1834 	int found;
1835 
1836 	if(CONADDR == 0) {
1837 		cp->cn_pri = CN_DEAD;
1838 		return;
1839 	}
1840 
1841 	comconsiot = iot;
1842 	if (bus_space_map(iot, CONADDR, COM_NPORTS, 0, &ioh)) {
1843 		cp->cn_pri = CN_DEAD;
1844 		return;
1845 	}
1846 	found = comprobe1(iot, ioh);
1847 	bus_space_unmap(iot, ioh, COM_NPORTS);
1848 	if (!found) {
1849 		cp->cn_pri = CN_DEAD;
1850 		return;
1851 	}
1852 
1853 	/* locate the major number */
1854 	for (commajor = 0; commajor < nchrdev; commajor++)
1855 		if (cdevsw[commajor].d_open == comopen)
1856 			break;
1857 
1858 	/* initialize required fields */
1859 	cp->cn_dev = makedev(commajor, CONUNIT);
1860 #ifdef	COMCONSOLE
1861 	cp->cn_pri = CN_REMOTE;		/* Force a serial port console */
1862 #else
1863 	cp->cn_pri = CN_NORMAL;
1864 #endif
1865 }
1866 
1867 /*
1868  * The following functions are polled getc and putc routines, shared
1869  * by the console and kgdb glue.
1870  */
1871 
1872 int
1873 com_common_getc(iot, ioh)
1874 	bus_space_tag_t iot;
1875 	bus_space_handle_t ioh;
1876 {
1877 	int s = splhigh();
1878 	u_char stat, c;
1879 
1880 	/* block until a character becomes available */
1881 	while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
1882 		continue;
1883 
1884 	c = bus_space_read_1(iot, ioh, com_data);
1885 	/* clear any interrupts generated by this transmission */
1886 	stat = bus_space_read_1(iot, ioh, com_iir);
1887 	splx(s);
1888 	return (c);
1889 }
1890 
1891 void
1892 com_common_putc(iot, ioh, c)
1893 	bus_space_tag_t iot;
1894 	bus_space_handle_t ioh;
1895 	int c;
1896 {
1897 	int s = splhigh();
1898 	int timo;
1899 
1900 	/* wait for any pending transmission to finish */
1901 	timo = 150000;
1902 	while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
1903 		continue;
1904 
1905 	bus_space_write_1(iot, ioh, com_data, c);
1906 
1907 	/* wait for this transmission to complete */
1908 	timo = 1500000;
1909 	while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
1910 		continue;
1911 
1912 	splx(s);
1913 }
1914 
1915 /*
1916  * Following are all routines needed for COM to act as console
1917  */
1918 
1919 void
1920 comcninit(cp)
1921 	struct consdev *cp;
1922 {
1923 
1924 	comconsaddr = CONADDR;
1925 
1926 	if (bus_space_map(comconsiot, comconsaddr, COM_NPORTS, 0, &comconsioh))
1927 		panic("comcninit: mapping failed");
1928 
1929 	cominit(comconsiot, comconsioh, comdefaultrate);
1930 	comconsinit = 0;
1931 }
1932 
1933 void
1934 cominit(iot, ioh, rate)
1935 	bus_space_tag_t iot;
1936 	bus_space_handle_t ioh;
1937 	int rate;
1938 {
1939 	int s = splhigh();
1940 	u_char stat;
1941 
1942 	bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);
1943 	rate = comspeed(COM_FREQ, rate); /* XXX not comdefaultrate? */
1944 	bus_space_write_1(iot, ioh, com_dlbl, rate);
1945 	bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
1946 	bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS);
1947 	bus_space_write_1(iot, ioh, com_mcr, MCR_DTR | MCR_RTS);
1948 	bus_space_write_1(iot, ioh, com_ier, IER_ERXRDY | IER_ETXRDY);
1949 	bus_space_write_1(iot, ioh, com_fifo,
1950 	    FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
1951 	stat = bus_space_read_1(iot, ioh, com_iir);
1952 	splx(s);
1953 }
1954 
1955 int
1956 comcnattach(iot, iobase, rate, frequency, cflag)
1957 	bus_space_tag_t iot;
1958 	int iobase;
1959 	int rate, frequency;
1960 	tcflag_t cflag;
1961 {
1962 	static struct consdev comcons = {
1963 		NULL, NULL, comcngetc, comcnputc, comcnpollc, NULL,
1964 		NODEV, CN_NORMAL
1965 	};
1966 
1967 	if (bus_space_map(iot, iobase, COM_NPORTS, 0, &comconsioh))
1968 		return ENOMEM;
1969 
1970 	cominit(iot, comconsioh, rate);
1971 
1972 	cn_tab = &comcons;
1973 
1974 	comconsiot = iot;
1975 	comconsaddr = iobase;
1976 	comconscflag = cflag;
1977 
1978 	return (0);
1979 }
1980 
1981 int
1982 comcngetc(dev)
1983 	dev_t dev;
1984 {
1985 	return (com_common_getc(comconsiot, comconsioh));
1986 }
1987 
1988 /*
1989  * Console kernel output character routine.
1990  */
1991 void
1992 comcnputc(dev, c)
1993 	dev_t dev;
1994 	int c;
1995 {
1996 #if 0
1997 	/* XXX not needed? */
1998 	bus_space_tag_t iot = comconsiot;
1999 	bus_space_handle_t ioh = comconsioh;
2000 
2001 	if (comconsinit == 0) {
2002 		cominit(iot, ioh, comdefaultrate);
2003 		comconsinit = 1;
2004 	}
2005 #endif
2006 	com_common_putc(comconsiot, comconsioh, c);
2007 
2008 }
2009 
2010 void
2011 comcnpollc(dev, on)
2012 	dev_t dev;
2013 	int on;
2014 {
2015 
2016 }
2017 
2018 #ifdef KGDB
2019 int
2020 com_kgdb_attach(iot, iobase, rate, frequency, cflag)
2021 	bus_space_tag_t iot;
2022 	int iobase;
2023 	int rate, frequency;
2024 	tcflag_t cflag;
2025 {
2026 	if (iot == comconsiot && iobase == comconsaddr) {
2027 		return (EBUSY); /* cannot share with console */
2028 	}
2029 
2030 	com_kgdb_iot = iot;
2031 	com_kgdb_addr = iobase;
2032 
2033 	if (bus_space_map(com_kgdb_iot, com_kgdb_addr, COM_NPORTS, 0,
2034 	    &com_kgdb_ioh))
2035 		panic("com_kgdb_attach: mapping failed");
2036 
2037 	/* XXX We currently don't respect KGDBMODE? */
2038 	cominit(com_kgdb_iot, com_kgdb_ioh, rate);
2039 
2040 	kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL);
2041 	kgdb_dev = 123; /* unneeded, only to satisfy some tests */
2042 
2043 	return (0);
2044 }
2045 
2046 /* ARGSUSED */
2047 int
2048 com_kgdb_getc(arg)
2049 	void *arg;
2050 {
2051 
2052 	return (com_common_getc(com_kgdb_iot, com_kgdb_ioh));
2053 }
2054 
2055 /* ARGSUSED */
2056 void
2057 com_kgdb_putc(arg, c)
2058 	void *arg;
2059 	int c;
2060 {
2061 
2062 	return (com_common_putc(com_kgdb_iot, com_kgdb_ioh, c));
2063 }
2064 #endif /* KGDB */
2065