Home | History | Annotate | Line # | Download | only in ixp12x0
ixp12x0_com.c revision 1.2.2.2
      1 /*	$NetBSD: ixp12x0_com.c,v 1.2.2.2 2002/07/21 12:02:52 gehenna Exp $ */
      2 #undef POLLING_COM
      3 /*
      4  * Copyright (c) 1998, 1999, 2001, 2002 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Ichiro FUKUHARA and Naoto Shimazaki.
      9  *
     10  * This code is derived from software contributed to The NetBSD Foundation
     11  * by IWAMOTO Toshihiro.
     12  *
     13  * This code is derived from software contributed to The NetBSD Foundation
     14  * by Charles M. Hannum.
     15  *
     16  * Redistribution and use in source and binary forms, with or without
     17  * modification, are permitted provided that the following conditions
     18  * are met:
     19  * 1. Redistributions of source code must retain the above copyright
     20  *    notice, this list of conditions and the following disclaimer.
     21  * 2. Redistributions in binary form must reproduce the above copyright
     22  *    notice, this list of conditions and the following disclaimer in the
     23  *    documentation and/or other materials provided with the distribution.
     24  * 3. All advertising materials mentioning features or use of this software
     25  *    must display the following acknowledgement:
     26  *        This product includes software developed by the NetBSD
     27  *        Foundation, Inc. and its contributors.
     28  * 4. Neither the name of The NetBSD Foundation nor the names of its
     29  *    contributors may be used to endorse or promote products derived
     30  *    from this software without specific prior written permission.
     31  *
     32  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     33  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     34  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     35  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     36  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     37  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     38  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     39  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     40  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     41  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGE.
     43  */
     44 
     45 /*
     46  * Copyright (c) 1991 The Regents of the University of California.
     47  * All rights reserved.
     48  *
     49  * Redistribution and use in source and binary forms, with or without
     50  * modification, are permitted provided that the following conditions
     51  * are met:
     52  * 1. Redistributions of source code must retain the above copyright
     53  *    notice, this list of conditions and the following disclaimer.
     54  * 2. Redistributions in binary form must reproduce the above copyright
     55  *    notice, this list of conditions and the following disclaimer in the
     56  *    documentation and/or other materials provided with the distribution.
     57  * 3. All advertising materials mentioning features or use of this software
     58  *    must display the following acknowledgement:
     59  *      This product includes software developed by the University of
     60  *      California, Berkeley and its contributors.
     61  * 4. Neither the name of the University nor the names of its contributors
     62  *    may be used to endorse or promote products derived from this software
     63  *    without specific prior written permission.
     64  *
     65  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     66  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     67  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     68  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     69  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     70  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     71  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     72  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     73  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     74  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     75  * SUCH DAMAGE.
     76  *
     77  *      @(#)com.c       7.5 (Berkeley) 5/16/91
     78  */
     79 
     80 
     81 #include "opt_com.h"
     82 #include "opt_ddb.h"
     83 #include "opt_kgdb.h"
     84 
     85 #include "rnd.h"
     86 #if NRND > 0 && defined(RND_COM)
     87 #include <sys/rnd.h>
     88 #endif
     89 
     90 #include <sys/param.h>
     91 #include <sys/systm.h>
     92 #include <sys/types.h>
     93 #include <sys/conf.h>
     94 #include <sys/file.h>
     95 #include <sys/device.h>
     96 #include <sys/kernel.h>
     97 #include <sys/malloc.h>
     98 #include <sys/tty.h>
     99 #include <sys/uio.h>
    100 #include <sys/vnode.h>
    101 
    102 #include <machine/intr.h>
    103 #include <machine/bus.h>
    104 
    105 #include <arm/ixp12x0/ixp12x0_comreg.h>
    106 #include <arm/ixp12x0/ixp12x0_comvar.h>
    107 #include <arm/ixp12x0/ixp12x0reg.h>
    108 #include <arm/ixp12x0/ixp12x0var.h>
    109 
    110 #include <arm/ixp12x0/ixpsipvar.h>
    111 
    112 #include <dev/cons.h>
    113 #include "ixpcom.h"
    114 
    115 #if 0
    116 #ifdef POLLING_COM
    117 #undef CR_RIE
    118 #define CR_RIE 0
    119 #undef CR_XIE
    120 #define CR_XIE 0
    121 #endif
    122 
    123 #ifdef NOXIE
    124 #undef CR_XIE
    125 #define CR_XIE 0
    126 #endif
    127 #endif
    128 
    129 static int	ixpcomparam(struct tty *, struct termios *);
    130 static void	ixpcomstart(struct tty *);
    131 static int	ixpcomhwiflow(struct tty *, int);
    132 
    133 static u_int	cflag2cr(tcflag_t);
    134 static void	ixpcom_iflush(struct ixpcom_softc *);
    135 static void	ixpcom_set_cr(struct ixpcom_softc *);
    136 
    137 int             ixpcomcngetc(dev_t);
    138 void            ixpcomcnputc(dev_t, int);
    139 void            ixpcomcnpollc(dev_t, int);
    140 
    141 static void	ixpcomsoft(void* arg);
    142 inline static void	ixpcom_txsoft(struct ixpcom_softc *, struct tty *);
    143 inline static void	ixpcom_rxsoft(struct ixpcom_softc *, struct tty *);
    144 
    145 void            ixpcomcnprobe(struct consdev *);
    146 void            ixpcomcninit(struct consdev *);
    147 
    148 u_int32_t	ixpcom_cr = 0;		/* tell cr to *_intr.c */
    149 u_int32_t	ixpcom_imask = 0;	/* intrrupt mask from *_intr.c */
    150 
    151 static bus_space_tag_t ixpcomconstag;
    152 static bus_space_handle_t ixpcomconsioh;
    153 static bus_addr_t ixpcomconsaddr = IXPCOM_UART_BASE; /* XXX initial value */
    154 
    155 static int ixpcomconsattached;
    156 static int ixpcomconsrate;
    157 static tcflag_t ixpcomconscflag;
    158 static struct cnm_state ixpcom_cnm_state;
    159 
    160 extern struct cfdriver ixpcom_cd;
    161 
    162 dev_type_open(ixpcomopen);
    163 dev_type_close(ixpcomclose);
    164 dev_type_read(ixpcomread);
    165 dev_type_write(ixpcomwrite);
    166 dev_type_stop(ixpcomstop);
    167 dev_type_tty(ixpcomtty);
    168 dev_type_poll(ixpcompoll);
    169 
    170 const struct cdevsw ixpcom_cdevsw = {
    171 	ixpcomopen, ixpcomclose, ixpcomread, ixpcomwrite, nullioctl,
    172 	ixpcomstop, ixpcomtty, ixpcompoll, nommap, D_TTY
    173 };
    174 
    175 struct consdev ixpcomcons = {
    176 	NULL, NULL, ixpcomcngetc, ixpcomcnputc, ixpcomcnpollc, NULL,
    177 	NODEV, CN_NORMAL
    178 };
    179 
    180 #ifndef DEFAULT_COMSPEED
    181 #define DEFAULT_COMSPEED 38400
    182 #endif
    183 
    184 #define COMUNIT_MASK    0x7ffff
    185 #define COMDIALOUT_MASK 0x80000
    186 
    187 #define COMUNIT(x)	(minor(x) & COMUNIT_MASK)
    188 #define COMDIALOUT(x)	(minor(x) & COMDIALOUT_MASK)
    189 
    190 #define COM_ISALIVE(sc)	((sc)->enabled != 0 && \
    191 			ISSET((sc)->sc_dev.dv_flags, DVF_ACTIVE))
    192 
    193 #define COM_BARRIER(t, h, f) bus_space_barrier((t), (h), 0, COM_NPORTS, (f))
    194 
    195 #define	COM_LOCK(sc);
    196 #define	COM_UNLOCK(sc);
    197 
    198 #define SET(t, f)	(t) |= (f)
    199 #define CLR(t, f)	(t) &= ~(f)
    200 #define ISSET(t, f)	((t) & (f))
    201 
    202 #define CFLAGS2CR_MASK	(CR_PE | CR_OES | CR_SBS | CR_DSS | CR_BRD)
    203 
    204 void
    205 ixpcom_attach_subr(sc)
    206 	struct ixpcom_softc *sc;
    207 {
    208 	bus_addr_t iobase = sc->sc_baseaddr;
    209 	bus_space_tag_t iot = sc->sc_iot;
    210 	struct tty *tp;
    211 
    212 	if (iot == ixpcomconstag && iobase == ixpcomconsaddr) {
    213 		ixpcomconsattached = 1;
    214 		sc->sc_speed = IXPCOMSPEED2BRD(ixpcomconsrate);
    215 
    216 		/* Make sure the console is always "hardwired". */
    217 		delay(10000);	/* wait for output to finish */
    218 		SET(sc->sc_hwflags, COM_HW_CONSOLE);
    219 		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
    220 	}
    221 
    222 	tp = ttymalloc();
    223 	tp->t_oproc = ixpcomstart;
    224 	tp->t_param = ixpcomparam;
    225 	tp->t_hwiflow = ixpcomhwiflow;
    226 
    227 	sc->sc_tty = tp;
    228 	sc->sc_rbuf = malloc(IXPCOM_RING_SIZE << 1, M_DEVBUF, M_NOWAIT);
    229 	sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
    230 	sc->sc_rbavail = IXPCOM_RING_SIZE;
    231 	if (sc->sc_rbuf == NULL) {
    232 		printf("%s: unable to allocate ring buffer\n",
    233 		    sc->sc_dev.dv_xname);
    234 		return;
    235 	}
    236 	sc->sc_ebuf = sc->sc_rbuf + (IXPCOM_RING_SIZE << 1);
    237 	sc->sc_tbc = 0;
    238 
    239 	sc->sc_rie = sc->sc_xie = 0;
    240 	ixpcom_cr = IXPCOMSPEED2BRD(DEFAULT_COMSPEED)
    241 		| CR_UE | sc->sc_rie | sc->sc_xie | DSS_8BIT;
    242 
    243 	tty_attach(tp);
    244 
    245 	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
    246 		int maj;
    247 
    248 		/* locate the major number */
    249 		maj = cdevsw_lookup_major(&ixpcom_cdevsw);
    250 
    251 		cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
    252 
    253 		delay(10000); /* XXX */
    254 		printf("%s: console\n", sc->sc_dev.dv_xname);
    255 		delay(10000); /* XXX */
    256 	}
    257 
    258 	sc->sc_si = softintr_establish(IPL_SOFTSERIAL, ixpcomsoft, sc);
    259 
    260 #if NRND > 0 && defined(RND_COM)
    261 	rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
    262 			  RND_TYPE_TTY, 0);
    263 #endif
    264 
    265 	/* if there are no enable/disable functions, assume the device
    266 	   is always enabled */
    267 	if (!sc->enable)
    268 		sc->enabled = 1;
    269 
    270 	/* XXX configure register */
    271 	/* xxx_config(sc) */
    272 
    273 	SET(sc->sc_hwflags, COM_HW_DEV_OK);
    274 }
    275 
    276 static int
    277 ixpcomparam(tp, t)
    278 	struct tty *tp;
    279 	struct termios *t;
    280 {
    281 	struct ixpcom_softc *sc
    282 		= device_lookup(&ixpcom_cd, COMUNIT(tp->t_dev));
    283 	u_int32_t cr;
    284 	int s;
    285 
    286 	if (COM_ISALIVE(sc) == 0)
    287 		return (EIO);
    288 
    289 	cr = IXPCOMSPEED2BRD(t->c_ospeed);
    290 
    291 	if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
    292 		return (EINVAL);
    293 
    294 	/*
    295 	 * For the console, always force CLOCAL and !HUPCL, so that the port
    296 	 * is always active.
    297 	 */
    298 	if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) ||
    299 	    ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
    300 		SET(t->c_cflag, CLOCAL);
    301 		CLR(t->c_cflag, HUPCL);
    302 	}
    303 
    304 	/*
    305 	 * If there were no changes, don't do anything.  This avoids dropping
    306 	 * input and improves performance when all we did was frob things like
    307 	 * VMIN and VTIME.
    308 	 */
    309 	if (tp->t_ospeed == t->c_ospeed &&
    310 	    tp->t_cflag == t->c_cflag)
    311 		return (0);
    312 
    313 	cr |= cflag2cr(t->c_cflag);
    314 
    315 	s = splserial();
    316 	COM_LOCK(sc);
    317 
    318 	ixpcom_cr = (ixpcom_cr & ~CFLAGS2CR_MASK) | cr;
    319 
    320 	/*
    321 	 * ixpcom don't have any hardware flow control.
    322 	 * we skip it.
    323 	 */
    324 
    325 	/* And copy to tty. */
    326 	tp->t_ispeed = 0;
    327 	tp->t_ospeed = t->c_ospeed;
    328 	tp->t_cflag = t->c_cflag;
    329 
    330 	if (!sc->sc_heldchange) {
    331 		if (sc->sc_tx_busy) {
    332 			sc->sc_heldtbc = sc->sc_tbc;
    333 			sc->sc_tbc = 0;
    334 			sc->sc_heldchange = 1;
    335 		} else
    336 			ixpcom_set_cr(sc);
    337 	}
    338 
    339 	COM_UNLOCK(sc);
    340 	splx(s);
    341 
    342 	/*
    343 	 * Update the tty layer's idea of the carrier bit.
    344 	 * We tell tty the carrier is always on.
    345 	 */
    346 	(void) (*tp->t_linesw->l_modem)(tp, 1);
    347 
    348 #ifdef COM_DEBUG
    349 	if (com_debug)
    350 		comstatus(sc, "comparam ");
    351 #endif
    352 
    353 	if (!ISSET(t->c_cflag, CHWFLOW)) {
    354 		if (sc->sc_tx_stopped) {
    355 			sc->sc_tx_stopped = 0;
    356 			ixpcomstart(tp);
    357 		}
    358 	}
    359 
    360 	return (0);
    361 }
    362 
    363 static int
    364 ixpcomhwiflow(tp, block)
    365 	struct tty *tp;
    366 	int block;
    367 {
    368 	return (0);
    369 }
    370 
    371 static void
    372 ixpcom_filltx(sc)
    373 	struct ixpcom_softc *sc;
    374 {
    375 	bus_space_tag_t iot = sc->sc_iot;
    376 	bus_space_handle_t ioh = sc->sc_ioh;
    377 	int n;
    378 
    379 	n = 0;
    380         while (bus_space_read_4(iot, ioh, IXPCOM_SR) & SR_TXR) {
    381 		if (n >= sc->sc_tbc)
    382 			break;
    383 		bus_space_write_4(iot, ioh, IXPCOM_DR,
    384 				  0xff & *(sc->sc_tba + n));
    385 		n++;
    386         }
    387         sc->sc_tbc -= n;
    388         sc->sc_tba += n;
    389 }
    390 
    391 static void
    392 ixpcomstart(tp)
    393 	struct tty *tp;
    394 {
    395 	struct ixpcom_softc *sc
    396 		= device_lookup(&ixpcom_cd, COMUNIT(tp->t_dev));
    397 	int s;
    398 
    399 	if (COM_ISALIVE(sc) == 0)
    400 		return;
    401 
    402 	s = spltty();
    403 	if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
    404 		goto out;
    405 	if (sc->sc_tx_stopped)
    406 		goto out;
    407 
    408 	if (tp->t_outq.c_cc <= tp->t_lowat) {
    409 		if (ISSET(tp->t_state, TS_ASLEEP)) {
    410 			CLR(tp->t_state, TS_ASLEEP);
    411 			wakeup(&tp->t_outq);
    412 		}
    413 		selwakeup(&tp->t_wsel);
    414 		if (tp->t_outq.c_cc == 0)
    415 			goto out;
    416 	}
    417 
    418 	/* Grab the first contiguous region of buffer space. */
    419 	{
    420 		u_char *tba;
    421 		int tbc;
    422 
    423 		tba = tp->t_outq.c_cf;
    424 		tbc = ndqb(&tp->t_outq, 0);
    425 
    426 		(void)splserial();
    427 		COM_LOCK(sc);
    428 
    429 		sc->sc_tba = tba;
    430 		sc->sc_tbc = tbc;
    431 	}
    432 
    433 	SET(tp->t_state, TS_BUSY);
    434 	sc->sc_tx_busy = 1;
    435 
    436 	/* Enable transmit completion interrupts if necessary. */
    437 	if (!ISSET(sc->sc_xie, CR_XIE)) {
    438 		SET(sc->sc_xie, CR_XIE);
    439 		ixpcom_set_cr(sc);
    440 	}
    441 
    442 	/* Output the first chunk of the contiguous buffer. */
    443 	ixpcom_filltx(sc);
    444 
    445 	COM_UNLOCK(sc);
    446 out:
    447 	splx(s);
    448 	return;
    449 }
    450 
    451 static void
    452 ixpcom_break(sc, onoff)
    453 	struct ixpcom_softc *sc;
    454 	int onoff;
    455 {
    456 	if (onoff)
    457 		SET(ixpcom_cr, CR_BRK);
    458 	else
    459 		CLR(ixpcom_cr, CR_BRK);
    460 	if (!sc->sc_heldchange) {
    461 		if (sc->sc_tx_busy) {
    462 			sc->sc_heldtbc = sc->sc_tbc;
    463 			sc->sc_tbc = 0;
    464 			sc->sc_heldchange = 1;
    465 		} else
    466 			ixpcom_set_cr(sc);
    467 	}
    468 }
    469 
    470 static void
    471 ixpcom_shutdown(sc)
    472 	struct ixpcom_softc *sc;
    473 {
    474 	int s;
    475 
    476 	s = splserial();
    477 	COM_LOCK(sc);
    478 
    479 	/* Clear any break condition set with TIOCSBRK. */
    480 	ixpcom_break(sc, 0);
    481 
    482 	/* Turn off interrupts. */
    483 	sc->sc_rie = sc->sc_xie = 0;
    484 	ixpcom_set_cr(sc);
    485 
    486 	if (sc->disable) {
    487 #ifdef DIAGNOSTIC
    488 		if (!sc->enabled)
    489 			panic("ixpcom_shutdown: not enabled?");
    490 #endif
    491 		(*sc->disable)(sc);
    492 		sc->enabled = 0;
    493 	}
    494 	COM_UNLOCK(sc);
    495 	splx(s);
    496 }
    497 
    498 int
    499 ixpcomopen(dev, flag, mode, p)
    500 	dev_t dev;
    501 	int flag, mode;
    502 	struct proc *p;
    503 {
    504 	struct ixpcom_softc *sc;
    505 	struct tty *tp;
    506 	int s, s2;
    507 	int error;
    508 
    509 	sc = device_lookup(&ixpcom_cd, COMUNIT(dev));
    510 	if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK) ||
    511 		sc->sc_rbuf == NULL)
    512 		return (ENXIO);
    513 
    514 	if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
    515 		return (ENXIO);
    516 
    517 #ifdef KGDB
    518 	/*
    519 	 * If this is the kgdb port, no other use is permitted.
    520 	 */
    521 	if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
    522 		return (EBUSY);
    523 #endif
    524 
    525 	tp = sc->sc_tty;
    526 
    527 	if (ISSET(tp->t_state, TS_ISOPEN) &&
    528 	    ISSET(tp->t_state, TS_XCLUDE) &&
    529 		p->p_ucred->cr_uid != 0)
    530 		return (EBUSY);
    531 
    532 	s = spltty();
    533 
    534 	/*
    535 	 * Do the following iff this is a first open.
    536 	 */
    537 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
    538 		struct termios t;
    539 
    540 		tp->t_dev = dev;
    541 
    542 		s2 = splserial();
    543 		COM_LOCK(sc);
    544 
    545 		if (sc->enable) {
    546 			if ((*sc->enable)(sc)) {
    547 				COM_UNLOCK(sc);
    548 				splx(s2);
    549 				splx(s);
    550 				printf("%s: device enable failed\n",
    551 				       sc->sc_dev.dv_xname);
    552 				return (EIO);
    553 			}
    554 			sc->enabled = 1;
    555 #if 0
    556 /* XXXXXXXXXXXXXXX */
    557 			com_config(sc);
    558 #endif
    559 		}
    560 
    561 		/* Turn on interrupts. */
    562 		SET(sc->sc_rie, CR_RIE);
    563 		ixpcom_set_cr(sc);
    564 
    565 #if 0
    566 		/* Fetch the current modem control status, needed later. */
    567 		sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr);
    568 
    569 		/* Clear PPS capture state on first open. */
    570 		sc->sc_ppsmask = 0;
    571 		sc->ppsparam.mode = 0;
    572 #endif
    573 
    574 		COM_UNLOCK(sc);
    575 		splx(s2);
    576 
    577 		/*
    578 		 * Initialize the termios status to the defaults.  Add in the
    579 		 * sticky bits from TIOCSFLAGS.
    580 		 */
    581 		t.c_ispeed = 0;
    582 		if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
    583 			t.c_ospeed = ixpcomconsrate;
    584 			t.c_cflag = ixpcomconscflag;
    585 		} else {
    586 			t.c_ospeed = TTYDEF_SPEED;
    587 			t.c_cflag = TTYDEF_CFLAG;
    588 		}
    589 		if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
    590 			SET(t.c_cflag, CLOCAL);
    591 		if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
    592 			SET(t.c_cflag, CRTSCTS);
    593 		if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
    594 			SET(t.c_cflag, MDMBUF);
    595 		/* Make sure ixpcomparam() will do something. */
    596 		tp->t_ospeed = 0;
    597 		(void) ixpcomparam(tp, &t);
    598 		tp->t_iflag = TTYDEF_IFLAG;
    599 		tp->t_oflag = TTYDEF_OFLAG;
    600 		tp->t_lflag = TTYDEF_LFLAG;
    601 		ttychars(tp);
    602 		ttsetwater(tp);
    603 
    604 		s2 = splserial();
    605 		COM_LOCK(sc);
    606 
    607 		/* Clear the input ring, and unblock. */
    608 		sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
    609 		sc->sc_rbavail = IXPCOM_RING_SIZE;
    610 		ixpcom_iflush(sc);
    611 		CLR(sc->sc_rx_flags, RX_ANY_BLOCK);
    612 
    613 #ifdef COM_DEBUG
    614 		if (ixpcom_debug)
    615 			comstatus(sc, "ixpcomopen  ");
    616 #endif
    617 
    618 		COM_UNLOCK(sc);
    619 		splx(s2);
    620 	}
    621 
    622 	splx(s);
    623 
    624 	error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK));
    625 	if (error)
    626 		goto bad;
    627 
    628 	error = (*tp->t_linesw->l_open)(dev, tp);
    629 	if (error)
    630 		goto bad;
    631 
    632 	return (0);
    633 
    634 bad:
    635 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
    636 		/*
    637 		 * We failed to open the device, and nobody else had it opened.
    638 		 * Clean up the state as appropriate.
    639 		 */
    640 		ixpcom_shutdown(sc);
    641 	}
    642 
    643 	return (error);
    644 }
    645 
    646 int
    647 ixpcomclose(dev, flag, mode, p)
    648 	dev_t dev;
    649 	int flag, mode;
    650 	struct proc *p;
    651 {
    652 	struct ixpcom_softc *sc = device_lookup(&ixpcom_cd, COMUNIT(dev));
    653 	struct tty *tp = sc->sc_tty;
    654 
    655 	/* XXX This is for cons.c. */
    656 	if (!ISSET(tp->t_state, TS_ISOPEN))
    657 		return (0);
    658 
    659 	(*tp->t_linesw->l_close)(tp, flag);
    660 	ttyclose(tp);
    661 
    662 	if (COM_ISALIVE(sc) == 0)
    663 		return (0);
    664 
    665 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
    666 		/*
    667 		 * Although we got a last close, the device may still be in
    668 		 * use; e.g. if this was the dialout node, and there are still
    669 		 * processes waiting for carrier on the non-dialout node.
    670 		 */
    671 		ixpcom_shutdown(sc);
    672 	}
    673 
    674 	return (0);
    675 }
    676 
    677 int
    678 ixpcomread(dev, uio, flag)
    679 	dev_t dev;
    680 	struct uio *uio;
    681 	int flag;
    682 {
    683 	struct ixpcom_softc *sc = device_lookup(&ixpcom_cd, COMUNIT(dev));
    684 	struct tty *tp = sc->sc_tty;
    685 
    686 	if (COM_ISALIVE(sc) == 0)
    687 		return (EIO);
    688 
    689 	return ((*tp->t_linesw->l_read)(tp, uio, flag));
    690 }
    691 
    692 int
    693 ixpcomwrite(dev, uio, flag)
    694 	dev_t dev;
    695 	struct uio *uio;
    696 	int flag;
    697 {
    698 	struct ixpcom_softc *sc = device_lookup(&ixpcom_cd, COMUNIT(dev));
    699 	struct tty *tp = sc->sc_tty;
    700 
    701 	if (COM_ISALIVE(sc) == 0)
    702 		return (EIO);
    703 
    704 	return ((*tp->t_linesw->l_write)(tp, uio, flag));
    705 }
    706 
    707 int
    708 ixpcompoll(dev, events, p)
    709 	dev_t dev;
    710 	int events;
    711 	struct proc *p;
    712 {
    713 	struct ixpcom_softc *sc = device_lookup(&ixpcom_cd, COMUNIT(dev));
    714 	struct tty *tp = sc->sc_tty;
    715 
    716 	if (COM_ISALIVE(sc) == 0)
    717 		return (EIO);
    718 
    719 	return ((*tp->t_linesw->l_poll)(tp, events, p));
    720 }
    721 
    722 struct tty *
    723 ixpcomtty(dev)
    724 	dev_t dev;
    725 {
    726 	struct ixpcom_softc *sc = device_lookup(&ixpcom_cd, COMUNIT(dev));
    727 	struct tty *tp = sc->sc_tty;
    728 
    729 	return (tp);
    730 }
    731 
    732 /*
    733  * Stop output on a line.
    734  */
    735 void
    736 ixpcomstop(tp, flag)
    737 	struct tty *tp;
    738 	int flag;
    739 {
    740 	struct ixpcom_softc *sc
    741 		= device_lookup(&ixpcom_cd, COMUNIT(tp->t_dev));
    742 	int s;
    743 
    744 	s = splserial();
    745 	COM_LOCK(sc);
    746 	if (ISSET(tp->t_state, TS_BUSY)) {
    747 		/* Stop transmitting at the next chunk. */
    748 		sc->sc_tbc = 0;
    749 		sc->sc_heldtbc = 0;
    750 		if (!ISSET(tp->t_state, TS_TTSTOP))
    751 			SET(tp->t_state, TS_FLUSH);
    752 	}
    753 	COM_UNLOCK(sc);
    754 	splx(s);
    755 }
    756 
    757 static u_int
    758 cflag2cr(cflag)
    759 	tcflag_t cflag;
    760 {
    761 	u_int cr;
    762 
    763 	cr  = (cflag & PARENB) ? CR_PE : 0;
    764 	cr |= (cflag & PARODD) ? CR_OES : 0;
    765 	cr |= (cflag & CSTOPB) ? CR_SBS : 0;
    766 	cr |= ((cflag & CSIZE) == CS8) ? DSS_8BIT : 0;
    767 
    768 	return (cr);
    769 }
    770 
    771 static void
    772 ixpcom_iflush(sc)
    773 	struct ixpcom_softc *sc;
    774 {
    775 	bus_space_tag_t iot = sc->sc_iot;
    776 	bus_space_handle_t ioh = sc->sc_ioh;
    777 #ifdef DIAGNOSTIC
    778 	int reg;
    779 #endif
    780 	int timo;
    781 
    782 #ifdef DIAGNOSTIC
    783 	reg = 0xffff;
    784 #endif
    785 	timo = 50000;
    786 	/* flush any pending I/O */
    787 	while (ISSET(bus_space_read_4(iot, ioh, IXPCOM_SR), SR_RXR)
    788 	       && --timo)
    789 #ifdef DIAGNOSTIC
    790 		reg =
    791 #else
    792 			(void)
    793 #endif
    794 			bus_space_read_4(iot, ioh, IXPCOM_DR);
    795 #ifdef DIAGNOSTIC
    796 	if (!timo)
    797 		printf("%s: com_iflush timeout %02x\n", sc->sc_dev.dv_xname,
    798 		       reg);
    799 #endif
    800 }
    801 
    802 static void
    803 ixpcom_set_cr(sc)
    804 	struct ixpcom_softc *sc;
    805 {
    806 	/* XXX */
    807 	ixpcom_cr &= ~(CR_RIE | CR_XIE);
    808 	ixpcom_cr |= sc->sc_rie | sc->sc_xie;
    809 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXPCOM_CR,
    810 			  ixpcom_cr & ~ixpcom_imask);
    811 }
    812 
    813 /* Initialization for serial console */
    814 int
    815 ixpcominit(iot, iobase, baud, cflag, iohp)
    816 	bus_space_tag_t iot;
    817 	bus_addr_t iobase;
    818 	int baud;
    819 	tcflag_t cflag;
    820 	bus_space_handle_t *iohp;
    821 {
    822 	int cr;
    823 
    824 	if (bus_space_map(iot, iobase, IXPCOM_UART_SIZE, 0, iohp))
    825 		printf("register map failed\n");
    826 
    827 	cr = cflag2cr(cflag);
    828 	cr |= IXPCOMSPEED2BRD(baud);
    829 #if 0
    830 	cr |= (CR_UE | CR_RIE | CR_XIE);
    831 #endif
    832 	cr |= CR_UE;
    833 	ixpcom_cr = cr;
    834 
    835 	/* enable the UART */
    836 	bus_space_write_4(iot, *iohp, IXPCOM_CR, cr);
    837 
    838 	return (0);
    839 }
    840 
    841 int
    842 ixpcomcnattach(iot, iobase, rate, cflag)
    843 	bus_space_tag_t iot;
    844 	bus_addr_t iobase;
    845 	int rate;
    846 	tcflag_t cflag;
    847 {
    848 	int res;
    849 
    850 	if ((res = ixpcominit(iot, iobase, rate, cflag, &ixpcomconsioh)))
    851 		return (res);
    852 	cn_tab = &ixpcomcons;
    853 	cn_init_magic(&ixpcom_cnm_state);
    854 	/*
    855 	 * XXX
    856 	 *
    857 	 * ixpcom cannot detect a break.  It can only detect framing
    858 	 * errors.  And, a sequence of "framing error, framing error"
    859 	 * meens a break.  So I made this hack:
    860 	 *
    861 	 * 1. Set default magic is a sequence of "BREAK, BREAK".
    862 	 * 2. Tell cn_check_magic() a "framing error" as BREAK.
    863 	 *
    864 	 * see ixpcom_intr() too.
    865 	 *
    866 	 */
    867 	/* default magic is a couple of BREAK. */
    868 	cn_set_magic("\047\001\047\001");
    869 
    870 	ixpcomconstag = iot;
    871 	ixpcomconsaddr = iobase;
    872 	ixpcomconsrate = rate;
    873 	ixpcomconscflag = cflag;
    874 
    875 	return (0);
    876 }
    877 
    878 void
    879 ixpcomcninit(cp)
    880 	struct consdev *cp;
    881 {
    882 	printf("ixpcomcninit called\n");
    883 #if 0
    884 	if (cp == NULL) {
    885 		/* XXX cp == NULL means that MMU is disabled. */
    886 		ixpcomconsioh = IXPCOM_UART_BASE;
    887 		ixpcomconstag = &ixpcom_bs_tag;
    888 		cn_tab = &ixpcomcons;
    889 
    890 		IXPREG(IXPCOM_UART_BASE + IXPCOM_CR)
    891 			= IXPCOMSPEED2BRD(DEFAULT_COMSPEED)
    892 			| DSS_8BIT
    893 			| (CR_UE | CR_RIE | CR_XIE);
    894 		return;
    895 	}
    896 
    897 	if (ixpcominit(&ixpcom_bs_tag, CONADDR, CONSPEED,
    898                           CONMODE, &ixpcomconsioh))
    899 		panic("can't init serial console @%x", CONADDR);
    900 	cn_tab = &ixpcomcons;
    901 	ixpcomconstag = &ixpcom_bs_tag;
    902 #endif
    903 }
    904 
    905 void
    906 ixpcomcnprobe(cp)
    907 	struct consdev *cp;
    908 {
    909 	cp->cn_pri = CN_REMOTE;
    910 }
    911 
    912 void
    913 ixpcomcnpollc(dev, on)
    914 	dev_t dev;
    915 	int on;
    916 {
    917 }
    918 
    919 void
    920 ixpcomcnputc(dev, c)
    921 	dev_t dev;
    922 	int c;
    923 {
    924 	int s;
    925 
    926 	s = spltty();   /* XXX do we need this? */
    927 
    928 	while(!(bus_space_read_4(ixpcomconstag, ixpcomconsioh, IXPCOM_SR)
    929 	    & SR_TXR))
    930 		;
    931 
    932 	bus_space_write_4(ixpcomconstag, ixpcomconsioh, IXPCOM_DR, c);
    933 
    934 #ifdef DEBUG
    935 	if (c == '\r') {
    936 		while(!(bus_space_read_4(ixpcomconstag, ixpcomconsioh,
    937 					 IXPCOM_SR)
    938 			& SR_TXE))
    939 			;
    940 	}
    941 #endif
    942 
    943 	splx(s);
    944 }
    945 
    946 int
    947 ixpcomcngetc(dev)
    948         dev_t dev;
    949 {
    950         int c, s;
    951 
    952         s = spltty();   /* XXX do we need this? */
    953 
    954 	while(!(bus_space_read_4(ixpcomconstag, ixpcomconsioh, IXPCOM_SR)
    955 	    & SR_RXR))
    956 		;
    957 
    958 	c = bus_space_read_4(ixpcomconstag, ixpcomconsioh, IXPCOM_DR);
    959 	c &= 0xff;
    960 	splx(s);
    961 
    962 	return (c);
    963 }
    964 
    965 inline static void
    966 ixpcom_txsoft(sc, tp)
    967 	struct ixpcom_softc *sc;
    968 	struct tty *tp;
    969 {
    970 	CLR(tp->t_state, TS_BUSY);
    971 	if (ISSET(tp->t_state, TS_FLUSH))
    972 		CLR(tp->t_state, TS_FLUSH);
    973         else
    974 		ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
    975 	(*tp->t_linesw->l_start)(tp);
    976 }
    977 
    978 inline static void
    979 ixpcom_rxsoft(sc, tp)
    980 	struct ixpcom_softc *sc;
    981 	struct tty *tp;
    982 {
    983 	int (*rint) __P((int c, struct tty *tp)) = tp->t_linesw->l_rint;
    984 	u_char *get, *end;
    985 	u_int cc, scc;
    986 	u_char lsr;
    987 	int code;
    988 	int s;
    989 
    990 	end = sc->sc_ebuf;
    991 	get = sc->sc_rbget;
    992 	scc = cc = IXPCOM_RING_SIZE - sc->sc_rbavail;
    993 #if 0
    994 	if (cc == IXPCOM_RING_SIZE) {
    995 		sc->sc_floods++;
    996 		if (sc->sc_errors++ == 0)
    997 			callout_reset(&sc->sc_diag_callout, 60 * hz,
    998 			    comdiag, sc);
    999 	}
   1000 #endif
   1001 	while (cc) {
   1002 		code = get[0];
   1003 		lsr = get[1];
   1004 		if (ISSET(lsr, DR_ROR | DR_FRE | DR_PRE)) {
   1005 #if 0
   1006 			if (ISSET(lsr, DR_ROR)) {
   1007 				sc->sc_overflows++;
   1008 				if (sc->sc_errors++ == 0)
   1009 					callout_reset(&sc->sc_diag_callout,
   1010 					    60 * hz, comdiag, sc);
   1011 			}
   1012 #endif
   1013 			if (ISSET(lsr, DR_FRE))
   1014 				SET(code, TTY_FE);
   1015 			if (ISSET(lsr, DR_PRE))
   1016 				SET(code, TTY_PE);
   1017 		}
   1018 		if ((*rint)(code, tp) == -1) {
   1019 			/*
   1020 			 * The line discipline's buffer is out of space.
   1021 			 */
   1022 			if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
   1023 				/*
   1024 				 * We're either not using flow control, or the
   1025 				 * line discipline didn't tell us to block for
   1026 				 * some reason.  Either way, we have no way to
   1027 				 * know when there's more space available, so
   1028 				 * just drop the rest of the data.
   1029 				 */
   1030 				get += cc << 1;
   1031 				if (get >= end)
   1032 					get -= IXPCOM_RING_SIZE << 1;
   1033 				cc = 0;
   1034 			} else {
   1035 				/*
   1036 				 * Don't schedule any more receive processing
   1037 				 * until the line discipline tells us there's
   1038 				 * space available (through comhwiflow()).
   1039 				 * Leave the rest of the data in the input
   1040 				 * buffer.
   1041 				 */
   1042 				SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
   1043 			}
   1044 			break;
   1045 		}
   1046 		get += 2;
   1047 		if (get >= end)
   1048 			get = sc->sc_rbuf;
   1049 		cc--;
   1050 	}
   1051 
   1052 	if (cc != scc) {
   1053 		sc->sc_rbget = get;
   1054 		s = splserial();
   1055 		COM_LOCK(sc);
   1056 
   1057 		cc = sc->sc_rbavail += scc - cc;
   1058 		/* Buffers should be ok again, release possible block. */
   1059 		if (cc >= 1) {
   1060 			if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
   1061 				CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
   1062 				SET(sc->sc_rie, CR_RIE);
   1063 				ixpcom_set_cr(sc);
   1064 			}
   1065 			if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
   1066 				CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
   1067 #if 0
   1068 				com_hwiflow(sc);
   1069 #endif
   1070 			}
   1071 		}
   1072 		COM_UNLOCK(sc);
   1073 		splx(s);
   1074 	}
   1075 }
   1076 
   1077 static void
   1078 ixpcomsoft(void* arg)
   1079 {
   1080 	struct ixpcom_softc *sc = arg;
   1081 
   1082 	if (COM_ISALIVE(sc) == 0)
   1083 		return;
   1084 
   1085 	if (sc->sc_rx_ready) {
   1086 		sc->sc_rx_ready = 0;
   1087 		ixpcom_rxsoft(sc, sc->sc_tty);
   1088 	}
   1089 	if (sc->sc_tx_done) {
   1090 		sc->sc_tx_done = 0;
   1091 		ixpcom_txsoft(sc, sc->sc_tty);
   1092 	}
   1093 }
   1094 
   1095 int
   1096 ixpcomintr(void* arg)
   1097 {
   1098 	struct ixpcom_softc *sc = arg;
   1099 	bus_space_tag_t iot = sc->sc_iot;
   1100 	bus_space_handle_t ioh = sc->sc_ioh;
   1101 	u_char *put, *end;
   1102 	u_int cc;
   1103 	u_int cr;
   1104 	u_int sr;
   1105 	u_int32_t c;
   1106 
   1107 	if (COM_ISALIVE(sc) == 0)
   1108 		return (0);
   1109 
   1110 	COM_LOCK(sc);
   1111 	cr = bus_space_read_4(iot, ioh, IXPCOM_CR) & CR_UE;
   1112 
   1113 	if (!cr) {
   1114 		COM_UNLOCK(sc);
   1115 		return (0);
   1116 	}
   1117 
   1118 	sr = bus_space_read_4(iot, ioh, IXPCOM_SR);
   1119 	if (!ISSET(sr, SR_TXR | SR_RXR))
   1120 		return (0);
   1121 
   1122 	/*
   1123 	 * XXX
   1124 	 *
   1125 	 * ixpcom cannot detect a break.  It can only detect framing
   1126 	 * errors.  And, a sequence of "framing error, framing error"
   1127 	 * meens a break.  So I made this hack:
   1128 	 *
   1129 	 * 1. Set default magic is a sequence of "BREAK, BREAK".
   1130 	 * 2. Tell cn_check_magic() a "framing error" as BREAK.
   1131 	 *
   1132 	 * see ixpcomcnattach() too.
   1133 	 *
   1134 	 */
   1135 	if (ISSET(sr, SR_FRE)) {
   1136 		cn_check_magic(sc->sc_tty->t_dev,
   1137 			       CNC_BREAK, ixpcom_cnm_state);
   1138 	}
   1139 
   1140 	end = sc->sc_ebuf;
   1141 	put = sc->sc_rbput;
   1142 	cc = sc->sc_rbavail;
   1143 
   1144 	if (ISSET(sr, SR_RXR)) {
   1145 		if (!ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
   1146 			while (cc > 0) {
   1147 				if (!ISSET(sr, SR_RXR))
   1148 					break;
   1149 				c = bus_space_read_4(iot, ioh, IXPCOM_DR);
   1150 				if (ISSET(c, DR_FRE)) {
   1151 					cn_check_magic(sc->sc_tty->t_dev,
   1152 						       CNC_BREAK,
   1153 						       ixpcom_cnm_state);
   1154 				}
   1155 				put[0] = c & 0xff;
   1156 				put[1] = (c >> 8) & 0xff;
   1157 				cn_check_magic(sc->sc_tty->t_dev,
   1158 					       put[0], ixpcom_cnm_state);
   1159 				put += 2;
   1160 				if (put >= end)
   1161 					put = sc->sc_rbuf;
   1162 				cc--;
   1163 
   1164 				sr = bus_space_read_4(iot, ioh, IXPCOM_SR);
   1165 			}
   1166 
   1167 			/*
   1168 			 * Current string of incoming characters ended because
   1169 			 * no more data was available or we ran out of space.
   1170 			 * Schedule a receive event if any data was received.
   1171 			 * If we're out of space, turn off receive interrupts.
   1172 			 */
   1173 			sc->sc_rbput = put;
   1174 			sc->sc_rbavail = cc;
   1175 			if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
   1176 				sc->sc_rx_ready = 1;
   1177 
   1178 			/*
   1179 			 * See if we are in danger of overflowing a buffer. If
   1180 			 * so, use hardware flow control to ease the pressure.
   1181 			 */
   1182 
   1183 			/* but ixpcom cannot. X-( */
   1184 
   1185 			/*
   1186 			 * If we're out of space, disable receive interrupts
   1187 			 * until the queue has drained a bit.
   1188 			 */
   1189 			if (!cc) {
   1190 				SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
   1191 				CLR(sc->sc_rie, CR_RIE);
   1192 				ixpcom_set_cr(sc);
   1193 			}
   1194 		} else {
   1195 #ifdef DIAGNOSTIC
   1196 			panic("ixpcomintr: we shouldn't reach here\n");
   1197 #endif
   1198 			CLR(sc->sc_rie, CR_RIE);
   1199 			ixpcom_set_cr(sc);
   1200 		}
   1201 	}
   1202 
   1203 	/*
   1204 	 * Done handling any receive interrupts. See if data can be
   1205 	 * transmitted as well. Schedule tx done event if no data left
   1206 	 * and tty was marked busy.
   1207 	 */
   1208 	sr = bus_space_read_4(iot, ioh, IXPCOM_SR);
   1209 	if (ISSET(sr, SR_TXR)) {
   1210 		/*
   1211 		 * If we've delayed a parameter change, do it now, and restart
   1212 		 * output.
   1213 		 */
   1214 		if (sc->sc_heldchange) {
   1215 			ixpcom_set_cr(sc);
   1216 			sc->sc_heldchange = 0;
   1217 			sc->sc_tbc = sc->sc_heldtbc;
   1218 			sc->sc_heldtbc = 0;
   1219 		}
   1220 
   1221 		/* Output the next chunk of the contiguous buffer, if any. */
   1222 		if (sc->sc_tbc > 0) {
   1223 			ixpcom_filltx(sc);
   1224 		} else {
   1225 			/* Disable transmit completion interrupts if necessary. */
   1226 			if (ISSET(sc->sc_xie, CR_XIE)) {
   1227 				CLR(sc->sc_xie, CR_XIE);
   1228 				ixpcom_set_cr(sc);
   1229 			}
   1230 			if (sc->sc_tx_busy) {
   1231 				sc->sc_tx_busy = 0;
   1232 				sc->sc_tx_done = 1;
   1233 			}
   1234 		}
   1235 	}
   1236 	COM_UNLOCK(sc);
   1237 
   1238 	/* Wake up the poller. */
   1239 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
   1240 	softintr_schedule(sc->sc_si);
   1241 #else
   1242 	setsoftserial();
   1243 #endif
   1244 
   1245 #if NRND > 0 && defined(RND_COM)
   1246 	rnd_add_uint32(&sc->rnd_source, iir | lsr);
   1247 #endif
   1248 	return (1);
   1249 }
   1250 
   1251