xref: /openbsd/sys/dev/pcmcia/com_pcmcia.c (revision 78b63d65)
1 /*	$OpenBSD: com_pcmcia.c,v 1.29 2001/08/17 21:52:16 deraadt Exp $	*/
2 /*	$NetBSD: com_pcmcia.c,v 1.15 1998/08/22 17:47:58 msaitoh 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) 1998 The NetBSD Foundation, Inc.
33  * All rights reserved.
34  *
35  * This code is derived from software contributed to The NetBSD Foundation
36  * by Charles M. Hannum.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the above copyright
42  *    notice, this list of conditions and the following disclaimer.
43  * 2. Redistributions in binary form must reproduce the above copyright
44  *    notice, this list of conditions and the following disclaimer in the
45  *    documentation and/or other materials provided with the distribution.
46  * 3. All advertising materials mentioning features or use of this software
47  *    must display the following acknowledgement:
48  *        This product includes software developed by the NetBSD
49  *        Foundation, Inc. and its contributors.
50  * 4. Neither the name of The NetBSD Foundation nor the names of its
51  *    contributors may be used to endorse or promote products derived
52  *    from this software without specific prior written permission.
53  *
54  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
55  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
56  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
58  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64  * POSSIBILITY OF SUCH DAMAGE.
65  */
66 
67 /*-
68  * Copyright (c) 1991 The Regents of the University of California.
69  * All rights reserved.
70  *
71  * Redistribution and use in source and binary forms, with or without
72  * modification, are permitted provided that the following conditions
73  * are met:
74  * 1. Redistributions of source code must retain the above copyright
75  *    notice, this list of conditions and the following disclaimer.
76  * 2. Redistributions in binary form must reproduce the above copyright
77  *    notice, this list of conditions and the following disclaimer in the
78  *    documentation and/or other materials provided with the distribution.
79  * 3. All advertising materials mentioning features or use of this software
80  *    must display the following acknowledgement:
81  *	This product includes software developed by the University of
82  *	California, Berkeley and its contributors.
83  * 4. Neither the name of the University nor the names of its contributors
84  *    may be used to endorse or promote products derived from this software
85  *    without specific prior written permission.
86  *
87  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
88  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
89  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
90  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
91  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
92  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
93  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
94  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
95  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
96  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
97  * SUCH DAMAGE.
98  *
99  *	@(#)com.c	7.5 (Berkeley) 5/16/91
100  */
101 
102 #include <sys/param.h>
103 #include <sys/systm.h>
104 #include <sys/ioctl.h>
105 #include <sys/select.h>
106 #include <sys/tty.h>
107 #include <sys/proc.h>
108 #include <sys/user.h>
109 #include <sys/conf.h>
110 #include <sys/file.h>
111 #include <sys/uio.h>
112 #include <sys/kernel.h>
113 #include <sys/syslog.h>
114 #include <sys/types.h>
115 #include <sys/device.h>
116 
117 #include <machine/intr.h>
118 #include <machine/bus.h>
119 
120 #include <dev/pcmcia/pcmciavar.h>
121 #include <dev/pcmcia/pcmciareg.h>
122 #include <dev/pcmcia/pcmciadevs.h>
123 
124 #include <dev/isa/isavar.h>
125 
126 #include "com.h"
127 #ifdef i386
128 #include "pccom.h"
129 #endif
130 
131 #include <dev/ic/comreg.h>
132 #if NPCCOM > 0
133 #include <i386/isa/pccomvar.h>
134 #endif
135 #if NCOM > 0
136 #include <dev/ic/comvar.h>
137 #endif
138 #include <dev/ic/ns16550reg.h>
139 
140 #include <dev/isa/isareg.h>
141 
142 #define	com_lcr		com_cfcr
143 #define	SET(t, f)	(t) |= (f)
144 
145 /* Devices that we need to match by CIS strings */
146 struct com_pcmcia_product {
147 	char *cis1_info[4];
148 } com_pcmcia_prod[] = {
149 	{ PCMCIA_CIS_MEGAHERTZ_XJ2288 },
150 };
151 
152 int com_pcmcia_match __P((struct device *, void *, void *));
153 void com_pcmcia_attach __P((struct device *, struct device *, void *));
154 int com_pcmcia_detach __P((struct device *, int));
155 void com_pcmcia_cleanup __P((void *));
156 int com_pcmcia_activate __P((struct device *, enum devact));
157 
158 int com_pcmcia_enable __P((struct com_softc *));
159 void com_pcmcia_disable __P((struct com_softc *));
160 int com_pcmcia_enable1 __P((struct com_softc *));
161 void com_pcmcia_disable1 __P((struct com_softc *));
162 
163 void com_pcmcia_attach2 __P((struct com_softc *));
164 
165 struct com_pcmcia_softc {
166 	struct com_softc sc_com;		/* real "com" softc */
167 
168 	/* PCMCIA-specific goo */
169 	struct pcmcia_io_handle sc_pcioh;	/* PCMCIA i/o space info */
170 	int sc_io_window;			/* our i/o window */
171 	struct pcmcia_function *sc_pf;		/* our PCMCIA function */
172 	void *sc_ih;				/* interrupt handler */
173 };
174 
175 #if NCOM_PCMCIA
176 struct cfattach com_pcmcia_ca = {
177 	sizeof(struct com_pcmcia_softc), com_pcmcia_match, com_pcmcia_attach,
178 	com_pcmcia_detach, com_pcmcia_activate
179 };
180 #elif NPCCOM_PCMCIA
181 struct cfattach pccom_pcmcia_ca = {
182 	sizeof(struct com_pcmcia_softc), com_pcmcia_match, com_pcmcia_attach,
183 	com_pcmcia_detach, com_pcmcia_activate
184 };
185 #endif
186 
187 int
188 com_pcmcia_match(parent, match, aux)
189 	struct device *parent;
190 	void *match, *aux;
191 {
192 	struct pcmcia_attach_args *pa = aux;
193 	struct pcmcia_config_entry *cfe;
194 	int i, j, comportmask;
195 
196 	/* 1. Does it claim to be a serial device? */
197 	if (pa->pf->function == PCMCIA_FUNCTION_SERIAL)
198 	    return 1;
199 
200 	/* 2. Does it have all four 'standard' port ranges? */
201 	comportmask = 0;
202 	for (cfe = pa->pf->cfe_head.sqh_first; cfe;
203 	     cfe = cfe->cfe_list.sqe_next) {
204 		switch (cfe->iospace[0].start) {
205 		case IO_COM1:
206 			comportmask |= 1;
207 			break;
208 		case IO_COM2:
209 			comportmask |= 2;
210 			break;
211 		case IO_COM3:
212 			comportmask |= 4;
213 			break;
214 		case IO_COM4:
215 			comportmask |= 8;
216 			break;
217 		}
218 	}
219 
220 	if (comportmask == 15)
221 		return 1;
222 
223 	/* 3. Is this a card we know about? */
224 	for (i = 0; i < sizeof(com_pcmcia_prod)/sizeof(com_pcmcia_prod[0]);
225 	    i++) {
226 		for (j = 0; j < 4; j++)
227 			if (com_pcmcia_prod[i].cis1_info[j] &&
228 			    pa->card->cis1_info[j] &&
229 			    strcmp(pa->card->cis1_info[j],
230 			    com_pcmcia_prod[i].cis1_info[j]))
231 				break;
232 		if (j == 4)
233 			return 1;
234 	}
235 
236 	return 0;
237 }
238 
239 int
240 com_pcmcia_activate(dev, act)
241 	struct device *dev;
242 	enum devact act;
243 {
244 	struct com_pcmcia_softc *sc = (void *) dev;
245 	int s;
246 
247 	s = spltty();
248 	switch (act) {
249 	case DVACT_ACTIVATE:
250 		pcmcia_function_enable(sc->sc_pf);
251 		sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_TTY,
252 		    comintr, sc, sc->sc_com.sc_dev.dv_xname);
253 		break;
254 
255 	case DVACT_DEACTIVATE:
256 		pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
257 		pcmcia_function_disable(sc->sc_pf);
258 		break;
259 	}
260 	splx(s);
261 	return (0);
262 }
263 
264 void
265 com_pcmcia_attach(parent, self, aux)
266 	struct device *parent, *self;
267 	void *aux;
268 {
269 	struct com_pcmcia_softc *psc = (void *) self;
270 	struct com_softc *sc = &psc->sc_com;
271 	struct pcmcia_attach_args *pa = aux;
272 	struct pcmcia_config_entry *cfe;
273 	int autoalloc = 0;
274 
275 	psc->sc_pf = pa->pf;
276 
277 retry:
278 	/* find a cfe we can use */
279 
280 	for (cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head); cfe;
281 	     cfe = SIMPLEQ_NEXT(cfe, cfe_list)) {
282 #if 0
283 		/*
284 		 * Some modem cards (e.g. Xircom CM33) also have
285 		 * mem space.  Don't bother with this check.
286 		 */
287 		if (cfe->num_memspace != 0)
288 			continue;
289 #endif
290 
291 		if (cfe->num_iospace != 1)
292 			continue;
293 
294 		if (!pcmcia_io_alloc(pa->pf,
295 		    autoalloc ? 0 : cfe->iospace[0].start,
296 		    cfe->iospace[0].length, COM_NPORTS, &psc->sc_pcioh)) {
297 			goto found;
298 		}
299 	}
300 	if (autoalloc == 0) {
301 		autoalloc = 1;
302 		goto retry;
303 	} else if (!cfe) {
304 		printf(": can't allocate i/o space\n");
305 		return;
306 	}
307 
308 found:
309 	sc->sc_iot = psc->sc_pcioh.iot;
310 	sc->sc_ioh = psc->sc_pcioh.ioh;
311 
312 	/* Enable the card. */
313 	pcmcia_function_init(pa->pf, cfe);
314 	if (com_pcmcia_enable1(sc))
315 		printf(": function enable failed\n");
316 
317 	sc->enabled = 1;
318 
319 	/* map in the io space */
320 
321 	if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ?
322 	    PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8), 0, psc->sc_pcioh.size,
323 	    &psc->sc_pcioh, &psc->sc_io_window)) {
324 		printf(": can't map i/o space\n");
325 		return;
326 	}
327 
328 	printf(" port 0x%lx/%d", psc->sc_pcioh.addr, psc->sc_pcioh.size);
329 
330 	sc->sc_iobase = -1;
331 	sc->enable = com_pcmcia_enable;
332 	sc->disable = com_pcmcia_disable;
333 	sc->sc_frequency = COM_FREQ;
334 
335 #ifdef notyet
336 	com_attach_subr(sc);
337 #endif
338 	/* establish the interrupt. */
339 	psc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_TTY,
340 	    comintr, sc, "");
341 	if (psc->sc_ih == NULL)
342 		printf(", couldn't establish interrupt");
343 
344 	com_pcmcia_attach2(sc);
345 
346 #ifdef notyet
347 	sc->enabled = 0;
348 
349 	com_pcmcia_disable1(sc);
350 #endif
351 }
352 
353 int
354 com_pcmcia_detach(dev, flags)
355 	struct device *dev;
356 	int flags;
357 {
358 	struct com_pcmcia_softc *psc = (struct com_pcmcia_softc *)dev;
359 	int error;
360 
361 	/* Release all resources.  */
362 	error = com_detach(dev, flags);
363 	if (error)
364 	    return (error);
365 
366 	pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
367 	pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
368 
369 	return (0);
370 }
371 
372 int
373 com_pcmcia_enable(sc)
374 	struct com_softc *sc;
375 {
376 	struct com_pcmcia_softc *psc = (struct com_pcmcia_softc *) sc;
377 	struct pcmcia_function *pf = psc->sc_pf;
378 
379 	/* establish the interrupt. */
380 	psc->sc_ih = pcmcia_intr_establish(pf, IPL_TTY, comintr, sc,
381 	    sc->sc_dev.dv_xname);
382 	if (psc->sc_ih == NULL) {
383 		printf("%s: couldn't establish interrupt\n",
384 		    sc->sc_dev.dv_xname);
385 		return (1);
386 	}
387 	return com_pcmcia_enable1(sc);
388 }
389 
390 int
391 com_pcmcia_enable1(sc)
392 	struct com_softc *sc;
393 {
394 	struct com_pcmcia_softc *psc = (struct com_pcmcia_softc *) sc;
395 	struct pcmcia_function *pf = psc->sc_pf;
396 	int ret;
397 
398 	if ((ret = pcmcia_function_enable(pf)))
399 	    return(ret);
400 
401 	if ((psc->sc_pf->sc->card.product == PCMCIA_PRODUCT_3COM_3C562) ||
402 	    (psc->sc_pf->sc->card.product == PCMCIA_PRODUCT_3COM_3CXEM556) ||
403 	    (psc->sc_pf->sc->card.product == PCMCIA_PRODUCT_3COM_3CXEM556B)) {
404 		int reg;
405 
406 		/* turn off the ethernet-disable bit */
407 
408 		reg = pcmcia_ccr_read(pf, PCMCIA_CCR_OPTION);
409 		if (reg & 0x08) {
410 		    reg &= ~0x08;
411 		    pcmcia_ccr_write(pf, PCMCIA_CCR_OPTION, reg);
412 		}
413 	}
414 
415 	return(ret);
416 }
417 
418 void
419 com_pcmcia_disable(sc)
420 	struct com_softc *sc;
421 {
422 	struct com_pcmcia_softc *psc = (struct com_pcmcia_softc *) sc;
423 
424 	pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
425 	com_pcmcia_disable1(sc);
426 }
427 
428 void
429 com_pcmcia_disable1(sc)
430 	struct com_softc *sc;
431 {
432 	struct com_pcmcia_softc *psc = (struct com_pcmcia_softc *) sc;
433 
434 	pcmcia_function_disable(psc->sc_pf);
435 }
436 
437 /*
438  * XXX This should be handled by a generic attach
439  */
440 void
441 com_pcmcia_attach2(sc)
442 	struct com_softc *sc;
443 {
444 	bus_space_tag_t iot = sc->sc_iot;
445 	bus_space_handle_t ioh = sc->sc_ioh;
446 	u_int8_t lcr;
447 
448 	sc->sc_hwflags = 0;
449 	sc->sc_swflags = 0;
450 
451 	/*
452 	 * Probe for all known forms of UART.
453 	 */
454 	lcr = bus_space_read_1(iot, ioh, com_lcr);
455 
456 	bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
457 	bus_space_write_1(iot, ioh, com_efr, 0);
458 	bus_space_write_1(iot, ioh, com_lcr, 0);
459 
460 	bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
461 	delay(100);
462 
463 	switch(bus_space_read_1(iot, ioh, com_iir) >> 6) {
464 	case 0:
465 		sc->sc_uarttype = COM_UART_16450;
466 		break;
467 	case 2:
468 		sc->sc_uarttype = COM_UART_16550;
469 		break;
470 	case 3:
471 		sc->sc_uarttype = COM_UART_16550A;
472 		break;
473 	default:
474 		sc->sc_uarttype = COM_UART_UNKNOWN;
475 		break;
476 	}
477 
478 	if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */
479 		bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
480 		if (bus_space_read_1(iot, ioh, com_efr) == 0) {
481 			sc->sc_uarttype = COM_UART_ST16650;
482 		} else {
483 			bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
484 			if (bus_space_read_1(iot, ioh, com_efr) == 0)
485 				sc->sc_uarttype = COM_UART_ST16650V2;
486 		}
487 	}
488 
489 #if NPCCOM > 0
490 #ifdef i386
491 	if (sc->sc_uarttype == COM_UART_ST16650V2) {	/* Probe for XR16850s */
492 		u_int8_t dlbl, dlbh;
493 
494 		/* Enable latch access and get the current values. */
495 		bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
496 		dlbl = bus_space_read_1(iot, ioh, com_dlbl);
497 		dlbh = bus_space_read_1(iot, ioh, com_dlbh);
498 
499 		/* Zero out the latch divisors */
500 		bus_space_write_1(iot, ioh, com_dlbl, 0);
501 		bus_space_write_1(iot, ioh, com_dlbh, 0);
502 
503 		if (bus_space_read_1(iot, ioh, com_dlbh) == 0x10) {
504 			sc->sc_uarttype = COM_UART_XR16850;
505 			sc->sc_uartrev = bus_space_read_1(iot, ioh, com_dlbl);
506 		}
507 
508 		/* Reset to original. */
509 		bus_space_write_1(iot, ioh, com_dlbl, dlbl);
510 		bus_space_write_1(iot, ioh, com_dlbh, dlbh);
511 	}
512 #endif
513 #endif
514 
515 	/* Reset the LCR (latch access is probably enabled). */
516 	bus_space_write_1(iot, ioh, com_lcr, lcr);
517 	if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */
518 		u_int8_t scr0, scr1, scr2;
519 
520 		scr0 = bus_space_read_1(iot, ioh, com_scratch);
521 		bus_space_write_1(iot, ioh, com_scratch, 0xa5);
522 		scr1 = bus_space_read_1(iot, ioh, com_scratch);
523 		bus_space_write_1(iot, ioh, com_scratch, 0x5a);
524 		scr2 = bus_space_read_1(iot, ioh, com_scratch);
525 		bus_space_write_1(iot, ioh, com_scratch, scr0);
526 
527 		if ((scr1 != 0xa5) || (scr2 != 0x5a))
528 			sc->sc_uarttype = COM_UART_8250;
529 	}
530 
531 	/*
532 	 * Print UART type and initialize ourself.
533 	 */
534 	sc->sc_fifolen = 1;	/* default */
535 	switch (sc->sc_uarttype) {
536 	case COM_UART_UNKNOWN:
537 		printf(": unknown uart\n");
538 		break;
539 	case COM_UART_8250:
540 		printf(": ns8250, no fifo\n");
541 		break;
542 	case COM_UART_16450:
543 		printf(": ns16450, no fifo\n");
544 		break;
545 	case COM_UART_16550:
546 		printf(": ns16550, no working fifo\n");
547 		break;
548 	case COM_UART_16550A:
549 		printf(": ns16550a, 16 byte fifo\n");
550 		SET(sc->sc_hwflags, COM_HW_FIFO);
551 		sc->sc_fifolen = 16;
552 		break;
553 	case COM_UART_ST16650:
554 		printf(": st16650, no working fifo\n");
555 		break;
556 	case COM_UART_ST16650V2:
557 		printf(": st16650, 32 byte fifo\n");
558 		SET(sc->sc_hwflags, COM_HW_FIFO);
559 		sc->sc_fifolen = 32;
560 		break;
561 #if NPCCOM > 0
562 #ifdef i386
563 	case COM_UART_XR16850:
564 		printf(": xr16850 (rev %d), 128 byte fifo\n", sc->sc_uartrev);
565 		SET(sc->sc_hwflags, COM_HW_FIFO);
566 		sc->sc_fifolen = 128;
567 		break;
568 #endif
569 #endif
570 	default:
571 		panic("comattach: bad fifo type");
572 	}
573 
574 	/* clear and disable fifo */
575 	bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST);
576 	(void)bus_space_read_1(iot, ioh, com_data);
577 	bus_space_write_1(iot, ioh, com_fifo, 0);
578 }
579