diff --git a/sys/dev/si/si.c b/sys/dev/si/si.c index 05de593157b..ecc3955407b 100644 --- a/sys/dev/si/si.c +++ b/sys/dev/si/si.c @@ -30,7 +30,7 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHORS BE LIABLE. * - * $Id: si.c,v 1.12 1995/11/04 13:23:40 bde Exp $ + * $Id: si.c,v 1.13 1995/11/04 17:07:47 bde Exp $ */ #ifndef lint @@ -39,8 +39,6 @@ static char si_copyright1[] = "@(#) (C) Specialix International, 1990,1992", si_copyright3[] = "@(#) (C) Peter Wemm 1995"; #endif /* not lint */ -#define SI_DEBUG /* turn driver debugging on */ - #include #include #include @@ -78,8 +76,9 @@ static char si_copyright1[] = "@(#) (C) Specialix International, 1990,1992", */ #define POLL /* turn on poller to generate buffer empty interrupt */ +#undef FASTPOLL /* turn on 100Hz poller, (XXX: NOTYET!) */ #define SI_DEF_HWFLOW /* turn on default CRTSCTS flow control */ -#define SI_I_HIGH_WATER (TTYHOG - SLXOS_BUFFERSIZE) +#define SI_I_HIGH_WATER (TTYHOG - 2 * SLXOS_BUFFERSIZE) enum si_mctl { GET, SET, BIS, BIC }; @@ -101,8 +100,9 @@ extern int siprobe __P((struct isa_device *id)); extern int siattach __P((struct isa_device *id)); static void si_modem_state __P((struct si_port *pp, struct tty *tp, int hi_ip)); -#ifdef SI_DEBUG -static void si_dprintf __P((/* XXX should be varargs struct si_port *pp, int flags, char *str, int a1, int a2, int a3, int a4, int a5, int a6 */)); +#ifdef SI_DEBUG /* use: ``options "SI_DEBUG"'' in your config file */ +/* XXX: should be varargs, I know.. but where's vprintf()? */ +static void si_dprintf __P((/* struct si_port *pp, int flags, char *str, int a1, int a2, int a3, int a4, int a5, int a6 */)); static char *si_mctl2str __P((enum si_mctl cmd)); #define DPRINT(x) si_dprintf x #else @@ -115,7 +115,7 @@ static int si_debug = 0; /* data, not bss, so it's patchable */ static struct tty *si_tty; -/* where the firmware lives */ +/* where the firmware lives; defined in si_code.c */ extern int si_dsize; extern unsigned char si_download[]; @@ -135,7 +135,7 @@ struct si_softc { }; struct si_softc si_softc[NSI]; /* up to 4 elements */ -#ifndef B2000 /* not standard */ +#ifndef B2000 /* not standard, but the hardware knows it. */ # define B2000 2000 #endif static struct speedtab bdrates[] = { @@ -192,6 +192,7 @@ static int si_default_cflag = TTYDEF_CFLAG; #ifdef POLL #define POLL_INTERVAL (hz/2) static int init_finished = 0; +static int fastpoll = 0; static void si_poll __P((void *)); #endif @@ -228,6 +229,7 @@ si_registerdev(id) } si_kdc[id->id_unit].kdc_unit = id->id_unit; si_kdc[id->id_unit].kdc_isa = id; + si_kdc[id->id_unit].kdc_state = DC_UNCONFIGURED; dev_attach(&si_kdc[id->id_unit]); } @@ -257,8 +259,8 @@ siprobe(id) */ if ((caddr_t)paddr < (caddr_t)IOM_BEGIN || (caddr_t)paddr >= (caddr_t)IOM_END) { - printf("si%d: iomem (%x) out of range\n", - id->id_unit, paddr); + printf("si%d: iomem (%lx) out of range\n", + id->id_unit, (long)paddr); return(0); } @@ -375,7 +377,7 @@ got_card: for (i=0; iid_unit, paddr+i, was, i&0xff)); goto fail; } @@ -389,7 +391,7 @@ got_card: for (i=0; iid_unit, paddr+i, was)); goto fail; } @@ -446,6 +448,7 @@ siattach(id) struct tty *tp; struct speedtab *spt; int nmodule, nport, x, y; + int uart_type; DPRINT((0, DBG_AUTOBOOT, "SLXOS siattach\n")); @@ -474,8 +477,10 @@ siattach(id) break; #endif /* fall-through if not EISA */ case SI2: - /* must get around to writing the code for - * these one day */ + /* + * must get around to converting the code for + * these one day, if FreeBSD ever supports it. + */ return 0; case SIHOST: *(maddr+SIRESET_CL) = 0; @@ -509,10 +514,10 @@ siattach(id) switch (regp->initstat) { case 0: printf("si%d: startup timeout - aborting\n", unit); - sc->sc_type = NULL; + sc->sc_type = SIEMPTY; return 0; case 1: - /* set throttle to 100 intr per second */ + /* set throttle to 125 intr per second */ regp->int_count = 25000; /* rx intr max of 25 timer per second */ regp->rx_int_count = 4; @@ -539,12 +544,12 @@ siattach(id) nport = 0; modp = (struct si_module *)(maddr + 0x80); for (;;) { - DPRINT((0, DBG_DOWNLOAD, "SLXOS si%d: ccb addr 0x%x\n", unit, modp)); + DPRINT((0, DBG_DOWNLOAD, "si%d: ccb addr 0x%x\n", unit, modp)); switch (modp->sm_type & (~MMASK)) { case M232: case M422: DPRINT((0, DBG_DOWNLOAD, - "SLXOS si%d: Found 232/422 module, %d ports\n", + "si%d: Found 232/422 module, %d ports\n", unit, (int)(modp->sm_type & MMASK))); /* this is a firmware issue */ @@ -597,6 +602,7 @@ mem_fail: pp = sc->sc_ports; nmodule = 0; modp = (struct si_module *)(maddr + 0x80); + uart_type = 0; for (;;) { switch (modp->sm_type & (~MMASK)) { case M232: @@ -604,11 +610,12 @@ mem_fail: nmodule++; nport = (modp->sm_type & MMASK); ccbp = (struct si_channel *)((char *)modp+0x100); + if (uart_type == 0) + uart_type = ccbp->type; for (x = 0; x < nport; x++, pp++, ccbp++) { pp->sp_ccb = ccbp; /* save the address */ pp->sp_tty = tp++; pp->sp_pend = IDLE_CLOSE; - pp->sp_flags = 0; pp->sp_state = 0; /* internal flag */ pp->sp_dtr_wait = 3 * hz; pp->sp_iin.c_iflag = si_default_iflag; @@ -625,11 +632,12 @@ mem_fail: break; } if (modp->sm_next == 0) { - printf("si%d: card: %s, ports: %d, modules: %d\n", + printf("si%d: card: %s, ports: %d, modules: %d (type: %d)\n", unit, sc->sc_typename, sc->sc_nport, - nmodule); + nmodule, + uart_type); break; } modp = (struct si_module *) @@ -675,15 +683,15 @@ siopen(dev, flag, mode, p) return (ENXIO); sc = &si_softc[card]; - if (sc->sc_type == NULL) { - DPRINT((0, DBG_OPEN|DBG_FAIL, "SLXOS si%d: type %s??\n", + if (sc->sc_type == SIEMPTY) { + DPRINT((0, DBG_OPEN|DBG_FAIL, "si%d: type %s??\n", card, sc->sc_typename)); return(ENXIO); } port = SI_PORT(mynor); if (port >= sc->sc_nport) { - DPRINT((0, DBG_OPEN|DBG_FAIL, "SLXOS si%d: nports %d\n", + DPRINT((0, DBG_OPEN|DBG_FAIL, "si%d: nports %d\n", card, sc->sc_nport)); return(ENXIO); } @@ -1246,7 +1254,7 @@ si_Sioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) sps = (struct si_pstat *)data; card = dp->tc_card; xsc = &si_softc[card]; /* check.. */ - if (card < 0 || card >= NSI || xsc->sc_type == NULL) { + if (card < 0 || card >= NSI || xsc->sc_type == SIEMPTY) { error = ENOENT; goto out; } @@ -1504,7 +1512,6 @@ siparam(tp, t) ccbp->hi_mr1, ccbp->hi_mr2, ccbp->hi_mask, ccbp->hi_prtcl, ccbp->hi_break)); splx(oldspl); -out: return(error); } @@ -1610,6 +1617,9 @@ si_modem_state(pp, tp, hi_ip) /* * Poller to catch missed interrupts. + * + * Note that the SYSV SLXOS drivers poll at 100 times per second to get better + * response. We could really use a "periodic" version timeout(). :-) */ #ifdef POLL static void @@ -1618,7 +1628,8 @@ si_poll(void *nothing) register struct si_softc *sc; register int i; volatile struct si_reg *regp; - int lost, oldspl; + register struct si_port *pp; + int lost, oldspl, port; DPRINT((0, DBG_POLL, "si_poll()\n")); oldspl = spltty(); @@ -1627,7 +1638,7 @@ si_poll(void *nothing) lost = 0; for (i=0; isc_type == NULL) + if (sc->sc_type == SIEMPTY) continue; regp = (struct si_reg *)sc->sc_maddr; /* @@ -1638,13 +1649,24 @@ si_poll(void *nothing) if (regp->int_pending != 0) { if (regp->int_scounter >= 200 && regp->initstat == 1) { - printf("SLXOS si%d: lost intr\n", i); + printf("si%d: lost intr\n", i); lost++; } } else { regp->int_scounter = 0; } + /* + * gripe about no input flow control.. + */ + pp = sc->sc_ports; + for (port = 0; port < sc->sc_nport; pp++, port++) { + if (pp->sp_delta_overflows > 0) { + printf("si%d: %d tty level buffer overflows\n", + i, pp->sp_delta_overflows); + pp->sp_delta_overflows = 0; + } + } } if (lost) siintr(-1); /* call intr with fake vector */ @@ -1660,7 +1682,7 @@ out: * it is called. */ -static BYTE rxbuf[SLXOS_BUFFERSIZE]; /* input staging area */ +static BYTE si_rxbuf[SLXOS_BUFFERSIZE]; /* input staging area */ void siintr(int unit) @@ -1672,7 +1694,7 @@ siintr(int unit) register struct tty *tp; volatile caddr_t maddr; BYTE op, ip; - int x, card, port, n, i; + int x, card, port, n, i, isopen; volatile BYTE *z; BYTE c; @@ -1680,7 +1702,7 @@ siintr(int unit) if (in_intr) { if (unit < 0) /* should never happen */ return; - printf("SLXOS si%d: Warning interrupt handler re-entered\n", + printf("si%d: Warning interrupt handler re-entered\n", unit); return; } @@ -1693,8 +1715,12 @@ siintr(int unit) */ for (card=0; card < NSI; card++) { sc = &si_softc[card]; - if (sc->sc_type == NULL) + if (sc->sc_type == SIEMPTY) continue; + + /* + * First, clear the interrupt + */ switch(sc->sc_type) { case SIHOST : maddr = sc->sc_maddr; @@ -1722,12 +1748,14 @@ siintr(int unit) } ((volatile struct si_reg *)maddr)->int_scounter = 0; - for (pp = sc->sc_ports, port=0; - port < sc->sc_nport; - pp++, port++) { + /* + * check each port + */ + for (pp=sc->sc_ports,port=0; port < sc->sc_nport; pp++,port++) { ccbp = pp->sp_ccb; tp = pp->sp_tty; + /* * See if a command has completed ? */ @@ -1761,109 +1789,155 @@ siintr(int unit) */ si_modem_state(pp, tp, ccbp->hi_ip); + /* + * Check to see if there's we should 'receive' + * characters. + */ + if (tp->t_state & TS_CONNECTED && + tp->t_state & TS_ISOPEN) + isopen = 1; + else + isopen = 0; + /* * Do break processing */ if (ccbp->hi_state & ST_BREAK) { - if (tp->t_state & TS_CONNECTED && - tp->t_state & TS_ISOPEN) { - (*linesw[tp->t_line].l_rint)(TTY_BI, tp); + if (isopen) { + (*linesw[tp->t_line].l_rint)(TTY_BI, tp); } ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */ DPRINT((pp, DBG_INTR, "si_intr break\n")); } /* - * Do RX stuff - if not open then - * dump any characters. + * Do RX stuff - if not open then dump any characters. + * XXX: This is VERY messy and needs to be cleaned up. + * + * XXX: can we leave data in the host adapter buffer + * when the clists are full? That may be dangerous + * if the user cannot get an interrupt signal through. */ - if ((tp->t_state & TS_CONNECTED) == 0 || - (tp->t_state & TS_ISOPEN) == 0) { + more_rx: /* XXX Sorry. the nesting was driving me bats! :-( */ + + if (!isopen) { ccbp->hi_rxopos = ccbp->hi_rxipos; + goto end_rx; + } + + /* + * Process read characters if not skipped above + */ + c = ccbp->hi_rxipos - ccbp->hi_rxopos; + if (c == 0) { + goto end_rx; + } + + op = ccbp->hi_rxopos; + ip = ccbp->hi_rxipos; + n = c & 0xff; + + DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", + n, op, ip)); + + /* + * Suck characters out of host card buffer into the + * "input staging buffer" - so that we dont leave the + * host card in limbo while we're possibly echoing + * characters and possibly flushing input inside the + * ldisc l_rint() routine. + */ + if (n <= SLXOS_BUFFERSIZE - op) { + + DPRINT((pp, DBG_INTR, "\tsingle copy\n")); + z = ccbp->hi_rxbuf + op; + bcopy((caddr_t)z, si_rxbuf, n); + + op += n; } else { - while ((c = ccbp->hi_rxipos - ccbp->hi_rxopos) != 0) { + x = SLXOS_BUFFERSIZE - op; - op = ccbp->hi_rxopos; - ip = ccbp->hi_rxipos; - n = c & 0xff; + DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x)); + z = ccbp->hi_rxbuf + op; + bcopy((caddr_t)z, si_rxbuf, x); - DPRINT((pp, DBG_INTR, - "n = %d, op = %d, ip = %d\n", + DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n", n-x)); + z = ccbp->hi_rxbuf; + bcopy((caddr_t)z, si_rxbuf+x, n-x); + + op += n; + } + + /* clear collected characters from buffer */ + ccbp->hi_rxopos = op; + + DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", n, op, ip)); - if (n <= SLXOS_BUFFERSIZE - op) { - DPRINT((pp, DBG_INTR, - "\tsingle copy\n")); - z = ccbp->hi_rxbuf + op; - bcopy((caddr_t)z, rxbuf, n); + /* + * at this point... + * n = number of chars placed in si_rxbuf + */ - op += n; - } else { - x = SLXOS_BUFFERSIZE - op; + /* + * Avoid the grotesquely inefficient lineswitch + * routine (ttyinput) in "raw" mode. It usually + * takes about 450 instructions (that's without + * canonical processing or echo!). slinput is + * reasonably fast (usually 40 instructions + * plus call overhead). + */ + if (tp->t_state & TS_CAN_BYPASS_L_RINT) { - DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x)); - z = ccbp->hi_rxbuf + op; - bcopy((caddr_t)z, rxbuf, x); + /* block if the driver supports it */ + if (tp->t_rawq.c_cc + n >= SI_I_HIGH_WATER + && (tp->t_cflag & CRTS_IFLOW + || tp->t_iflag & IXOFF) + && !(tp->t_state & TS_TBLOCK)) + ttyblock(tp); - DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n", n-x)); - z = ccbp->hi_rxbuf; - bcopy((caddr_t)z, rxbuf+x, n-x); + tk_nin += n; + tk_rawcc += n; + tp->t_rawcc += n; - op += n; + pp->sp_delta_overflows += + b_to_q((char *)si_rxbuf, n, &tp->t_rawq); + + ttwakeup(tp); + if (tp->t_state & TS_TTSTOP + && (tp->t_iflag & IXANY + || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { + tp->t_state &= ~TS_TTSTOP; + tp->t_lflag &= ~FLUSHO; + si_start(tp); + } + } else { + /* + * It'd be nice to not have to go through the + * function call overhead for each char here. + * It'd be nice to block input it, saving a + * loop here and the call/return overhead. + */ + for(x = 0; x < n; x++) { + i = si_rxbuf[x]; + if ((*linesw[tp->t_line].l_rint)(i, tp) + == -1) { + pp->sp_delta_overflows++; } - - ccbp->hi_rxopos = op; - - DPRINT((pp, DBG_INTR, - "n = %d, op = %d, ip = %d\n", - n, op, ip)); - /* - * at this point... - * n = number of chars placed in rxbuf + * doesn't seem to be much point doing + * this here.. this driver has no + * softtty processing! ?? */ - /* - * Avoid the grotesquely inefficient lineswitch routine - * (ttyinput) in "raw" mode. It usually takes about 450 - * instructions (that's without canonical processing or echo!). - * slinput is reasonably fast (usually 40 instructions plus - * call overhead). - */ - if (tp->t_state & TS_CAN_BYPASS_L_RINT) { - - /* block if the driver supports it */ - if (tp->t_rawq.c_cc + n >= SI_I_HIGH_WATER - && (tp->t_cflag & CRTS_IFLOW - || tp->t_iflag & IXOFF) - && !(tp->t_state & TS_TBLOCK)) - ttyblock(tp); - - tk_nin += n; - tk_rawcc += n; - tp->t_rawcc += n; - - b_to_q((char *)rxbuf, n, &tp->t_rawq); - ttwakeup(tp); - if (tp->t_state & TS_TTSTOP - && (tp->t_iflag & IXANY - || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { - tp->t_state &= ~TS_TTSTOP; - tp->t_lflag &= ~FLUSHO; - si_start(tp); - } - } else { - for(x = 0; x < n; x++) { - i = rxbuf[x]; - (*linesw[tp->t_line].l_rint)(rxbuf[x], tp); - if (pp->sp_hotchar && i == pp->sp_hotchar) { - setsofttty(); - } - } + if (pp->sp_hotchar && i == pp->sp_hotchar) { + setsofttty(); } + } + } + goto more_rx; /* try for more until RXbuf is empty */ - } /* end of RX while */ - } /* end TS_CONNECTED */ + end_rx: /* XXX: Again, sorry about the gotos.. :-) */ /* * Do TX stuff @@ -1879,6 +1953,13 @@ siintr(int unit) /* * Nudge the transmitter... + * + * XXX: I inherited some funny code here. It implies the host card only + * interrupts when the transmit buffer reaches the low-water-mark, and does + * not interrupt when it's actually hits empty. In some cases, we have + * processes waiting for complete drain, and we need to simulate an interrupt + * about when we think the buffer is going to be empty (and retry if not). + * I really am not certain about this... I *need* the hardware manuals. */ static void si_start(tp) @@ -1975,8 +2056,8 @@ si_start(tp) else time = 2; } else { - printf("SLXOS si%d: bad char time value!!\n", - SI_CARD(tp->t_dev)); + printf("si%d: bad char time value!!\n", + (int)SI_CARD(tp->t_dev)); goto out; } } @@ -2025,7 +2106,7 @@ si_lstart(pp) /* deal with the process exit case */ ttwwakeup(tp); - /* nudge protocols */ + /* nudge protocols - eg: ppp */ (*linesw[tp->t_line].l_start)(tp); pp->sp_state &= ~SS_INLSTART; @@ -2057,7 +2138,12 @@ sistop(tp, rw) ttwwakeup(tp); /* Bruce???? */ } } -#if 0 /* this doesn't work right yet.. */ +#if 1 /* XXX: this doesn't work right yet.. */ + /* XXX: this may have been failing because we used to call l_rint() + * while we were looping based on these two counters. Now, we collect + * the data and then loop stuffing it into l_rint(), making this + * useless. Should we cause this to blow away the staging buffer? + */ if (rw & FREAD) { ccbp->hi_rxopos = ccbp->hi_rxipos; } @@ -2184,8 +2270,8 @@ si_dprintf(pp, flags, str, a1, a2, a3, a4, a5, a6) (pp != NULL && ((pp->sp_debug&flags) || (si_debug&flags)))) { if (pp != NULL) printf("SLXOS %ci%d(%d): ", 's', - SI_CARD(pp->sp_tty->t_dev), - SI_PORT(pp->sp_tty->t_dev)); + (int)SI_CARD(pp->sp_tty->t_dev), + (int)SI_PORT(pp->sp_tty->t_dev)); printf(str, a1, a2, a3, a4, a5, a6); } } diff --git a/sys/dev/si/si.h b/sys/dev/si/si.h index 9770fb63eb5..2c62fe4fc34 100644 --- a/sys/dev/si/si.h +++ b/sys/dev/si/si.h @@ -30,7 +30,7 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHORS BE LIABLE. * - * $Id: si.h,v 1.3 1995/08/22 00:42:07 peter Exp $ + * $Id: si.h,v 1.4 1995/09/13 08:39:28 peter Exp $ */ /* @@ -348,8 +348,8 @@ struct si_port { int sp_last_hi_ip; /* cached DCD */ int sp_state; int sp_active_out; /* callout is open */ - int sp_flags; int sp_dtr_wait; /* DTR holddown in hz */ + int sp_delta_overflows; u_int sp_wopeners; /* # procs waiting DCD */ u_char sp_hotchar; /* ldisc specific ASAP char */ /* Initial state. */ @@ -381,27 +381,6 @@ struct si_port { #define SS_BLOCKWRITE 0x2000 #define SS_DTR_OFF 0x4000 /* DTR held off */ -/* sp_flags */ -#define SPF_COOKMODE 0x0003 -#define SPFC_WELL 0 -#define SPFC_MEDIUM 1 -#define SPFC_RAW 2 -#define spfc_clear(pp) (pp)->sp_flags &= ~SPF_COOKMODE -#define SPF_COOK_WELL(pp) spfc_clear(pp) -#define SPF_COOK_MEDIUM(pp) {spfc_clear(pp);(pp)->sp_flags|=SPFC_MEDIUM;} -#define SPF_COOK_RAW(pp) {spfc_clear(pp);(pp)->sp_flags|=SPFC_RAW;} -#define SPF_SETCOOK(pp, c) {spfc_clear(pp);(pp)->sp_flags|=(c);} -#define SPF_ISCOOKWELL(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_WELL) -#define SPF_ISCOOKMEDIUM(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_MEDIUM) -#define SPF_ISCOOKRAW(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_RAW) -#define SPF_COOKWELL_ALWAYS 0x0004 /* always use line disc */ -/* 0x0008 */ -#define SPF_IXANY 0x0020 /* IXANY enable/disable flag */ -#define SPF_CTSOFLOW 0x0040 /* use CTS to handle o/p flow */ -#define SPF_RTSIFLOW 0x0080 /* use RTS to handle i/p flow */ -#define SPF_PPP 0x0100 /* special handling for upper - * level protocol code */ - /* * Command post flags */ @@ -479,13 +458,10 @@ struct si_pstat { /* 101 defunct */ /* 102 defunct */ /* 103 defunct */ -#define TCSIIXANY _IOW('S', 103, struct si_tcsi) /* enable ixany */ /* 104 defunct */ #define TCSISTATE _IOWR('S', 105, struct si_tcsi) /* get current state of RTS DCD and DTR pins */ - /* Set/reset/enquire cook mode, 1 = always use line disc - * -1 = enquire current setting */ -#define TCSICOOKMODE _IOWR('S', 106, struct si_tcsi) + /* 106 defunct */ #define TCSIPORTS _IOR('S', 107, int) /* Number of ports found */ #define TCSISDBG_LEVEL _IOW('S', 108, struct si_tcsi) /* equivalent of TCSIDEBUG which sets a * particular debug level (DBG_??? bit @@ -498,17 +474,15 @@ struct si_pstat { /* 114 defunct */ /* 115 defunct */ /* 116 defunct */ -#define TCSIMODEM _IOWR('S', 117, struct si_tcsi) /* set/clear/query the modem bit */ + /* 117 defunct */ #define TCSISDBG_ALL _IOW('S', 118, int) /* set global debug level */ #define TCSIGDBG_ALL _IOR('S', 119, int) /* get global debug level */ -#define TCSIFLOW _IOWR('S', 120, struct si_tcsi) /* set/get h/w flow state */ + /* 120 defunct */ /* 121 defunct */ /* 122 defunct */ - - -#define TCSIPPP _IOWR('S', 123, struct si_tcsi) /* set/get PPP flag bit */ + /* 123 defunct */ #define TCSIMODULES _IOR('S', 124, int) /* Number of modules found */ /* Various stats and monitoring hooks per tty device */ diff --git a/sys/i386/include/si.h b/sys/i386/include/si.h index 9770fb63eb5..2c62fe4fc34 100644 --- a/sys/i386/include/si.h +++ b/sys/i386/include/si.h @@ -30,7 +30,7 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHORS BE LIABLE. * - * $Id: si.h,v 1.3 1995/08/22 00:42:07 peter Exp $ + * $Id: si.h,v 1.4 1995/09/13 08:39:28 peter Exp $ */ /* @@ -348,8 +348,8 @@ struct si_port { int sp_last_hi_ip; /* cached DCD */ int sp_state; int sp_active_out; /* callout is open */ - int sp_flags; int sp_dtr_wait; /* DTR holddown in hz */ + int sp_delta_overflows; u_int sp_wopeners; /* # procs waiting DCD */ u_char sp_hotchar; /* ldisc specific ASAP char */ /* Initial state. */ @@ -381,27 +381,6 @@ struct si_port { #define SS_BLOCKWRITE 0x2000 #define SS_DTR_OFF 0x4000 /* DTR held off */ -/* sp_flags */ -#define SPF_COOKMODE 0x0003 -#define SPFC_WELL 0 -#define SPFC_MEDIUM 1 -#define SPFC_RAW 2 -#define spfc_clear(pp) (pp)->sp_flags &= ~SPF_COOKMODE -#define SPF_COOK_WELL(pp) spfc_clear(pp) -#define SPF_COOK_MEDIUM(pp) {spfc_clear(pp);(pp)->sp_flags|=SPFC_MEDIUM;} -#define SPF_COOK_RAW(pp) {spfc_clear(pp);(pp)->sp_flags|=SPFC_RAW;} -#define SPF_SETCOOK(pp, c) {spfc_clear(pp);(pp)->sp_flags|=(c);} -#define SPF_ISCOOKWELL(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_WELL) -#define SPF_ISCOOKMEDIUM(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_MEDIUM) -#define SPF_ISCOOKRAW(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_RAW) -#define SPF_COOKWELL_ALWAYS 0x0004 /* always use line disc */ -/* 0x0008 */ -#define SPF_IXANY 0x0020 /* IXANY enable/disable flag */ -#define SPF_CTSOFLOW 0x0040 /* use CTS to handle o/p flow */ -#define SPF_RTSIFLOW 0x0080 /* use RTS to handle i/p flow */ -#define SPF_PPP 0x0100 /* special handling for upper - * level protocol code */ - /* * Command post flags */ @@ -479,13 +458,10 @@ struct si_pstat { /* 101 defunct */ /* 102 defunct */ /* 103 defunct */ -#define TCSIIXANY _IOW('S', 103, struct si_tcsi) /* enable ixany */ /* 104 defunct */ #define TCSISTATE _IOWR('S', 105, struct si_tcsi) /* get current state of RTS DCD and DTR pins */ - /* Set/reset/enquire cook mode, 1 = always use line disc - * -1 = enquire current setting */ -#define TCSICOOKMODE _IOWR('S', 106, struct si_tcsi) + /* 106 defunct */ #define TCSIPORTS _IOR('S', 107, int) /* Number of ports found */ #define TCSISDBG_LEVEL _IOW('S', 108, struct si_tcsi) /* equivalent of TCSIDEBUG which sets a * particular debug level (DBG_??? bit @@ -498,17 +474,15 @@ struct si_pstat { /* 114 defunct */ /* 115 defunct */ /* 116 defunct */ -#define TCSIMODEM _IOWR('S', 117, struct si_tcsi) /* set/clear/query the modem bit */ + /* 117 defunct */ #define TCSISDBG_ALL _IOW('S', 118, int) /* set global debug level */ #define TCSIGDBG_ALL _IOR('S', 119, int) /* get global debug level */ -#define TCSIFLOW _IOWR('S', 120, struct si_tcsi) /* set/get h/w flow state */ + /* 120 defunct */ /* 121 defunct */ /* 122 defunct */ - - -#define TCSIPPP _IOWR('S', 123, struct si_tcsi) /* set/get PPP flag bit */ + /* 123 defunct */ #define TCSIMODULES _IOR('S', 124, int) /* Number of modules found */ /* Various stats and monitoring hooks per tty device */ diff --git a/sys/i386/isa/si.c b/sys/i386/isa/si.c index 05de593157b..ecc3955407b 100644 --- a/sys/i386/isa/si.c +++ b/sys/i386/isa/si.c @@ -30,7 +30,7 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHORS BE LIABLE. * - * $Id: si.c,v 1.12 1995/11/04 13:23:40 bde Exp $ + * $Id: si.c,v 1.13 1995/11/04 17:07:47 bde Exp $ */ #ifndef lint @@ -39,8 +39,6 @@ static char si_copyright1[] = "@(#) (C) Specialix International, 1990,1992", si_copyright3[] = "@(#) (C) Peter Wemm 1995"; #endif /* not lint */ -#define SI_DEBUG /* turn driver debugging on */ - #include #include #include @@ -78,8 +76,9 @@ static char si_copyright1[] = "@(#) (C) Specialix International, 1990,1992", */ #define POLL /* turn on poller to generate buffer empty interrupt */ +#undef FASTPOLL /* turn on 100Hz poller, (XXX: NOTYET!) */ #define SI_DEF_HWFLOW /* turn on default CRTSCTS flow control */ -#define SI_I_HIGH_WATER (TTYHOG - SLXOS_BUFFERSIZE) +#define SI_I_HIGH_WATER (TTYHOG - 2 * SLXOS_BUFFERSIZE) enum si_mctl { GET, SET, BIS, BIC }; @@ -101,8 +100,9 @@ extern int siprobe __P((struct isa_device *id)); extern int siattach __P((struct isa_device *id)); static void si_modem_state __P((struct si_port *pp, struct tty *tp, int hi_ip)); -#ifdef SI_DEBUG -static void si_dprintf __P((/* XXX should be varargs struct si_port *pp, int flags, char *str, int a1, int a2, int a3, int a4, int a5, int a6 */)); +#ifdef SI_DEBUG /* use: ``options "SI_DEBUG"'' in your config file */ +/* XXX: should be varargs, I know.. but where's vprintf()? */ +static void si_dprintf __P((/* struct si_port *pp, int flags, char *str, int a1, int a2, int a3, int a4, int a5, int a6 */)); static char *si_mctl2str __P((enum si_mctl cmd)); #define DPRINT(x) si_dprintf x #else @@ -115,7 +115,7 @@ static int si_debug = 0; /* data, not bss, so it's patchable */ static struct tty *si_tty; -/* where the firmware lives */ +/* where the firmware lives; defined in si_code.c */ extern int si_dsize; extern unsigned char si_download[]; @@ -135,7 +135,7 @@ struct si_softc { }; struct si_softc si_softc[NSI]; /* up to 4 elements */ -#ifndef B2000 /* not standard */ +#ifndef B2000 /* not standard, but the hardware knows it. */ # define B2000 2000 #endif static struct speedtab bdrates[] = { @@ -192,6 +192,7 @@ static int si_default_cflag = TTYDEF_CFLAG; #ifdef POLL #define POLL_INTERVAL (hz/2) static int init_finished = 0; +static int fastpoll = 0; static void si_poll __P((void *)); #endif @@ -228,6 +229,7 @@ si_registerdev(id) } si_kdc[id->id_unit].kdc_unit = id->id_unit; si_kdc[id->id_unit].kdc_isa = id; + si_kdc[id->id_unit].kdc_state = DC_UNCONFIGURED; dev_attach(&si_kdc[id->id_unit]); } @@ -257,8 +259,8 @@ siprobe(id) */ if ((caddr_t)paddr < (caddr_t)IOM_BEGIN || (caddr_t)paddr >= (caddr_t)IOM_END) { - printf("si%d: iomem (%x) out of range\n", - id->id_unit, paddr); + printf("si%d: iomem (%lx) out of range\n", + id->id_unit, (long)paddr); return(0); } @@ -375,7 +377,7 @@ got_card: for (i=0; iid_unit, paddr+i, was, i&0xff)); goto fail; } @@ -389,7 +391,7 @@ got_card: for (i=0; iid_unit, paddr+i, was)); goto fail; } @@ -446,6 +448,7 @@ siattach(id) struct tty *tp; struct speedtab *spt; int nmodule, nport, x, y; + int uart_type; DPRINT((0, DBG_AUTOBOOT, "SLXOS siattach\n")); @@ -474,8 +477,10 @@ siattach(id) break; #endif /* fall-through if not EISA */ case SI2: - /* must get around to writing the code for - * these one day */ + /* + * must get around to converting the code for + * these one day, if FreeBSD ever supports it. + */ return 0; case SIHOST: *(maddr+SIRESET_CL) = 0; @@ -509,10 +514,10 @@ siattach(id) switch (regp->initstat) { case 0: printf("si%d: startup timeout - aborting\n", unit); - sc->sc_type = NULL; + sc->sc_type = SIEMPTY; return 0; case 1: - /* set throttle to 100 intr per second */ + /* set throttle to 125 intr per second */ regp->int_count = 25000; /* rx intr max of 25 timer per second */ regp->rx_int_count = 4; @@ -539,12 +544,12 @@ siattach(id) nport = 0; modp = (struct si_module *)(maddr + 0x80); for (;;) { - DPRINT((0, DBG_DOWNLOAD, "SLXOS si%d: ccb addr 0x%x\n", unit, modp)); + DPRINT((0, DBG_DOWNLOAD, "si%d: ccb addr 0x%x\n", unit, modp)); switch (modp->sm_type & (~MMASK)) { case M232: case M422: DPRINT((0, DBG_DOWNLOAD, - "SLXOS si%d: Found 232/422 module, %d ports\n", + "si%d: Found 232/422 module, %d ports\n", unit, (int)(modp->sm_type & MMASK))); /* this is a firmware issue */ @@ -597,6 +602,7 @@ mem_fail: pp = sc->sc_ports; nmodule = 0; modp = (struct si_module *)(maddr + 0x80); + uart_type = 0; for (;;) { switch (modp->sm_type & (~MMASK)) { case M232: @@ -604,11 +610,12 @@ mem_fail: nmodule++; nport = (modp->sm_type & MMASK); ccbp = (struct si_channel *)((char *)modp+0x100); + if (uart_type == 0) + uart_type = ccbp->type; for (x = 0; x < nport; x++, pp++, ccbp++) { pp->sp_ccb = ccbp; /* save the address */ pp->sp_tty = tp++; pp->sp_pend = IDLE_CLOSE; - pp->sp_flags = 0; pp->sp_state = 0; /* internal flag */ pp->sp_dtr_wait = 3 * hz; pp->sp_iin.c_iflag = si_default_iflag; @@ -625,11 +632,12 @@ mem_fail: break; } if (modp->sm_next == 0) { - printf("si%d: card: %s, ports: %d, modules: %d\n", + printf("si%d: card: %s, ports: %d, modules: %d (type: %d)\n", unit, sc->sc_typename, sc->sc_nport, - nmodule); + nmodule, + uart_type); break; } modp = (struct si_module *) @@ -675,15 +683,15 @@ siopen(dev, flag, mode, p) return (ENXIO); sc = &si_softc[card]; - if (sc->sc_type == NULL) { - DPRINT((0, DBG_OPEN|DBG_FAIL, "SLXOS si%d: type %s??\n", + if (sc->sc_type == SIEMPTY) { + DPRINT((0, DBG_OPEN|DBG_FAIL, "si%d: type %s??\n", card, sc->sc_typename)); return(ENXIO); } port = SI_PORT(mynor); if (port >= sc->sc_nport) { - DPRINT((0, DBG_OPEN|DBG_FAIL, "SLXOS si%d: nports %d\n", + DPRINT((0, DBG_OPEN|DBG_FAIL, "si%d: nports %d\n", card, sc->sc_nport)); return(ENXIO); } @@ -1246,7 +1254,7 @@ si_Sioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) sps = (struct si_pstat *)data; card = dp->tc_card; xsc = &si_softc[card]; /* check.. */ - if (card < 0 || card >= NSI || xsc->sc_type == NULL) { + if (card < 0 || card >= NSI || xsc->sc_type == SIEMPTY) { error = ENOENT; goto out; } @@ -1504,7 +1512,6 @@ siparam(tp, t) ccbp->hi_mr1, ccbp->hi_mr2, ccbp->hi_mask, ccbp->hi_prtcl, ccbp->hi_break)); splx(oldspl); -out: return(error); } @@ -1610,6 +1617,9 @@ si_modem_state(pp, tp, hi_ip) /* * Poller to catch missed interrupts. + * + * Note that the SYSV SLXOS drivers poll at 100 times per second to get better + * response. We could really use a "periodic" version timeout(). :-) */ #ifdef POLL static void @@ -1618,7 +1628,8 @@ si_poll(void *nothing) register struct si_softc *sc; register int i; volatile struct si_reg *regp; - int lost, oldspl; + register struct si_port *pp; + int lost, oldspl, port; DPRINT((0, DBG_POLL, "si_poll()\n")); oldspl = spltty(); @@ -1627,7 +1638,7 @@ si_poll(void *nothing) lost = 0; for (i=0; isc_type == NULL) + if (sc->sc_type == SIEMPTY) continue; regp = (struct si_reg *)sc->sc_maddr; /* @@ -1638,13 +1649,24 @@ si_poll(void *nothing) if (regp->int_pending != 0) { if (regp->int_scounter >= 200 && regp->initstat == 1) { - printf("SLXOS si%d: lost intr\n", i); + printf("si%d: lost intr\n", i); lost++; } } else { regp->int_scounter = 0; } + /* + * gripe about no input flow control.. + */ + pp = sc->sc_ports; + for (port = 0; port < sc->sc_nport; pp++, port++) { + if (pp->sp_delta_overflows > 0) { + printf("si%d: %d tty level buffer overflows\n", + i, pp->sp_delta_overflows); + pp->sp_delta_overflows = 0; + } + } } if (lost) siintr(-1); /* call intr with fake vector */ @@ -1660,7 +1682,7 @@ out: * it is called. */ -static BYTE rxbuf[SLXOS_BUFFERSIZE]; /* input staging area */ +static BYTE si_rxbuf[SLXOS_BUFFERSIZE]; /* input staging area */ void siintr(int unit) @@ -1672,7 +1694,7 @@ siintr(int unit) register struct tty *tp; volatile caddr_t maddr; BYTE op, ip; - int x, card, port, n, i; + int x, card, port, n, i, isopen; volatile BYTE *z; BYTE c; @@ -1680,7 +1702,7 @@ siintr(int unit) if (in_intr) { if (unit < 0) /* should never happen */ return; - printf("SLXOS si%d: Warning interrupt handler re-entered\n", + printf("si%d: Warning interrupt handler re-entered\n", unit); return; } @@ -1693,8 +1715,12 @@ siintr(int unit) */ for (card=0; card < NSI; card++) { sc = &si_softc[card]; - if (sc->sc_type == NULL) + if (sc->sc_type == SIEMPTY) continue; + + /* + * First, clear the interrupt + */ switch(sc->sc_type) { case SIHOST : maddr = sc->sc_maddr; @@ -1722,12 +1748,14 @@ siintr(int unit) } ((volatile struct si_reg *)maddr)->int_scounter = 0; - for (pp = sc->sc_ports, port=0; - port < sc->sc_nport; - pp++, port++) { + /* + * check each port + */ + for (pp=sc->sc_ports,port=0; port < sc->sc_nport; pp++,port++) { ccbp = pp->sp_ccb; tp = pp->sp_tty; + /* * See if a command has completed ? */ @@ -1761,109 +1789,155 @@ siintr(int unit) */ si_modem_state(pp, tp, ccbp->hi_ip); + /* + * Check to see if there's we should 'receive' + * characters. + */ + if (tp->t_state & TS_CONNECTED && + tp->t_state & TS_ISOPEN) + isopen = 1; + else + isopen = 0; + /* * Do break processing */ if (ccbp->hi_state & ST_BREAK) { - if (tp->t_state & TS_CONNECTED && - tp->t_state & TS_ISOPEN) { - (*linesw[tp->t_line].l_rint)(TTY_BI, tp); + if (isopen) { + (*linesw[tp->t_line].l_rint)(TTY_BI, tp); } ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */ DPRINT((pp, DBG_INTR, "si_intr break\n")); } /* - * Do RX stuff - if not open then - * dump any characters. + * Do RX stuff - if not open then dump any characters. + * XXX: This is VERY messy and needs to be cleaned up. + * + * XXX: can we leave data in the host adapter buffer + * when the clists are full? That may be dangerous + * if the user cannot get an interrupt signal through. */ - if ((tp->t_state & TS_CONNECTED) == 0 || - (tp->t_state & TS_ISOPEN) == 0) { + more_rx: /* XXX Sorry. the nesting was driving me bats! :-( */ + + if (!isopen) { ccbp->hi_rxopos = ccbp->hi_rxipos; + goto end_rx; + } + + /* + * Process read characters if not skipped above + */ + c = ccbp->hi_rxipos - ccbp->hi_rxopos; + if (c == 0) { + goto end_rx; + } + + op = ccbp->hi_rxopos; + ip = ccbp->hi_rxipos; + n = c & 0xff; + + DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", + n, op, ip)); + + /* + * Suck characters out of host card buffer into the + * "input staging buffer" - so that we dont leave the + * host card in limbo while we're possibly echoing + * characters and possibly flushing input inside the + * ldisc l_rint() routine. + */ + if (n <= SLXOS_BUFFERSIZE - op) { + + DPRINT((pp, DBG_INTR, "\tsingle copy\n")); + z = ccbp->hi_rxbuf + op; + bcopy((caddr_t)z, si_rxbuf, n); + + op += n; } else { - while ((c = ccbp->hi_rxipos - ccbp->hi_rxopos) != 0) { + x = SLXOS_BUFFERSIZE - op; - op = ccbp->hi_rxopos; - ip = ccbp->hi_rxipos; - n = c & 0xff; + DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x)); + z = ccbp->hi_rxbuf + op; + bcopy((caddr_t)z, si_rxbuf, x); - DPRINT((pp, DBG_INTR, - "n = %d, op = %d, ip = %d\n", + DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n", n-x)); + z = ccbp->hi_rxbuf; + bcopy((caddr_t)z, si_rxbuf+x, n-x); + + op += n; + } + + /* clear collected characters from buffer */ + ccbp->hi_rxopos = op; + + DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", n, op, ip)); - if (n <= SLXOS_BUFFERSIZE - op) { - DPRINT((pp, DBG_INTR, - "\tsingle copy\n")); - z = ccbp->hi_rxbuf + op; - bcopy((caddr_t)z, rxbuf, n); + /* + * at this point... + * n = number of chars placed in si_rxbuf + */ - op += n; - } else { - x = SLXOS_BUFFERSIZE - op; + /* + * Avoid the grotesquely inefficient lineswitch + * routine (ttyinput) in "raw" mode. It usually + * takes about 450 instructions (that's without + * canonical processing or echo!). slinput is + * reasonably fast (usually 40 instructions + * plus call overhead). + */ + if (tp->t_state & TS_CAN_BYPASS_L_RINT) { - DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x)); - z = ccbp->hi_rxbuf + op; - bcopy((caddr_t)z, rxbuf, x); + /* block if the driver supports it */ + if (tp->t_rawq.c_cc + n >= SI_I_HIGH_WATER + && (tp->t_cflag & CRTS_IFLOW + || tp->t_iflag & IXOFF) + && !(tp->t_state & TS_TBLOCK)) + ttyblock(tp); - DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n", n-x)); - z = ccbp->hi_rxbuf; - bcopy((caddr_t)z, rxbuf+x, n-x); + tk_nin += n; + tk_rawcc += n; + tp->t_rawcc += n; - op += n; + pp->sp_delta_overflows += + b_to_q((char *)si_rxbuf, n, &tp->t_rawq); + + ttwakeup(tp); + if (tp->t_state & TS_TTSTOP + && (tp->t_iflag & IXANY + || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { + tp->t_state &= ~TS_TTSTOP; + tp->t_lflag &= ~FLUSHO; + si_start(tp); + } + } else { + /* + * It'd be nice to not have to go through the + * function call overhead for each char here. + * It'd be nice to block input it, saving a + * loop here and the call/return overhead. + */ + for(x = 0; x < n; x++) { + i = si_rxbuf[x]; + if ((*linesw[tp->t_line].l_rint)(i, tp) + == -1) { + pp->sp_delta_overflows++; } - - ccbp->hi_rxopos = op; - - DPRINT((pp, DBG_INTR, - "n = %d, op = %d, ip = %d\n", - n, op, ip)); - /* - * at this point... - * n = number of chars placed in rxbuf + * doesn't seem to be much point doing + * this here.. this driver has no + * softtty processing! ?? */ - /* - * Avoid the grotesquely inefficient lineswitch routine - * (ttyinput) in "raw" mode. It usually takes about 450 - * instructions (that's without canonical processing or echo!). - * slinput is reasonably fast (usually 40 instructions plus - * call overhead). - */ - if (tp->t_state & TS_CAN_BYPASS_L_RINT) { - - /* block if the driver supports it */ - if (tp->t_rawq.c_cc + n >= SI_I_HIGH_WATER - && (tp->t_cflag & CRTS_IFLOW - || tp->t_iflag & IXOFF) - && !(tp->t_state & TS_TBLOCK)) - ttyblock(tp); - - tk_nin += n; - tk_rawcc += n; - tp->t_rawcc += n; - - b_to_q((char *)rxbuf, n, &tp->t_rawq); - ttwakeup(tp); - if (tp->t_state & TS_TTSTOP - && (tp->t_iflag & IXANY - || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { - tp->t_state &= ~TS_TTSTOP; - tp->t_lflag &= ~FLUSHO; - si_start(tp); - } - } else { - for(x = 0; x < n; x++) { - i = rxbuf[x]; - (*linesw[tp->t_line].l_rint)(rxbuf[x], tp); - if (pp->sp_hotchar && i == pp->sp_hotchar) { - setsofttty(); - } - } + if (pp->sp_hotchar && i == pp->sp_hotchar) { + setsofttty(); } + } + } + goto more_rx; /* try for more until RXbuf is empty */ - } /* end of RX while */ - } /* end TS_CONNECTED */ + end_rx: /* XXX: Again, sorry about the gotos.. :-) */ /* * Do TX stuff @@ -1879,6 +1953,13 @@ siintr(int unit) /* * Nudge the transmitter... + * + * XXX: I inherited some funny code here. It implies the host card only + * interrupts when the transmit buffer reaches the low-water-mark, and does + * not interrupt when it's actually hits empty. In some cases, we have + * processes waiting for complete drain, and we need to simulate an interrupt + * about when we think the buffer is going to be empty (and retry if not). + * I really am not certain about this... I *need* the hardware manuals. */ static void si_start(tp) @@ -1975,8 +2056,8 @@ si_start(tp) else time = 2; } else { - printf("SLXOS si%d: bad char time value!!\n", - SI_CARD(tp->t_dev)); + printf("si%d: bad char time value!!\n", + (int)SI_CARD(tp->t_dev)); goto out; } } @@ -2025,7 +2106,7 @@ si_lstart(pp) /* deal with the process exit case */ ttwwakeup(tp); - /* nudge protocols */ + /* nudge protocols - eg: ppp */ (*linesw[tp->t_line].l_start)(tp); pp->sp_state &= ~SS_INLSTART; @@ -2057,7 +2138,12 @@ sistop(tp, rw) ttwwakeup(tp); /* Bruce???? */ } } -#if 0 /* this doesn't work right yet.. */ +#if 1 /* XXX: this doesn't work right yet.. */ + /* XXX: this may have been failing because we used to call l_rint() + * while we were looping based on these two counters. Now, we collect + * the data and then loop stuffing it into l_rint(), making this + * useless. Should we cause this to blow away the staging buffer? + */ if (rw & FREAD) { ccbp->hi_rxopos = ccbp->hi_rxipos; } @@ -2184,8 +2270,8 @@ si_dprintf(pp, flags, str, a1, a2, a3, a4, a5, a6) (pp != NULL && ((pp->sp_debug&flags) || (si_debug&flags)))) { if (pp != NULL) printf("SLXOS %ci%d(%d): ", 's', - SI_CARD(pp->sp_tty->t_dev), - SI_PORT(pp->sp_tty->t_dev)); + (int)SI_CARD(pp->sp_tty->t_dev), + (int)SI_PORT(pp->sp_tty->t_dev)); printf(str, a1, a2, a3, a4, a5, a6); } }