--- si.c.dist 2008-09-04 11:11:22.000000000 -0700 +++ si.c 2008-09-04 11:12:49.000000000 -0700 @@ -44,7 +44,6 @@ static const char si_copyright1[] = "@( #include "opt_compat.h" #include "opt_debug_si.h" #include "opt_eisa.h" -#include "opt_tty.h" #include #include @@ -95,13 +94,13 @@ static const char si_copyright1[] = "@( static void si_command(struct si_port *, int, int); static int si_Sioctl(struct cdev *, u_long, caddr_t, int, struct thread *); static void si_start(struct tty *); -static void si_stop(struct tty *, int); +/* static void si_stop(struct tty *, int); */ static timeout_t si_lstart; -static t_break_t sibreak; -static t_close_t siclose; -static t_modem_t simodem; -static t_open_t siopen; +static tsw_ioctl_t siioctl; +static tsw_close_t siclose; +static tsw_modem_t simodem; +static tsw_open_t siopen; static int siparam(struct tty *, struct termios *); @@ -126,6 +125,12 @@ static int si_numunits; devclass_t si_devclass; + +struct speedtab { + int sp_speed; /* Speed. */ + int sp_code; /* Code. */ +}; + #ifndef B2000 /* not standard, but the hardware knows it. */ # define B2000 2000 #endif @@ -261,6 +266,30 @@ si_bcopyv(const void *src, volatile void *d++ = *s++; } +static int +ttspeedtab(int speed, struct speedtab *table) +{ + if (speed == 0) + return (0); /* hangup */ + for ( ; table->sp_speed > 0; table++) + if (table->sp_speed <= speed) /* nearest one, rounded down */ + return (table->sp_code); + return (1); /* 50, min and not hangup */ +} + + +static struct ttydevsw si_tty_class = { + .tsw_flags = TF_INITLOCK|TF_CALLOUT, + .tsw_open = siopen, + .tsw_close = siclose, + .tsw_outwakeup = si_start, + /* .tsw_stop = si_stop */ + .tsw_ioctl = siioctl, + .tsw_param = siparam, + .tsw_modem = simodem, +}; + + /* * Attach the device. Initialize the card. */ @@ -579,17 +608,8 @@ try_next: sprintf(pp->sp_name, "si%r%r", unit, (int)(pp - sc->sc_ports)); #endif - tp = pp->sp_tty = ttyalloc(); - tp->t_sc = pp; - tp->t_break = sibreak; - tp->t_close = siclose; - tp->t_modem = simodem; - tp->t_open = siopen; - tp->t_oproc = si_start; - tp->t_param = siparam; - tp->t_stop = si_stop; - ttycreate(tp, TS_CALLOUT, "A%r%r", unit, - (int)(pp - sc->sc_ports)); + tp = pp->sp_tty = tty_alloc(&si_tty_class, pp, NULL); + tty_makedev(tp, NULL, "A%r%r", unit, (int)(pp - sc->sc_ports)); } try_next2: if (modp->sm_next == 0) { @@ -620,7 +640,7 @@ try_next2: } static int -siopen(struct tty *tp, struct cdev *dev) +siopen(struct tty *tp) { mtx_assert(&Giant, MA_OWNED); @@ -642,24 +662,28 @@ siclose(struct tty *tp) struct si_port *pp; mtx_assert(&Giant, MA_OWNED); - pp = tp->t_sc; + pp = tty_softc(tp); (void) si_command(pp, FCLOSE, SI_WAIT); } -static void -sibreak(struct tty *tp, int sig) +static int +siioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) { struct si_port *pp; mtx_assert(&Giant, MA_OWNED); - pp = tp->t_sc; - if (sig) + pp = tty_softc(tp); + switch (cmd) { + case TIOCSBRK: si_command(pp, SBREAK, SI_WAIT); - else + return (0); + case TIOCCBRK: si_command(pp, EBREAK, SI_WAIT); + return (0); + } + return (0); } - /* * Handle the Specialix ioctls on the control dev. */ @@ -805,7 +829,7 @@ out: static int siparam(struct tty *tp, struct termios *t) { - struct si_port *pp = tp->t_sc; + struct si_port *pp = tty_softc(tp); volatile struct si_channel *ccbp; int oldspl, cflag, iflag, oflag, lflag; int error = 0; /* shutup gcc */ @@ -981,7 +1005,7 @@ simodem(struct tty *tp, int sigon, int s volatile struct si_channel *ccbp; int x; - pp = tp->t_sc; + pp = tty_softc(tp); DPRINT((pp, DBG_ENTRY|DBG_MODEM, "simodem(%x,%x)\n", sigon, sigoff)); mtx_assert(&Giant, MA_OWNED); ccbp = pp->sp_ccb; /* Find channel address */ @@ -1021,15 +1045,18 @@ si_modem_state(struct si_port *pp, struc mtx_assert(&Giant, MA_OWNED); if (hi_ip & IP_DCD) { if (!(pp->sp_last_hi_ip & IP_DCD)) { - DPRINT((pp, DBG_INTR, "modem carr on t_line %d\n", - tp->t_line)); - (void)ttyld_modem(tp, 1); + DPRINT((pp, DBG_INTR, "modem carr on%d\n")); + (void)ttydisc_modem(tp, 1); } } else { if (pp->sp_last_hi_ip & IP_DCD) { DPRINT((pp, DBG_INTR, "modem carr off\n")); - if (ttyld_modem(tp, 0)) +#if 0 /* XXX mpsafetty ttyld_modem used to tell us to shutdown the port or not */ + if (ttydisc_modem(tp, 0)) (void) simodem(tp, 0, SER_DTR | SER_RTS); +#else + ttydisc_modem(tp, 0); +#endif } } pp->sp_last_hi_ip = hi_ip; @@ -1184,6 +1211,7 @@ si_intr(void *arg) pp++, port++) { ccbp = pp->sp_ccb; tp = pp->sp_tty; + tty_lock(tp); /* * See if a command has completed ? @@ -1223,18 +1251,14 @@ si_intr(void *arg) /* * Check to see if we should 'receive' characters. */ - if (tp->t_state & TS_CONNECTED && - tp->t_state & TS_ISOPEN) - isopen = 1; - else - isopen = 0; + isopen = tty_opened(tp); /* * Do input break processing */ if (ccbp->hi_state & ST_BREAK) { if (isopen) - ttyld_rint(tp, TTY_BI); + ttydisc_rint(tp, 0, TRE_BREAK); ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */ DPRINT((pp, DBG_INTR, "si_intr break\n")); } @@ -1255,6 +1279,7 @@ si_intr(void *arg) goto end_rx; } +#if 0 /* XXXMPSAFETTY */ /* * If the tty input buffers are blocked, stop emptying * the incoming buffers and let the auto flow control @@ -1262,6 +1287,7 @@ si_intr(void *arg) */ if (tp->t_state & TS_TBLOCK) goto end_rx; +#endif /* * Process read characters if not skipped above @@ -1315,38 +1341,12 @@ si_intr(void *arg) * n = number of chars placed in si_rxbuf */ - /* - * 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) { + if (ttydisc_can_bypass(tp)) { + + i = ttydisc_rint_bypass(tp, (char *)si_rxbuf, n); + if (i < n) + pp->sp_delta_overflows += (n - i); - /* 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; - - 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 @@ -1356,7 +1356,7 @@ si_intr(void *arg) */ for(x = 0; x < n; x++) { i = si_rxbuf[x]; - if (ttyld_rint(tp, i) == -1) + if (ttydisc_rint(tp, i, 0) == -1) pp->sp_delta_overflows++; } } @@ -1364,10 +1364,13 @@ si_intr(void *arg) end_rx: + ttydisc_rint_done(tp); + /* * Do TX stuff */ - ttyld_start(tp); + si_start(tp); + tty_unlock(tp); } /* end of for (all ports on this controller) */ } /* end of for (all controllers) */ @@ -1390,63 +1393,41 @@ si_start(struct tty *tp) { struct si_port *pp; volatile struct si_channel *ccbp; - struct clist *qp; - BYTE ipos; + BYTE ipos, count; int nchar; - int oldspl, count, n, amount; + int oldspl, n, amount; oldspl = spltty(); mtx_assert(&Giant, MA_OWNED); - qp = &tp->t_outq; - pp = tp->t_sc; + pp = tty_softc(tp); DPRINT((pp, DBG_ENTRY|DBG_START, - "si_start(%x) t_state %x sp_state %x t_outq.c_cc %d\n", - tp, tp->t_state, pp->sp_state, qp->c_cc)); - - if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) - goto out; + "si_start(%x) sp_state %x\n", + tp, pp->sp_state)); ccbp = pp->sp_ccb; - count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos; - DPRINT((pp, DBG_START, "count %d\n", (BYTE)count)); - - while ((nchar = qp->c_cc) > 0) { - if ((BYTE)count >= 255) - break; - amount = min(nchar, (255 - (BYTE)count)); + while ((count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos) < 255) { + DPRINT((pp, DBG_START, "count %d\n", (BYTE)count)); ipos = (unsigned int)ccbp->hi_txipos; - n = q_to_b(&tp->t_outq, si_txbuf, amount); - /* will it fit in one lump? */ - if ((SI_BUFFERSIZE - ipos) >= n) { - si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos], n); - } else { - si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos], - SI_BUFFERSIZE - ipos); - si_bcopyv(si_txbuf + (SI_BUFFERSIZE - ipos), - &ccbp->hi_txbuf[0], n - (SI_BUFFERSIZE - ipos)); - } + if ((int)ccbp->hi_txopos <= ipos) + amount = SI_BUFFERSIZE - ipos; + else + amount = 255 - count; + n = ttydisc_getc(tp, si_txbuf, amount); + si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos], n); ccbp->hi_txipos += n; - count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos; } - if (count != 0 && nchar == 0) - tp->t_state |= TS_BUSY; - else - tp->t_state &= ~TS_BUSY; - - /* wakeup time? */ - ttwwakeup(tp); - - DPRINT((pp, DBG_START, "count %d, nchar %d, tp->t_state 0x%x\n", - (BYTE)count, nchar, tp->t_state)); + nchar = ttyoutq_bytesleft(&tp->t_outq); + DPRINT((pp, DBG_START, "count %d, nchar %d\n", + (BYTE)count, nchar)); - if (tp->t_state & TS_BUSY) { + if (count != 0 && nchar == 0) { int time; - time = ttspeedtab(tp->t_ospeed, chartimes); + time = ttspeedtab(tp->t_termios.c_ospeed, chartimes); if (time > 0) { if (time < nchar) @@ -1466,7 +1447,6 @@ si_start(struct tty *tp) pp->lstart_ch = timeout(si_lstart, (caddr_t)pp, time); } -out: splx(oldspl); DPRINT((pp, DBG_EXIT|DBG_START, "leave si_start()\n")); } @@ -1492,20 +1472,12 @@ si_lstart(void *arg) pp->sp_state &= ~SS_LSTART; tp = pp->sp_tty; - if ((tp->t_state & TS_ISOPEN) == 0) { - splx(oldspl); - return; - } - - /* deal with the process exit case */ - ttwwakeup(tp); - - /* nudge protocols - eg: ppp */ - ttyld_start(tp); + si_start(tp); splx(oldspl); } +#if 0 /* XXX mpsafetty */ /* * Stop output on a line. called at spltty(); */ @@ -1516,7 +1488,7 @@ si_stop(struct tty *tp, int rw) struct si_port *pp; mtx_assert(&Giant, MA_OWNED); - pp = tp->t_sc; + pp = tty_softc(tp); ccbp = pp->sp_ccb; DPRINT((pp, DBG_ENTRY|DBG_STOP, "si_stop(%x,%x)\n", tp, rw)); @@ -1541,6 +1513,7 @@ si_stop(struct tty *tp, int rw) } #endif } +#endif /* * Issue a command to the host card CPU. @@ -1567,8 +1540,7 @@ si_command(struct si_port *pp, int cmd, x != IDLE_CLOSE && x != IDLE_BREAK && x != cmd) { - if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH, - "sicmd1", hz/4)) { + if (tsleep(&pp->sp_state, (PSOCK+1)|PCATCH, "sicmd1", hz/4)) { DPRINT((pp, DBG_PARAM, "sicmd1 timeout: hi_stat (%s)\n", si_cmdname(ccbp->hi_stat))); /* This is very very bad. The card has crashed. */ @@ -1602,8 +1574,7 @@ si_command(struct si_port *pp, int cmd, while((x = ccbp->hi_stat) != IDLE_OPEN && x != IDLE_CLOSE && x != IDLE_BREAK) { - if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH, - "sicmd2", 0)) + if (tsleep(&pp->sp_state, (PSOCK+1)|PCATCH, "sicmd2", 0)) break; } }