Pass 1 of mpsafetty-ifying si(4). It compiles and has basic functionality,

but needs a lot more work.  In particular, it has no flow control and has
a tendency to race when giving commands.  It still uses Giant for the
tty and driver lock, but this is a keep-it-simple feature for now.
Some of the [temporary] proliferation of messages lines are way too long.
This commit is contained in:
Peter Wemm 2008-09-08 11:41:20 +00:00
parent 286fa44565
commit 434cb98901
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=182871

View file

@ -44,7 +44,6 @@ static const char si_copyright1[] = "@(#) Copyright (C) Specialix International
#include "opt_compat.h"
#include "opt_debug_si.h"
#include "opt_eisa.h"
#include "opt_tty.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -82,7 +81,7 @@ static const char si_copyright1[] = "@(#) Copyright (C) Specialix International
* The code for the Host 1 (very old ISA cards) has not been tested.
*/
#define POLL /* turn on poller to scan for lost interrupts */
#undef POLL /* turn on poller to scan for lost interrupts */
#if 0
#define REALPOLL /* on each poll, scan for work regardless */
#endif
@ -94,16 +93,17 @@ static const char si_copyright1[] = "@(#) Copyright (C) Specialix International
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); */
#if 0
static timeout_t si_lstart;
#endif
static t_break_t sibreak;
static t_close_t siclose;
static t_modem_t simodem;
static t_open_t siopen;
static int siparam(struct tty *, struct termios *);
static tsw_outwakeup_t si_start;
static tsw_ioctl_t siioctl;
static tsw_close_t siclose;
static tsw_modem_t simodem;
static tsw_open_t siopen;
static tsw_param_t siparam;
static void si_modem_state(struct si_port *pp, struct tty *tp, int hi_ip);
static char * si_modulename(int host_type, int uart_type);
@ -117,7 +117,7 @@ static struct cdevsw si_Scdevsw = {
static int si_Nports;
static int si_Nmodules;
static int si_debug = 0; /* data, not bss, so it's patchable */
static int si_debug;
SYSCTL_INT(_machdep, OID_AUTO, si_debug, CTLFLAG_RW, &si_debug, 0, "");
TUNABLE_INT("machdep.si_debug", &si_debug);
@ -126,10 +126,15 @@ static int si_numunits;
devclass_t si_devclass;
struct si_speedtab {
int sp_speed; /* Speed. */
int sp_code; /* Code. */
};
#ifndef B2000 /* not standard, but the hardware knows it. */
# define B2000 2000
#endif
static struct speedtab bdrates[] = {
static struct si_speedtab bdrates[] = {
{ B75, CLK75, }, /* 0x0 */
{ B110, CLK110, }, /* 0x1 */
{ B150, CLK150, }, /* 0x3 */
@ -148,27 +153,6 @@ static struct speedtab bdrates[] = {
};
/* populated with approx character/sec rates - translated at card
* initialisation time to chars per tick of the clock */
static int done_chartimes = 0;
static struct speedtab chartimes[] = {
{ B75, 8, },
{ B110, 11, },
{ B150, 15, },
{ B300, 30, },
{ B600, 60, },
{ B1200, 120, },
{ B2000, 200, },
{ B2400, 240, },
{ B4800, 480, },
{ B9600, 960, },
{ B19200, 1920, },
{ B38400, 3840, },
{ B57600, 5760, },
{ B115200, 11520, },
{ -1, -1 },
};
#ifdef POLL
static int si_pollrate; /* in addition to irq */
static int si_realpoll = 0; /* poll HW on timer */
@ -261,6 +245,28 @@ si_bcopyv(const void *src, volatile void *dst, size_t len)
*d++ = *s++;
}
static int
si_speedtab(int speed, struct si_speedtab *table)
{
for ( ; table->sp_speed != -1; table++)
if (table->sp_speed == speed)
return (table->sp_code);
return (-1);
}
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.
*/
@ -275,7 +281,6 @@ siattach(device_t dev)
volatile struct si_reg *regp;
volatile caddr_t maddr;
struct si_module *modp;
struct speedtab *spt;
int nmodule, nport, x, y;
int uart_type;
@ -579,17 +584,8 @@ siattach(device_t dev)
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, &Giant);
tty_makedev(tp, NULL, "A%r%r", unit, (int)(pp - sc->sc_ports));
}
try_next2:
if (modp->sm_next == 0) {
@ -605,13 +601,6 @@ siattach(device_t dev)
modp = (struct si_module *)
(maddr + (unsigned)(modp->sm_next & 0x7fff));
}
if (done_chartimes == 0) {
for (spt = chartimes ; spt->sp_speed != -1; spt++) {
if ((spt->sp_code /= hz) == 0)
spt->sp_code = 1;
}
done_chartimes = 1;
}
if (unit == 0)
make_dev(&si_Scdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
@ -620,9 +609,10 @@ siattach(device_t dev)
}
static int
siopen(struct tty *tp, struct cdev *dev)
siopen(struct tty *tp)
{
DPRINT((0, DBG_ENTRY|DBG_OPEN, "siopen()\n"));
mtx_assert(&Giant, MA_OWNED);
#ifdef POLL
/*
@ -633,6 +623,7 @@ siopen(struct tty *tp, struct cdev *dev)
init_finished = 1;
}
#endif
DPRINT((0, DBG_EXIT|DBG_OPEN, "siopen() finished\n"));
return(0);
}
@ -641,25 +632,32 @@ siclose(struct tty *tp)
{
struct si_port *pp;
DPRINT((0, DBG_ENTRY|DBG_CLOSE, "siclose()\n"));
mtx_assert(&Giant, MA_OWNED);
pp = tp->t_sc;
pp = tty_softc(tp);
(void) si_command(pp, FCLOSE, SI_WAIT);
DPRINT((0, DBG_EXIT|DBG_CLOSE, "siclose() finished\n"));
}
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;
DPRINT((0, DBG_ENTRY|DBG_IOCTL, "siioctl(0x%lx,0x%x)\n", cmd, data));
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 (ENOIOCTL); /* Let the common tty ioctl handler do it */
}
/*
* Handle the Specialix ioctls on the control dev.
*/
@ -675,8 +673,8 @@ si_Sioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
int oldspl;
int card, port;
DPRINT((0, DBG_ENTRY|DBG_IOCTL, "si_Sioctl(%s,%lx,%x,%x)\n",
devtoname(dev), cmd, data, flag));
DPRINT((0, DBG_ENTRY|DBG_IOCTL, "si_Sioctl(%s,0x%lx,0x%x)\n",
devtoname(dev), cmd, data));
mtx_assert(&Giant, MA_OWNED);
#if 1
@ -805,7 +803,7 @@ si_Sioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
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 */
@ -827,10 +825,9 @@ siparam(struct tty *tp, struct termios *t)
/* if not hung up.. */
if (t->c_ospeed != 0) {
/* translate baud rate to firmware values */
ospeed = ttspeedtab(t->c_ospeed, bdrates);
ospeed = si_speedtab(t->c_ospeed, bdrates);
ispeed = t->c_ispeed ?
ttspeedtab(t->c_ispeed, bdrates) : ospeed;
si_speedtab(t->c_ispeed, bdrates) : ospeed;
/* enforce legit baud rate */
if (ospeed < 0 || ispeed < 0)
return (EINVAL);
@ -862,10 +859,11 @@ siparam(struct tty *tp, struct termios *t)
/* ========== set hi_mr2 ========== */
val = 0;
if (cflag & CSTOPB) /* Stop bits */
if (cflag & CSTOPB) /* Stop bits */
val |= MR2_2_STOP;
else
val |= MR2_1_STOP;
/*
* Enable H/W RTS/CTS handshaking. The default TA/MTA is
* a DCE, hence the reverse sense of RTS and CTS
@ -885,15 +883,15 @@ siparam(struct tty *tp, struct termios *t)
if (cflag & PARODD)
val |= MR1_ODD;
if ((cflag & CS8) == CS8) { /* 8 data bits? */
if ((cflag & CS8) == CS8) /* 8 data bits? */
val |= MR1_8_BITS;
} else if ((cflag & CS7) == CS7) { /* 7 data bits? */
else if ((cflag & CS7) == CS7) /* 7 data bits? */
val |= MR1_7_BITS;
} else if ((cflag & CS6) == CS6) { /* 6 data bits? */
else if ((cflag & CS6) == CS6) /* 6 data bits? */
val |= MR1_6_BITS;
} else { /* Must be 5 */
else /* Must be 5 */
val |= MR1_5_BITS;
}
/*
* Enable H/W RTS/CTS handshaking. The default TA/MTA is
* a DCE, hence the reverse sense of RTS and CTS
@ -961,8 +959,8 @@ siparam(struct tty *tp, struct termios *t)
(void) simodem(tp, SER_DTR | SER_RTS, 0);
}
DPRINT((pp, DBG_PARAM, "siparam, complete: MR1 %x MR2 %x HI_MASK %x PRTCL %x HI_BREAK %x\n",
ccbp->hi_mr1, ccbp->hi_mr2, ccbp->hi_mask, ccbp->hi_prtcl, ccbp->hi_break));
DPRINT((pp, DBG_PARAM, "siparam, complete: MR1 %x MR2 %x HI_MASK %x PRTCL %x HI_BREAK %x HI_CSR %x\n",
ccbp->hi_mr1, ccbp->hi_mr2, ccbp->hi_mask, ccbp->hi_prtcl, ccbp->hi_break, ccbp->hi_csr));
splx(oldspl);
return(error);
@ -981,7 +979,7 @@ simodem(struct tty *tp, int sigon, int sigoff)
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 +1019,18 @@ si_modem_state(struct si_port *pp, struct tty *tp, int hi_ip)
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 +1185,7 @@ si_intr(void *arg)
pp++, port++) {
ccbp = pp->sp_ccb;
tp = pp->sp_tty;
tty_lock(tp);
/*
* See if a command has completed ?
@ -1212,8 +1214,10 @@ si_intr(void *arg)
/*
* Continue on if it's closed
*/
if (ccbp->hi_stat == IDLE_CLOSE)
if (ccbp->hi_stat == IDLE_CLOSE) {
tty_unlock(tp);
continue;
}
/*
* Do modem state change if not a local device
@ -1223,18 +1227,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"));
}
@ -1251,10 +1251,12 @@ si_intr(void *arg)
more_rx:
if (!isopen) {
DPRINT((pp, DBG_INTR, "intr1: not open\n"));
ccbp->hi_rxopos = ccbp->hi_rxipos;
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 +1264,7 @@ si_intr(void *arg)
*/
if (tp->t_state & TS_TBLOCK)
goto end_rx;
#endif
/*
* Process read characters if not skipped above
@ -1307,46 +1310,17 @@ si_intr(void *arg)
/* clear collected characters from buffer */
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 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 (0 && ttydisc_can_bypass(tp)) {
/* 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);
i = ttydisc_rint_bypass(tp, (char *)si_rxbuf, n);
if (i < n)
pp->sp_delta_overflows += (n - i);
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 +1330,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 +1338,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 +1367,59 @@ si_start(struct tty *tp)
{
struct si_port *pp;
volatile struct si_channel *ccbp;
struct clist *qp;
BYTE ipos;
BYTE ipos, count;
#if 0
int nchar;
int oldspl, count, n, amount;
#endif
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, "txbuf pend 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;
DPRINT((pp, DBG_START, "spaceleft amount %d\n", amount));
if (amount == 0)
break;
n = ttydisc_getc(tp, si_txbuf, amount);
DPRINT((pp, DBG_START, "getc n=%d\n", n));
if (n == 0)
break;
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;
#if 0
/*
* See if there are any characters still to come. If so, we can
* depend on si_start being called again.
*
* XXX the manual is vague on this. It implies we get an interrupt
* when the transmit queue reaches the 25% low water mark, but NOT
* when it hits empty.
*/
nchar = ttyoutq_getsize(&tp->t_outq) - ttyoutq_bytesleft(&tp->t_outq);
DPRINT((pp, DBG_START, "count %d, nchar %d\n",
(BYTE)count, nchar));
/* wakeup time? */
ttwwakeup(tp);
DPRINT((pp, DBG_START, "count %d, nchar %d, tp->t_state 0x%x\n",
(BYTE)count, nchar, tp->t_state));
if (tp->t_state & TS_BUSY) {
if (count != 0 && nchar == 0) {
int time;
time = ttspeedtab(tp->t_ospeed, chartimes);
/* XXX lame. Ticks per character. used to be a table. */
time = (tp->t_termios.c_ospeed + 9) / 10;
if (time > 0) {
if (time < nchar)
@ -1465,12 +1438,13 @@ si_start(struct tty *tp)
pp->sp_state |= SS_LSTART;
pp->lstart_ch = timeout(si_lstart, (caddr_t)pp, time);
}
#endif
out:
splx(oldspl);
DPRINT((pp, DBG_EXIT|DBG_START, "leave si_start()\n"));
}
#if 0
/*
* Note: called at splsoftclock from the timeout code
* This has to deal with two things... cause wakeups while waiting for
@ -1492,20 +1466,13 @@ 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);
}
#endif
#if 0 /* XXX mpsafetty */
/*
* Stop output on a line. called at spltty();
*/
@ -1516,7 +1483,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,17 +1508,24 @@ si_stop(struct tty *tp, int rw)
}
#endif
}
#endif
/*
* Issue a command to the host card CPU.
*
* XXX This is all just so WRONG!. Ed says we're not supposed to sleep
* here anyway. We sort of get away with it for now by using Giant.
* Something better will have to be done.
* Linux does a busy spin here waiting for the 8-bit cpu to notice the
* posted command and respond to it. I'm not sure I like that either.
*/
static void
si_command(struct si_port *pp, int cmd, int waitflag)
{
int oldspl;
volatile struct si_channel *ccbp = pp->sp_ccb;
int x;
int err;
DPRINT((pp, DBG_ENTRY|DBG_PARAM, "si_command(%x,%s,%d): hi_stat %s, sp_pend: %s\n",
pp, si_cmdname(cmd), waitflag, si_cmdname(ccbp->hi_stat),
@ -1567,17 +1541,21 @@ si_command(struct si_port *pp, int cmd, int waitflag)
x != IDLE_CLOSE &&
x != IDLE_BREAK &&
x != cmd) {
if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
"sicmd1", hz/4)) {
DPRINT((pp, DBG_PARAM, "sicmd1 old cmd pending (going to tsleep): hi_stat (%s)\n", si_cmdname(ccbp->hi_stat)));
err = tsleep(&pp->sp_state, (PSOCK+1)|PCATCH, "sicmd1", hz/4);
if (err) {
DPRINT((pp, DBG_PARAM, "sicmd1 timeout: hi_stat (%s)\n",
si_cmdname(ccbp->hi_stat)));
/* This is very very bad. The card has crashed. */
/* XXX the driver breaks at this point */
if (err == ETIMEDOUT)
printf("%s: tsleep1 timeout. hi_stat %s, sp_pend %s\n", pp->sp_name, si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend));
splx(oldspl);
return;
}
}
/* it should now be in IDLE_{OPEN|CLOSE|BREAK}, or "cmd" */
DPRINT((pp, DBG_PARAM, "sicmd1 now in: hi_stat (%s) sp_pend (%s)\n", si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend)));
/* if there was a pending command, cause a state-change wakeup */
switch(pp->sp_pend) {
@ -1588,7 +1566,7 @@ si_command(struct si_port *pp, int cmd, int waitflag)
case CONFIG:
case SBREAK:
case EBREAK:
DPRINT((pp, DBG_PARAM, "si_command: sp_pend %s\n", si_cmdname(pp->sp_pend)));
DPRINT((pp, DBG_PARAM, "si_command: sp_pend %s, doing wakeup\n", si_cmdname(pp->sp_pend)));
wakeup(&pp->sp_state);
break;
default:
@ -1597,16 +1575,24 @@ si_command(struct si_port *pp, int cmd, int waitflag)
pp->sp_pend = cmd; /* New command pending */
ccbp->hi_stat = cmd; /* Post it */
DPRINT((pp, DBG_PARAM, "sicmd now posted: hi_stat (%s) sp_pend (%s)\n", si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend)));
if (waitflag) {
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))
DPRINT((pp, DBG_PARAM, "sicmd2 now waiting: hi_stat (%s) sp_pend (%s) (going to tsleep)\n", si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend)));
err = tsleep(&pp->sp_state, (PSOCK+1)|PCATCH, "sicmd2", hz);
if (err) {
DPRINT((pp, DBG_PARAM, "sicmd2 tsleep error: hi_stat (%s) sp_pend (%s)\n", si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend)));
if (err == ETIMEDOUT) {
printf("%s: tsleep2 timeout. hi_stat %s, sp_pend %s\n", pp->sp_name, si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend));
}
break;
}
}
}
DPRINT((pp, DBG_PARAM, "sicmd2 finished: hi_stat (%s) sp_pend (%s)\n", si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend)));
splx(oldspl);
}