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