- Use a spin mutex instead of COM_LOCK, since COM_LOCK is going away.

The same name from the sio(4) driver was used and an appropriate
  dictionary item added at the top to reduce diffs.
- Catch up to the new swi API.
This commit is contained in:
John Baldwin 2001-02-09 17:55:32 +00:00
parent 522be16a94
commit 6221adac84
3 changed files with 249 additions and 495 deletions

View File

@ -133,7 +133,10 @@
#define siosetwater cysetwater
#define comstop cystop
#define siowrite cywrite
#define sio_ih cy_ih
#define sio_irec cy_irec
#define sio_lock cy_lock
#define sio_inited cy_inited
#define sio_timeout cy_timeout
#define sio_timeout_handle cy_timeout_handle
#define sio_timeouts_until_log cy_timeouts_until_log
@ -351,7 +354,9 @@ static void disc_optim __P((struct tty *tp, struct termios *t,
void cystatus __P((int unit));
#endif
static char driver_name[] = "cy";
static char driver_name[] = "cy";
static struct mtx sio_lock;
static int sio_inited;
/* table and macro for fast conversion from a unit number to its com struct */
static struct com_s *p_com_addr[NSIO];
@ -391,7 +396,7 @@ static struct cdevsw sio_cdevsw = {
static int comconsole = -1;
static speed_t comdefaultrate = TTYDEF_SPEED;
static u_int com_events; /* input chars + weighted output completions */
static struct intrhand *sio_ih;
static void *sio_ih;
static int sio_timeout;
static int sio_timeouts_until_log;
static struct callout_handle sio_timeout_handle
@ -428,6 +433,9 @@ sioprobe(dev)
iobase = (cy_addr)dev->id_maddr;
if (atomic_cmpset_int(&sio_inited, 0, 1))
mtx_init(&sio_lock, driver_name, MTX_SPIN);
/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
cy_inb(iobase, CY16_RESET, 0); /* XXX? */
DELAY(500); /* wait for the board to get its act together */
@ -595,9 +603,11 @@ cyattach_common(cy_iobase, cy_align)
com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
}
if (siosetwater(com, com->it_in.c_ispeed) != 0) {
mtx_unlock_spin(&sio_lock);
free(com, M_DEVBUF);
return (0);
}
mtx_unlock_spin(&sio_lock);
termioschars(&com->it_in);
com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
com->it_out = com->it_in;
@ -608,8 +618,8 @@ cyattach_common(cy_iobase, cy_align)
if (sio_ih == NULL) {
cdevsw_add(&sio_cdevsw);
sio_ih = sinthand_add("tty:sio", &tty_ithd, siopoll, NULL,
SWI_TTY, 0);
swi_add(&tty_ithd, "tty:cy", siopoll, NULL, SWI_TTY, 0,
&sio_ih);
}
make_dev(&sio_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter,
@ -651,7 +661,6 @@ sioopen(dev, flag, mode, p)
int s;
struct tty *tp;
int unit;
int intrsave;
mynor = minor(dev);
unit = MINOR_TO_UNIT(mynor);
@ -758,17 +767,14 @@ sioopen(dev, flag, mode, p)
}
}
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
(void) inb(com->line_status_port);
(void) inb(com->data_port);
com->prev_modem_status = com->last_modem_status
= inb(com->modem_status_port);
outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS
| IER_EMSC);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#else /* !0 */
/*
* Flush fifos. This requires a full channel reset which
@ -779,16 +785,13 @@ sioopen(dev, flag, mode, p)
CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET);
cd1400_channel_cmd(com, com->channel_control);
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com->prev_modem_status = com->last_modem_status
= cd_getreg(com, CD1400_MSVR2);
cd_setreg(com, CD1400_SRER,
com->intr_enable
= CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#endif /* 0 */
/*
* Handle initial DCD. Callout devices get a fake initial
@ -871,7 +874,6 @@ comhardclose(com)
int s;
struct tty *tp;
int unit;
int intrsave;
unit = com->unit;
iobase = com->iobase;
@ -885,13 +887,10 @@ comhardclose(com)
outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
#else
/* XXX */
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com->etc = ETC_NONE;
cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
#endif
@ -899,12 +898,9 @@ comhardclose(com)
#if 0
outb(iobase + com_ier, 0);
#else
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
cd_setreg(com, CD1400_SRER, com->intr_enable = 0);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#endif
tp = com->tp;
if ((tp->t_cflag & HUPCL)
@ -995,9 +991,8 @@ siodtrwakeup(chan)
}
/*
* This function:
* a) needs to be called with COM_LOCK() held, and
* b) needs to return with COM_LOCK() held.
* Call this function with the sio_lock mutex held. It will return with the
* lock still held.
*/
static void
sioinput(com)
@ -1008,7 +1003,6 @@ sioinput(com)
u_char line_status;
int recv_data;
struct tty *tp;
int intrsave;
buf = com->ibuf;
tp = com->tp;
@ -1032,9 +1026,7 @@ sioinput(com)
* semantics instead of the save-and-disable semantics
* that are used everywhere else.
*/
intrsave = save_intr();
COM_UNLOCK();
enable_intr();
mtx_unlock_spin(&sio_lock);
incc = com->iptr - buf;
if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
&& (com->state & CS_RTS_IFLOW
@ -1055,8 +1047,7 @@ sioinput(com)
tp->t_lflag &= ~FLUSHO;
comstart(tp);
}
restore_intr(intrsave);
COM_LOCK();
mtx_lock_spin(&sio_lock);
} while (buf < com->iptr);
} else {
do {
@ -1065,9 +1056,7 @@ sioinput(com)
* semantics instead of the save-and-disable semantics
* that are used everywhere else.
*/
intrsave = save_intr();
COM_UNLOCK();
enable_intr();
mtx_unlock_spin(&sio_lock);
line_status = buf[com->ierroff];
recv_data = *buf++;
if (line_status
@ -1082,8 +1071,7 @@ sioinput(com)
recv_data |= TTY_PE;
}
(*linesw[tp->t_line].l_rint)(recv_data, tp);
restore_intr(intrsave);
COM_LOCK();
mtx_lock_spin(&sio_lock);
} while (buf < com->iptr);
}
com_events -= (com->iptr - com->ibuf);
@ -1115,7 +1103,7 @@ siointr(unit)
cy_addr iobase;
u_char status;
COM_LOCK(); /* XXX could this be placed down lower in the loop? */
mtx_lock_spin(&sio_lock); /* XXX could this be placed down lower in the loop? */
baseu = unit * CY_MAX_PORTS;
cy_align = com_addr(baseu)->cy_align;
@ -1173,7 +1161,7 @@ siointr(unit)
#ifndef SOFT_HOTCHAR
if (line_status & CD1400_RDSR_SPECIAL
&& com->hotchar != 0)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
#if 1 /* XXX "intelligent" PFO error handling would break O error handling */
@ -1201,7 +1189,7 @@ siointr(unit)
++com->bytes_in;
#ifdef SOFT_HOTCHAR
if (com->hotchar != 0 && recv_data == com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
ioptr = com->iptr;
if (ioptr >= com->ibufend)
@ -1251,7 +1239,7 @@ siointr(unit)
if (com->hotchar != 0
&& recv_data
== com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
ioptr[0] = recv_data;
ioptr[com->ierroff] = 0;
@ -1266,7 +1254,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR
if (com->hotchar != 0
&& recv_data == com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
} while (--count != 0);
} else {
@ -1291,7 +1279,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR
if (com->hotchar != 0
&& recv_data == com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
ioptr[0] = recv_data;
ioptr[com->ierroff] = 0;
@ -1356,7 +1344,7 @@ siointr(unit)
if (!(com->state & CS_CHECKMSR)) {
com_events += LOTS_OF_EVENTS;
com->state |= CS_CHECKMSR;
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
#ifdef SOFT_CTS_OFLOW
@ -1487,7 +1475,7 @@ siointr(unit)
if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS;
com->state |= CS_ODONE;
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
break;
case ETC_BREAK_ENDED:
@ -1501,7 +1489,7 @@ siointr(unit)
if (!(com->extra_state & CSE_ODONE)) {
com_events += LOTS_OF_EVENTS;
com->extra_state |= CSE_ODONE;
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
cd_outb(iobase, CD1400_SRER, cy_align,
com->intr_enable
@ -1559,7 +1547,7 @@ siointr(unit)
com->state |= CS_ODONE;
/* handle at high level ASAP */
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
}
}
@ -1579,9 +1567,9 @@ siointr(unit)
/* ensure an edge for the next interrupt */
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
COM_UNLOCK();
mtx_unlock_spin(&sio_lock);
}
#if 0
@ -1756,7 +1744,6 @@ static void
siopoll(void *arg)
{
int unit;
int intrsave;
#ifdef CyDebug
++cy_timeouts;
@ -1779,9 +1766,7 @@ siopoll(void *arg)
* (actually never opened devices) so that we don't
* loop.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
incc = com->iptr - com->ibuf;
com->iptr = com->ibuf;
if (com->state & CS_CHECKMSR) {
@ -1789,8 +1774,7 @@ siopoll(void *arg)
com->state &= ~CS_CHECKMSR;
}
com_events -= incc;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (incc != 0)
log(LOG_DEBUG,
"sio%d: %d events for device with no tp\n",
@ -1798,39 +1782,30 @@ siopoll(void *arg)
continue;
}
if (com->iptr != com->ibuf) {
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
sioinput(com);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
if (com->state & CS_CHECKMSR) {
u_char delta_modem_status;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
sioinput(com);
delta_modem_status = com->last_modem_status
^ com->prev_modem_status;
com->prev_modem_status = com->last_modem_status;
com_events -= LOTS_OF_EVENTS;
com->state &= ~CS_CHECKMSR;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (delta_modem_status & MSR_DCD)
(*linesw[tp->t_line].l_modem)
(tp, com->prev_modem_status & MSR_DCD);
}
if (com->extra_state & CSE_ODONE) {
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com_events -= LOTS_OF_EVENTS;
com->extra_state &= ~CSE_ODONE;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (!(com->state & CS_BUSY)) {
tp->t_state &= ~TS_BUSY;
ttwwakeup(com->tp);
@ -1842,13 +1817,10 @@ siopoll(void *arg)
}
}
if (com->state & CS_ODONE) {
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com_events -= LOTS_OF_EVENTS;
com->state &= ~CS_ODONE;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
(*linesw[tp->t_line].l_start)(tp);
}
if (com_events == 0)
@ -1877,7 +1849,6 @@ comparam(tp, t)
u_char opt;
int s;
int unit;
int intrsave;
/* do historical conversions */
if (t->c_ispeed == 0)
@ -2025,15 +1996,11 @@ comparam(tp, t)
if (cflag & CCTS_OFLOW)
opt |= CD1400_COR2_CCTS_OFLOW;
#endif
intrsave = save_intr();
disable_intr();
COM_LOCK();
if (opt != com->cor[1]) {
cor_change |= CD1400_CCR_COR2;
cd_setreg(com, CD1400_COR2, com->cor[1] = opt);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
/*
* set channel option register 3 -
@ -2154,9 +2121,7 @@ comparam(tp, t)
* XXX should have done this long ago, but there is too much state
* to change all atomically.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com->state &= ~CS_TTGO;
if (!(tp->t_state & TS_TTSTOP))
@ -2222,8 +2187,7 @@ comparam(tp, t)
| CD1400_SRER_TXMPTY);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
splx(s);
comstart(tp);
if (com->ibufold != NULL) {
@ -2233,6 +2197,10 @@ comparam(tp, t)
return (0);
}
/*
* This function must be called with the sio_lock mutex released and will
* return with it obtained.
*/
static int
siosetwater(com, speed)
struct com_s *com;
@ -2242,7 +2210,6 @@ siosetwater(com, speed)
u_char *ibuf;
int ibufsize;
struct tty *tp;
int intrsave;
/*
* Make the buffer size large enough to handle a softtty interrupt
@ -2254,6 +2221,7 @@ siosetwater(com, speed)
for (ibufsize = 128; ibufsize < cp4ticks;)
ibufsize <<= 1;
if (ibufsize == com->ibufsize) {
mtx_lock_spin(&sio_lock);
return (0);
}
@ -2263,6 +2231,7 @@ siosetwater(com, speed)
*/
ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT);
if (ibuf == NULL) {
mtx_lock_spin(&sio_lock);
return (ENOMEM);
}
@ -2280,9 +2249,7 @@ siosetwater(com, speed)
* Read current input buffer, if any. Continue with interrupts
* disabled.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->iptr != com->ibuf)
sioinput(com);
@ -2302,8 +2269,6 @@ siosetwater(com, speed)
com->ierroff = ibufsize;
com->ihighwater = ibuf + 3 * ibufsize / 4;
COM_UNLOCK();
restore_intr(intrsave);
return (0);
}
@ -2317,7 +2282,6 @@ comstart(tp)
bool_t started;
#endif
int unit;
int intrsave;
unit = DEV_TO_UNIT(tp->t_dev);
com = com_addr(unit);
@ -2328,9 +2292,7 @@ comstart(tp)
started = FALSE;
#endif
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (tp->t_state & TS_TTSTOP) {
com->state &= ~CS_TTGO;
if (com->intr_enable & CD1400_SRER_TXRDY)
@ -2366,8 +2328,7 @@ comstart(tp)
com->mcr_image |= com->mcr_rts);
#endif
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
ttwwakeup(tp);
splx(s);
@ -2386,9 +2347,7 @@ comstart(tp)
sizeof com->obuf1);
com->obufs[0].l_next = NULL;
com->obufs[0].l_queued = TRUE;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->state & CS_BUSY) {
qp = com->obufq.l_next;
while ((next = qp->l_next) != NULL)
@ -2407,8 +2366,7 @@ comstart(tp)
& ~CD1400_SRER_TXMPTY)
| CD1400_SRER_TXRDY);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
#ifdef CyDebug
@ -2419,9 +2377,7 @@ comstart(tp)
sizeof com->obuf2);
com->obufs[1].l_next = NULL;
com->obufs[1].l_queued = TRUE;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->state & CS_BUSY) {
qp = com->obufq.l_next;
while ((next = qp->l_next) != NULL)
@ -2440,8 +2396,7 @@ comstart(tp)
& ~CD1400_SRER_TXMPTY)
| CD1400_SRER_TXRDY);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
tp->t_state |= TS_BUSY;
}
@ -2450,13 +2405,10 @@ comstart(tp)
++com->start_real;
#endif
#if 0
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->state >= (CS_BUSY | CS_TTGO))
siointr1(com); /* fake interrupt to start output */
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#endif
ttwwakeup(tp);
splx(s);
@ -2469,13 +2421,10 @@ comstop(tp, rw)
{
struct com_s *com;
bool_t wakeup_etc;
int intrsave;
com = com_addr(DEV_TO_UNIT(tp->t_dev));
wakeup_etc = FALSE;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (rw & FWRITE) {
com->obufs[0].l_queued = FALSE;
com->obufs[1].l_queued = FALSE;
@ -2498,8 +2447,7 @@ comstop(tp, rw)
com_events -= (com->iptr - com->ibuf);
com->iptr = com->ibuf;
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (wakeup_etc)
wakeup(&com->etc);
if (rw & FWRITE && com->etc == ETC_NONE)
@ -2515,7 +2463,6 @@ commctl(com, bits, how)
{
int mcr;
int msr;
int intrsave;
if (how == DMGET) {
if (com->channel_control & CD1400_CCR_RCVEN)
@ -2553,9 +2500,7 @@ commctl(com, bits, how)
mcr |= com->mcr_dtr;
if (bits & TIOCM_RTS)
mcr |= com->mcr_rts;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
switch (how) {
case DMSET:
com->mcr_image = mcr;
@ -2573,8 +2518,7 @@ commctl(com, bits, how)
cd_setreg(com, CD1400_MSVR2, mcr);
break;
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
return (0);
}
@ -2636,14 +2580,9 @@ comwakeup(chan)
com = com_addr(unit);
if (com != NULL
&& (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
int intrsave;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
siointr1(com);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
}
#endif
@ -2663,15 +2602,11 @@ comwakeup(chan)
for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
u_int delta;
u_long total;
int intrsave;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
delta = com->delta_error_counts[errnum];
com->delta_error_counts[errnum] = 0;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (delta == 0)
continue;
total = com->error_counts[errnum] += delta;
@ -2823,7 +2758,6 @@ cd_etc(com, etc)
struct com_s *com;
int etc;
{
int intrsave;
/*
* We can't change the hardware's ETC state while there are any
@ -2836,9 +2770,7 @@ cd_etc(com, etc)
* for the tx to become empty so that the command is sure to be
* executed soon after we issue it.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->etc == etc)
goto wait;
if ((etc == CD1400_ETC_SENDBREAK
@ -2847,8 +2779,7 @@ cd_etc(com, etc)
|| (etc == CD1400_ETC_STOPBREAK
&& (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED
|| com->etc == ETC_NONE))) {
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
return;
}
com->etc = etc;
@ -2856,8 +2787,7 @@ cd_etc(com, etc)
com->intr_enable
= (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY);
wait:
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
while (com->etc == etc
&& tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0)
continue;
@ -2871,7 +2801,6 @@ cd_getreg(com, reg)
struct com_s *basecom;
u_char car;
int cy_align;
int intrsave;
cy_addr iobase;
int val;
@ -2879,16 +2808,11 @@ cd_getreg(com, reg)
car = com->unit & CD1400_CAR_CHAN;
cy_align = com->cy_align;
iobase = com->iobase;
intrsave = save_intr();
disable_intr();
if (intrsave & PSL_I)
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (basecom->car != car)
cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
val = cd_inb(iobase, reg, cy_align);
if (intrsave & PSL_I)
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
return (val);
}
@ -2901,23 +2825,17 @@ cd_setreg(com, reg, val)
struct com_s *basecom;
u_char car;
int cy_align;
int intrsave;
cy_addr iobase;
basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
car = com->unit & CD1400_CAR_CHAN;
cy_align = com->cy_align;
iobase = com->iobase;
intrsave = save_intr();
disable_intr();
if (intrsave & PSL_I)
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (basecom->car != car)
cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
cd_outb(iobase, reg, cy_align, val);
if (intrsave & PSL_I)
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
#ifdef CyDebug

View File

@ -133,7 +133,10 @@
#define siosetwater cysetwater
#define comstop cystop
#define siowrite cywrite
#define sio_ih cy_ih
#define sio_irec cy_irec
#define sio_lock cy_lock
#define sio_inited cy_inited
#define sio_timeout cy_timeout
#define sio_timeout_handle cy_timeout_handle
#define sio_timeouts_until_log cy_timeouts_until_log
@ -351,7 +354,9 @@ static void disc_optim __P((struct tty *tp, struct termios *t,
void cystatus __P((int unit));
#endif
static char driver_name[] = "cy";
static char driver_name[] = "cy";
static struct mtx sio_lock;
static int sio_inited;
/* table and macro for fast conversion from a unit number to its com struct */
static struct com_s *p_com_addr[NSIO];
@ -391,7 +396,7 @@ static struct cdevsw sio_cdevsw = {
static int comconsole = -1;
static speed_t comdefaultrate = TTYDEF_SPEED;
static u_int com_events; /* input chars + weighted output completions */
static struct intrhand *sio_ih;
static void *sio_ih;
static int sio_timeout;
static int sio_timeouts_until_log;
static struct callout_handle sio_timeout_handle
@ -428,6 +433,9 @@ sioprobe(dev)
iobase = (cy_addr)dev->id_maddr;
if (atomic_cmpset_int(&sio_inited, 0, 1))
mtx_init(&sio_lock, driver_name, MTX_SPIN);
/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
cy_inb(iobase, CY16_RESET, 0); /* XXX? */
DELAY(500); /* wait for the board to get its act together */
@ -595,9 +603,11 @@ cyattach_common(cy_iobase, cy_align)
com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
}
if (siosetwater(com, com->it_in.c_ispeed) != 0) {
mtx_unlock_spin(&sio_lock);
free(com, M_DEVBUF);
return (0);
}
mtx_unlock_spin(&sio_lock);
termioschars(&com->it_in);
com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
com->it_out = com->it_in;
@ -608,8 +618,8 @@ cyattach_common(cy_iobase, cy_align)
if (sio_ih == NULL) {
cdevsw_add(&sio_cdevsw);
sio_ih = sinthand_add("tty:sio", &tty_ithd, siopoll, NULL,
SWI_TTY, 0);
swi_add(&tty_ithd, "tty:cy", siopoll, NULL, SWI_TTY, 0,
&sio_ih);
}
make_dev(&sio_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter,
@ -651,7 +661,6 @@ sioopen(dev, flag, mode, p)
int s;
struct tty *tp;
int unit;
int intrsave;
mynor = minor(dev);
unit = MINOR_TO_UNIT(mynor);
@ -758,17 +767,14 @@ sioopen(dev, flag, mode, p)
}
}
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
(void) inb(com->line_status_port);
(void) inb(com->data_port);
com->prev_modem_status = com->last_modem_status
= inb(com->modem_status_port);
outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS
| IER_EMSC);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#else /* !0 */
/*
* Flush fifos. This requires a full channel reset which
@ -779,16 +785,13 @@ sioopen(dev, flag, mode, p)
CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET);
cd1400_channel_cmd(com, com->channel_control);
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com->prev_modem_status = com->last_modem_status
= cd_getreg(com, CD1400_MSVR2);
cd_setreg(com, CD1400_SRER,
com->intr_enable
= CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#endif /* 0 */
/*
* Handle initial DCD. Callout devices get a fake initial
@ -871,7 +874,6 @@ comhardclose(com)
int s;
struct tty *tp;
int unit;
int intrsave;
unit = com->unit;
iobase = com->iobase;
@ -885,13 +887,10 @@ comhardclose(com)
outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
#else
/* XXX */
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com->etc = ETC_NONE;
cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
#endif
@ -899,12 +898,9 @@ comhardclose(com)
#if 0
outb(iobase + com_ier, 0);
#else
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
cd_setreg(com, CD1400_SRER, com->intr_enable = 0);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#endif
tp = com->tp;
if ((tp->t_cflag & HUPCL)
@ -995,9 +991,8 @@ siodtrwakeup(chan)
}
/*
* This function:
* a) needs to be called with COM_LOCK() held, and
* b) needs to return with COM_LOCK() held.
* Call this function with the sio_lock mutex held. It will return with the
* lock still held.
*/
static void
sioinput(com)
@ -1008,7 +1003,6 @@ sioinput(com)
u_char line_status;
int recv_data;
struct tty *tp;
int intrsave;
buf = com->ibuf;
tp = com->tp;
@ -1032,9 +1026,7 @@ sioinput(com)
* semantics instead of the save-and-disable semantics
* that are used everywhere else.
*/
intrsave = save_intr();
COM_UNLOCK();
enable_intr();
mtx_unlock_spin(&sio_lock);
incc = com->iptr - buf;
if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
&& (com->state & CS_RTS_IFLOW
@ -1055,8 +1047,7 @@ sioinput(com)
tp->t_lflag &= ~FLUSHO;
comstart(tp);
}
restore_intr(intrsave);
COM_LOCK();
mtx_lock_spin(&sio_lock);
} while (buf < com->iptr);
} else {
do {
@ -1065,9 +1056,7 @@ sioinput(com)
* semantics instead of the save-and-disable semantics
* that are used everywhere else.
*/
intrsave = save_intr();
COM_UNLOCK();
enable_intr();
mtx_unlock_spin(&sio_lock);
line_status = buf[com->ierroff];
recv_data = *buf++;
if (line_status
@ -1082,8 +1071,7 @@ sioinput(com)
recv_data |= TTY_PE;
}
(*linesw[tp->t_line].l_rint)(recv_data, tp);
restore_intr(intrsave);
COM_LOCK();
mtx_lock_spin(&sio_lock);
} while (buf < com->iptr);
}
com_events -= (com->iptr - com->ibuf);
@ -1115,7 +1103,7 @@ siointr(unit)
cy_addr iobase;
u_char status;
COM_LOCK(); /* XXX could this be placed down lower in the loop? */
mtx_lock_spin(&sio_lock); /* XXX could this be placed down lower in the loop? */
baseu = unit * CY_MAX_PORTS;
cy_align = com_addr(baseu)->cy_align;
@ -1173,7 +1161,7 @@ siointr(unit)
#ifndef SOFT_HOTCHAR
if (line_status & CD1400_RDSR_SPECIAL
&& com->hotchar != 0)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
#if 1 /* XXX "intelligent" PFO error handling would break O error handling */
@ -1201,7 +1189,7 @@ siointr(unit)
++com->bytes_in;
#ifdef SOFT_HOTCHAR
if (com->hotchar != 0 && recv_data == com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
ioptr = com->iptr;
if (ioptr >= com->ibufend)
@ -1251,7 +1239,7 @@ siointr(unit)
if (com->hotchar != 0
&& recv_data
== com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
ioptr[0] = recv_data;
ioptr[com->ierroff] = 0;
@ -1266,7 +1254,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR
if (com->hotchar != 0
&& recv_data == com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
} while (--count != 0);
} else {
@ -1291,7 +1279,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR
if (com->hotchar != 0
&& recv_data == com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
ioptr[0] = recv_data;
ioptr[com->ierroff] = 0;
@ -1356,7 +1344,7 @@ siointr(unit)
if (!(com->state & CS_CHECKMSR)) {
com_events += LOTS_OF_EVENTS;
com->state |= CS_CHECKMSR;
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
#ifdef SOFT_CTS_OFLOW
@ -1487,7 +1475,7 @@ siointr(unit)
if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS;
com->state |= CS_ODONE;
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
break;
case ETC_BREAK_ENDED:
@ -1501,7 +1489,7 @@ siointr(unit)
if (!(com->extra_state & CSE_ODONE)) {
com_events += LOTS_OF_EVENTS;
com->extra_state |= CSE_ODONE;
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
cd_outb(iobase, CD1400_SRER, cy_align,
com->intr_enable
@ -1559,7 +1547,7 @@ siointr(unit)
com->state |= CS_ODONE;
/* handle at high level ASAP */
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
}
}
@ -1579,9 +1567,9 @@ siointr(unit)
/* ensure an edge for the next interrupt */
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
COM_UNLOCK();
mtx_unlock_spin(&sio_lock);
}
#if 0
@ -1756,7 +1744,6 @@ static void
siopoll(void *arg)
{
int unit;
int intrsave;
#ifdef CyDebug
++cy_timeouts;
@ -1779,9 +1766,7 @@ siopoll(void *arg)
* (actually never opened devices) so that we don't
* loop.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
incc = com->iptr - com->ibuf;
com->iptr = com->ibuf;
if (com->state & CS_CHECKMSR) {
@ -1789,8 +1774,7 @@ siopoll(void *arg)
com->state &= ~CS_CHECKMSR;
}
com_events -= incc;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (incc != 0)
log(LOG_DEBUG,
"sio%d: %d events for device with no tp\n",
@ -1798,39 +1782,30 @@ siopoll(void *arg)
continue;
}
if (com->iptr != com->ibuf) {
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
sioinput(com);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
if (com->state & CS_CHECKMSR) {
u_char delta_modem_status;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
sioinput(com);
delta_modem_status = com->last_modem_status
^ com->prev_modem_status;
com->prev_modem_status = com->last_modem_status;
com_events -= LOTS_OF_EVENTS;
com->state &= ~CS_CHECKMSR;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (delta_modem_status & MSR_DCD)
(*linesw[tp->t_line].l_modem)
(tp, com->prev_modem_status & MSR_DCD);
}
if (com->extra_state & CSE_ODONE) {
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com_events -= LOTS_OF_EVENTS;
com->extra_state &= ~CSE_ODONE;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (!(com->state & CS_BUSY)) {
tp->t_state &= ~TS_BUSY;
ttwwakeup(com->tp);
@ -1842,13 +1817,10 @@ siopoll(void *arg)
}
}
if (com->state & CS_ODONE) {
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com_events -= LOTS_OF_EVENTS;
com->state &= ~CS_ODONE;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
(*linesw[tp->t_line].l_start)(tp);
}
if (com_events == 0)
@ -1877,7 +1849,6 @@ comparam(tp, t)
u_char opt;
int s;
int unit;
int intrsave;
/* do historical conversions */
if (t->c_ispeed == 0)
@ -2025,15 +1996,11 @@ comparam(tp, t)
if (cflag & CCTS_OFLOW)
opt |= CD1400_COR2_CCTS_OFLOW;
#endif
intrsave = save_intr();
disable_intr();
COM_LOCK();
if (opt != com->cor[1]) {
cor_change |= CD1400_CCR_COR2;
cd_setreg(com, CD1400_COR2, com->cor[1] = opt);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
/*
* set channel option register 3 -
@ -2154,9 +2121,7 @@ comparam(tp, t)
* XXX should have done this long ago, but there is too much state
* to change all atomically.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com->state &= ~CS_TTGO;
if (!(tp->t_state & TS_TTSTOP))
@ -2222,8 +2187,7 @@ comparam(tp, t)
| CD1400_SRER_TXMPTY);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
splx(s);
comstart(tp);
if (com->ibufold != NULL) {
@ -2233,6 +2197,10 @@ comparam(tp, t)
return (0);
}
/*
* This function must be called with the sio_lock mutex released and will
* return with it obtained.
*/
static int
siosetwater(com, speed)
struct com_s *com;
@ -2242,7 +2210,6 @@ siosetwater(com, speed)
u_char *ibuf;
int ibufsize;
struct tty *tp;
int intrsave;
/*
* Make the buffer size large enough to handle a softtty interrupt
@ -2254,6 +2221,7 @@ siosetwater(com, speed)
for (ibufsize = 128; ibufsize < cp4ticks;)
ibufsize <<= 1;
if (ibufsize == com->ibufsize) {
mtx_lock_spin(&sio_lock);
return (0);
}
@ -2263,6 +2231,7 @@ siosetwater(com, speed)
*/
ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT);
if (ibuf == NULL) {
mtx_lock_spin(&sio_lock);
return (ENOMEM);
}
@ -2280,9 +2249,7 @@ siosetwater(com, speed)
* Read current input buffer, if any. Continue with interrupts
* disabled.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->iptr != com->ibuf)
sioinput(com);
@ -2302,8 +2269,6 @@ siosetwater(com, speed)
com->ierroff = ibufsize;
com->ihighwater = ibuf + 3 * ibufsize / 4;
COM_UNLOCK();
restore_intr(intrsave);
return (0);
}
@ -2317,7 +2282,6 @@ comstart(tp)
bool_t started;
#endif
int unit;
int intrsave;
unit = DEV_TO_UNIT(tp->t_dev);
com = com_addr(unit);
@ -2328,9 +2292,7 @@ comstart(tp)
started = FALSE;
#endif
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (tp->t_state & TS_TTSTOP) {
com->state &= ~CS_TTGO;
if (com->intr_enable & CD1400_SRER_TXRDY)
@ -2366,8 +2328,7 @@ comstart(tp)
com->mcr_image |= com->mcr_rts);
#endif
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
ttwwakeup(tp);
splx(s);
@ -2386,9 +2347,7 @@ comstart(tp)
sizeof com->obuf1);
com->obufs[0].l_next = NULL;
com->obufs[0].l_queued = TRUE;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->state & CS_BUSY) {
qp = com->obufq.l_next;
while ((next = qp->l_next) != NULL)
@ -2407,8 +2366,7 @@ comstart(tp)
& ~CD1400_SRER_TXMPTY)
| CD1400_SRER_TXRDY);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
#ifdef CyDebug
@ -2419,9 +2377,7 @@ comstart(tp)
sizeof com->obuf2);
com->obufs[1].l_next = NULL;
com->obufs[1].l_queued = TRUE;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->state & CS_BUSY) {
qp = com->obufq.l_next;
while ((next = qp->l_next) != NULL)
@ -2440,8 +2396,7 @@ comstart(tp)
& ~CD1400_SRER_TXMPTY)
| CD1400_SRER_TXRDY);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
tp->t_state |= TS_BUSY;
}
@ -2450,13 +2405,10 @@ comstart(tp)
++com->start_real;
#endif
#if 0
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->state >= (CS_BUSY | CS_TTGO))
siointr1(com); /* fake interrupt to start output */
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#endif
ttwwakeup(tp);
splx(s);
@ -2469,13 +2421,10 @@ comstop(tp, rw)
{
struct com_s *com;
bool_t wakeup_etc;
int intrsave;
com = com_addr(DEV_TO_UNIT(tp->t_dev));
wakeup_etc = FALSE;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (rw & FWRITE) {
com->obufs[0].l_queued = FALSE;
com->obufs[1].l_queued = FALSE;
@ -2498,8 +2447,7 @@ comstop(tp, rw)
com_events -= (com->iptr - com->ibuf);
com->iptr = com->ibuf;
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (wakeup_etc)
wakeup(&com->etc);
if (rw & FWRITE && com->etc == ETC_NONE)
@ -2515,7 +2463,6 @@ commctl(com, bits, how)
{
int mcr;
int msr;
int intrsave;
if (how == DMGET) {
if (com->channel_control & CD1400_CCR_RCVEN)
@ -2553,9 +2500,7 @@ commctl(com, bits, how)
mcr |= com->mcr_dtr;
if (bits & TIOCM_RTS)
mcr |= com->mcr_rts;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
switch (how) {
case DMSET:
com->mcr_image = mcr;
@ -2573,8 +2518,7 @@ commctl(com, bits, how)
cd_setreg(com, CD1400_MSVR2, mcr);
break;
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
return (0);
}
@ -2636,14 +2580,9 @@ comwakeup(chan)
com = com_addr(unit);
if (com != NULL
&& (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
int intrsave;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
siointr1(com);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
}
#endif
@ -2663,15 +2602,11 @@ comwakeup(chan)
for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
u_int delta;
u_long total;
int intrsave;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
delta = com->delta_error_counts[errnum];
com->delta_error_counts[errnum] = 0;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (delta == 0)
continue;
total = com->error_counts[errnum] += delta;
@ -2823,7 +2758,6 @@ cd_etc(com, etc)
struct com_s *com;
int etc;
{
int intrsave;
/*
* We can't change the hardware's ETC state while there are any
@ -2836,9 +2770,7 @@ cd_etc(com, etc)
* for the tx to become empty so that the command is sure to be
* executed soon after we issue it.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->etc == etc)
goto wait;
if ((etc == CD1400_ETC_SENDBREAK
@ -2847,8 +2779,7 @@ cd_etc(com, etc)
|| (etc == CD1400_ETC_STOPBREAK
&& (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED
|| com->etc == ETC_NONE))) {
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
return;
}
com->etc = etc;
@ -2856,8 +2787,7 @@ cd_etc(com, etc)
com->intr_enable
= (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY);
wait:
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
while (com->etc == etc
&& tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0)
continue;
@ -2871,7 +2801,6 @@ cd_getreg(com, reg)
struct com_s *basecom;
u_char car;
int cy_align;
int intrsave;
cy_addr iobase;
int val;
@ -2879,16 +2808,11 @@ cd_getreg(com, reg)
car = com->unit & CD1400_CAR_CHAN;
cy_align = com->cy_align;
iobase = com->iobase;
intrsave = save_intr();
disable_intr();
if (intrsave & PSL_I)
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (basecom->car != car)
cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
val = cd_inb(iobase, reg, cy_align);
if (intrsave & PSL_I)
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
return (val);
}
@ -2901,23 +2825,17 @@ cd_setreg(com, reg, val)
struct com_s *basecom;
u_char car;
int cy_align;
int intrsave;
cy_addr iobase;
basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
car = com->unit & CD1400_CAR_CHAN;
cy_align = com->cy_align;
iobase = com->iobase;
intrsave = save_intr();
disable_intr();
if (intrsave & PSL_I)
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (basecom->car != car)
cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
cd_outb(iobase, reg, cy_align, val);
if (intrsave & PSL_I)
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
#ifdef CyDebug

View File

@ -133,7 +133,10 @@
#define siosetwater cysetwater
#define comstop cystop
#define siowrite cywrite
#define sio_ih cy_ih
#define sio_irec cy_irec
#define sio_lock cy_lock
#define sio_inited cy_inited
#define sio_timeout cy_timeout
#define sio_timeout_handle cy_timeout_handle
#define sio_timeouts_until_log cy_timeouts_until_log
@ -351,7 +354,9 @@ static void disc_optim __P((struct tty *tp, struct termios *t,
void cystatus __P((int unit));
#endif
static char driver_name[] = "cy";
static char driver_name[] = "cy";
static struct mtx sio_lock;
static int sio_inited;
/* table and macro for fast conversion from a unit number to its com struct */
static struct com_s *p_com_addr[NSIO];
@ -391,7 +396,7 @@ static struct cdevsw sio_cdevsw = {
static int comconsole = -1;
static speed_t comdefaultrate = TTYDEF_SPEED;
static u_int com_events; /* input chars + weighted output completions */
static struct intrhand *sio_ih;
static void *sio_ih;
static int sio_timeout;
static int sio_timeouts_until_log;
static struct callout_handle sio_timeout_handle
@ -428,6 +433,9 @@ sioprobe(dev)
iobase = (cy_addr)dev->id_maddr;
if (atomic_cmpset_int(&sio_inited, 0, 1))
mtx_init(&sio_lock, driver_name, MTX_SPIN);
/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
cy_inb(iobase, CY16_RESET, 0); /* XXX? */
DELAY(500); /* wait for the board to get its act together */
@ -595,9 +603,11 @@ cyattach_common(cy_iobase, cy_align)
com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
}
if (siosetwater(com, com->it_in.c_ispeed) != 0) {
mtx_unlock_spin(&sio_lock);
free(com, M_DEVBUF);
return (0);
}
mtx_unlock_spin(&sio_lock);
termioschars(&com->it_in);
com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
com->it_out = com->it_in;
@ -608,8 +618,8 @@ cyattach_common(cy_iobase, cy_align)
if (sio_ih == NULL) {
cdevsw_add(&sio_cdevsw);
sio_ih = sinthand_add("tty:sio", &tty_ithd, siopoll, NULL,
SWI_TTY, 0);
swi_add(&tty_ithd, "tty:cy", siopoll, NULL, SWI_TTY, 0,
&sio_ih);
}
make_dev(&sio_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter,
@ -651,7 +661,6 @@ sioopen(dev, flag, mode, p)
int s;
struct tty *tp;
int unit;
int intrsave;
mynor = minor(dev);
unit = MINOR_TO_UNIT(mynor);
@ -758,17 +767,14 @@ sioopen(dev, flag, mode, p)
}
}
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
(void) inb(com->line_status_port);
(void) inb(com->data_port);
com->prev_modem_status = com->last_modem_status
= inb(com->modem_status_port);
outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS
| IER_EMSC);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#else /* !0 */
/*
* Flush fifos. This requires a full channel reset which
@ -779,16 +785,13 @@ sioopen(dev, flag, mode, p)
CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET);
cd1400_channel_cmd(com, com->channel_control);
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com->prev_modem_status = com->last_modem_status
= cd_getreg(com, CD1400_MSVR2);
cd_setreg(com, CD1400_SRER,
com->intr_enable
= CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#endif /* 0 */
/*
* Handle initial DCD. Callout devices get a fake initial
@ -871,7 +874,6 @@ comhardclose(com)
int s;
struct tty *tp;
int unit;
int intrsave;
unit = com->unit;
iobase = com->iobase;
@ -885,13 +887,10 @@ comhardclose(com)
outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
#else
/* XXX */
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com->etc = ETC_NONE;
cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
#endif
@ -899,12 +898,9 @@ comhardclose(com)
#if 0
outb(iobase + com_ier, 0);
#else
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
cd_setreg(com, CD1400_SRER, com->intr_enable = 0);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#endif
tp = com->tp;
if ((tp->t_cflag & HUPCL)
@ -995,9 +991,8 @@ siodtrwakeup(chan)
}
/*
* This function:
* a) needs to be called with COM_LOCK() held, and
* b) needs to return with COM_LOCK() held.
* Call this function with the sio_lock mutex held. It will return with the
* lock still held.
*/
static void
sioinput(com)
@ -1008,7 +1003,6 @@ sioinput(com)
u_char line_status;
int recv_data;
struct tty *tp;
int intrsave;
buf = com->ibuf;
tp = com->tp;
@ -1032,9 +1026,7 @@ sioinput(com)
* semantics instead of the save-and-disable semantics
* that are used everywhere else.
*/
intrsave = save_intr();
COM_UNLOCK();
enable_intr();
mtx_unlock_spin(&sio_lock);
incc = com->iptr - buf;
if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
&& (com->state & CS_RTS_IFLOW
@ -1055,8 +1047,7 @@ sioinput(com)
tp->t_lflag &= ~FLUSHO;
comstart(tp);
}
restore_intr(intrsave);
COM_LOCK();
mtx_lock_spin(&sio_lock);
} while (buf < com->iptr);
} else {
do {
@ -1065,9 +1056,7 @@ sioinput(com)
* semantics instead of the save-and-disable semantics
* that are used everywhere else.
*/
intrsave = save_intr();
COM_UNLOCK();
enable_intr();
mtx_unlock_spin(&sio_lock);
line_status = buf[com->ierroff];
recv_data = *buf++;
if (line_status
@ -1082,8 +1071,7 @@ sioinput(com)
recv_data |= TTY_PE;
}
(*linesw[tp->t_line].l_rint)(recv_data, tp);
restore_intr(intrsave);
COM_LOCK();
mtx_lock_spin(&sio_lock);
} while (buf < com->iptr);
}
com_events -= (com->iptr - com->ibuf);
@ -1115,7 +1103,7 @@ siointr(unit)
cy_addr iobase;
u_char status;
COM_LOCK(); /* XXX could this be placed down lower in the loop? */
mtx_lock_spin(&sio_lock); /* XXX could this be placed down lower in the loop? */
baseu = unit * CY_MAX_PORTS;
cy_align = com_addr(baseu)->cy_align;
@ -1173,7 +1161,7 @@ siointr(unit)
#ifndef SOFT_HOTCHAR
if (line_status & CD1400_RDSR_SPECIAL
&& com->hotchar != 0)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
#if 1 /* XXX "intelligent" PFO error handling would break O error handling */
@ -1201,7 +1189,7 @@ siointr(unit)
++com->bytes_in;
#ifdef SOFT_HOTCHAR
if (com->hotchar != 0 && recv_data == com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
ioptr = com->iptr;
if (ioptr >= com->ibufend)
@ -1251,7 +1239,7 @@ siointr(unit)
if (com->hotchar != 0
&& recv_data
== com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
ioptr[0] = recv_data;
ioptr[com->ierroff] = 0;
@ -1266,7 +1254,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR
if (com->hotchar != 0
&& recv_data == com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
} while (--count != 0);
} else {
@ -1291,7 +1279,7 @@ siointr(unit)
#ifdef SOFT_HOTCHAR
if (com->hotchar != 0
&& recv_data == com->hotchar)
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
#endif
ioptr[0] = recv_data;
ioptr[com->ierroff] = 0;
@ -1356,7 +1344,7 @@ siointr(unit)
if (!(com->state & CS_CHECKMSR)) {
com_events += LOTS_OF_EVENTS;
com->state |= CS_CHECKMSR;
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
#ifdef SOFT_CTS_OFLOW
@ -1487,7 +1475,7 @@ siointr(unit)
if (!(com->state & CS_ODONE)) {
com_events += LOTS_OF_EVENTS;
com->state |= CS_ODONE;
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
break;
case ETC_BREAK_ENDED:
@ -1501,7 +1489,7 @@ siointr(unit)
if (!(com->extra_state & CSE_ODONE)) {
com_events += LOTS_OF_EVENTS;
com->extra_state |= CSE_ODONE;
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
cd_outb(iobase, CD1400_SRER, cy_align,
com->intr_enable
@ -1559,7 +1547,7 @@ siointr(unit)
com->state |= CS_ODONE;
/* handle at high level ASAP */
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
}
}
}
@ -1579,9 +1567,9 @@ siointr(unit)
/* ensure an edge for the next interrupt */
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
sched_swi(sio_ih, SWI_NOSWITCH);
swi_sched(sio_ih, SWI_NOSWITCH);
COM_UNLOCK();
mtx_unlock_spin(&sio_lock);
}
#if 0
@ -1756,7 +1744,6 @@ static void
siopoll(void *arg)
{
int unit;
int intrsave;
#ifdef CyDebug
++cy_timeouts;
@ -1779,9 +1766,7 @@ siopoll(void *arg)
* (actually never opened devices) so that we don't
* loop.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
incc = com->iptr - com->ibuf;
com->iptr = com->ibuf;
if (com->state & CS_CHECKMSR) {
@ -1789,8 +1774,7 @@ siopoll(void *arg)
com->state &= ~CS_CHECKMSR;
}
com_events -= incc;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (incc != 0)
log(LOG_DEBUG,
"sio%d: %d events for device with no tp\n",
@ -1798,39 +1782,30 @@ siopoll(void *arg)
continue;
}
if (com->iptr != com->ibuf) {
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
sioinput(com);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
if (com->state & CS_CHECKMSR) {
u_char delta_modem_status;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
sioinput(com);
delta_modem_status = com->last_modem_status
^ com->prev_modem_status;
com->prev_modem_status = com->last_modem_status;
com_events -= LOTS_OF_EVENTS;
com->state &= ~CS_CHECKMSR;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (delta_modem_status & MSR_DCD)
(*linesw[tp->t_line].l_modem)
(tp, com->prev_modem_status & MSR_DCD);
}
if (com->extra_state & CSE_ODONE) {
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com_events -= LOTS_OF_EVENTS;
com->extra_state &= ~CSE_ODONE;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (!(com->state & CS_BUSY)) {
tp->t_state &= ~TS_BUSY;
ttwwakeup(com->tp);
@ -1842,13 +1817,10 @@ siopoll(void *arg)
}
}
if (com->state & CS_ODONE) {
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com_events -= LOTS_OF_EVENTS;
com->state &= ~CS_ODONE;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
(*linesw[tp->t_line].l_start)(tp);
}
if (com_events == 0)
@ -1877,7 +1849,6 @@ comparam(tp, t)
u_char opt;
int s;
int unit;
int intrsave;
/* do historical conversions */
if (t->c_ispeed == 0)
@ -2025,15 +1996,11 @@ comparam(tp, t)
if (cflag & CCTS_OFLOW)
opt |= CD1400_COR2_CCTS_OFLOW;
#endif
intrsave = save_intr();
disable_intr();
COM_LOCK();
if (opt != com->cor[1]) {
cor_change |= CD1400_CCR_COR2;
cd_setreg(com, CD1400_COR2, com->cor[1] = opt);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
/*
* set channel option register 3 -
@ -2154,9 +2121,7 @@ comparam(tp, t)
* XXX should have done this long ago, but there is too much state
* to change all atomically.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
com->state &= ~CS_TTGO;
if (!(tp->t_state & TS_TTSTOP))
@ -2222,8 +2187,7 @@ comparam(tp, t)
| CD1400_SRER_TXMPTY);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
splx(s);
comstart(tp);
if (com->ibufold != NULL) {
@ -2233,6 +2197,10 @@ comparam(tp, t)
return (0);
}
/*
* This function must be called with the sio_lock mutex released and will
* return with it obtained.
*/
static int
siosetwater(com, speed)
struct com_s *com;
@ -2242,7 +2210,6 @@ siosetwater(com, speed)
u_char *ibuf;
int ibufsize;
struct tty *tp;
int intrsave;
/*
* Make the buffer size large enough to handle a softtty interrupt
@ -2254,6 +2221,7 @@ siosetwater(com, speed)
for (ibufsize = 128; ibufsize < cp4ticks;)
ibufsize <<= 1;
if (ibufsize == com->ibufsize) {
mtx_lock_spin(&sio_lock);
return (0);
}
@ -2263,6 +2231,7 @@ siosetwater(com, speed)
*/
ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT);
if (ibuf == NULL) {
mtx_lock_spin(&sio_lock);
return (ENOMEM);
}
@ -2280,9 +2249,7 @@ siosetwater(com, speed)
* Read current input buffer, if any. Continue with interrupts
* disabled.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->iptr != com->ibuf)
sioinput(com);
@ -2302,8 +2269,6 @@ siosetwater(com, speed)
com->ierroff = ibufsize;
com->ihighwater = ibuf + 3 * ibufsize / 4;
COM_UNLOCK();
restore_intr(intrsave);
return (0);
}
@ -2317,7 +2282,6 @@ comstart(tp)
bool_t started;
#endif
int unit;
int intrsave;
unit = DEV_TO_UNIT(tp->t_dev);
com = com_addr(unit);
@ -2328,9 +2292,7 @@ comstart(tp)
started = FALSE;
#endif
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (tp->t_state & TS_TTSTOP) {
com->state &= ~CS_TTGO;
if (com->intr_enable & CD1400_SRER_TXRDY)
@ -2366,8 +2328,7 @@ comstart(tp)
com->mcr_image |= com->mcr_rts);
#endif
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
ttwwakeup(tp);
splx(s);
@ -2386,9 +2347,7 @@ comstart(tp)
sizeof com->obuf1);
com->obufs[0].l_next = NULL;
com->obufs[0].l_queued = TRUE;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->state & CS_BUSY) {
qp = com->obufq.l_next;
while ((next = qp->l_next) != NULL)
@ -2407,8 +2366,7 @@ comstart(tp)
& ~CD1400_SRER_TXMPTY)
| CD1400_SRER_TXRDY);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
#ifdef CyDebug
@ -2419,9 +2377,7 @@ comstart(tp)
sizeof com->obuf2);
com->obufs[1].l_next = NULL;
com->obufs[1].l_queued = TRUE;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->state & CS_BUSY) {
qp = com->obufq.l_next;
while ((next = qp->l_next) != NULL)
@ -2440,8 +2396,7 @@ comstart(tp)
& ~CD1400_SRER_TXMPTY)
| CD1400_SRER_TXRDY);
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
tp->t_state |= TS_BUSY;
}
@ -2450,13 +2405,10 @@ comstart(tp)
++com->start_real;
#endif
#if 0
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->state >= (CS_BUSY | CS_TTGO))
siointr1(com); /* fake interrupt to start output */
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
#endif
ttwwakeup(tp);
splx(s);
@ -2469,13 +2421,10 @@ comstop(tp, rw)
{
struct com_s *com;
bool_t wakeup_etc;
int intrsave;
com = com_addr(DEV_TO_UNIT(tp->t_dev));
wakeup_etc = FALSE;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (rw & FWRITE) {
com->obufs[0].l_queued = FALSE;
com->obufs[1].l_queued = FALSE;
@ -2498,8 +2447,7 @@ comstop(tp, rw)
com_events -= (com->iptr - com->ibuf);
com->iptr = com->ibuf;
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (wakeup_etc)
wakeup(&com->etc);
if (rw & FWRITE && com->etc == ETC_NONE)
@ -2515,7 +2463,6 @@ commctl(com, bits, how)
{
int mcr;
int msr;
int intrsave;
if (how == DMGET) {
if (com->channel_control & CD1400_CCR_RCVEN)
@ -2553,9 +2500,7 @@ commctl(com, bits, how)
mcr |= com->mcr_dtr;
if (bits & TIOCM_RTS)
mcr |= com->mcr_rts;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
switch (how) {
case DMSET:
com->mcr_image = mcr;
@ -2573,8 +2518,7 @@ commctl(com, bits, how)
cd_setreg(com, CD1400_MSVR2, mcr);
break;
}
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
return (0);
}
@ -2636,14 +2580,9 @@ comwakeup(chan)
com = com_addr(unit);
if (com != NULL
&& (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
int intrsave;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
siointr1(com);
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
}
#endif
@ -2663,15 +2602,11 @@ comwakeup(chan)
for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
u_int delta;
u_long total;
int intrsave;
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
delta = com->delta_error_counts[errnum];
com->delta_error_counts[errnum] = 0;
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
if (delta == 0)
continue;
total = com->error_counts[errnum] += delta;
@ -2823,7 +2758,6 @@ cd_etc(com, etc)
struct com_s *com;
int etc;
{
int intrsave;
/*
* We can't change the hardware's ETC state while there are any
@ -2836,9 +2770,7 @@ cd_etc(com, etc)
* for the tx to become empty so that the command is sure to be
* executed soon after we issue it.
*/
intrsave = save_intr();
disable_intr();
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (com->etc == etc)
goto wait;
if ((etc == CD1400_ETC_SENDBREAK
@ -2847,8 +2779,7 @@ cd_etc(com, etc)
|| (etc == CD1400_ETC_STOPBREAK
&& (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED
|| com->etc == ETC_NONE))) {
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
return;
}
com->etc = etc;
@ -2856,8 +2787,7 @@ cd_etc(com, etc)
com->intr_enable
= (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY);
wait:
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
while (com->etc == etc
&& tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0)
continue;
@ -2871,7 +2801,6 @@ cd_getreg(com, reg)
struct com_s *basecom;
u_char car;
int cy_align;
int intrsave;
cy_addr iobase;
int val;
@ -2879,16 +2808,11 @@ cd_getreg(com, reg)
car = com->unit & CD1400_CAR_CHAN;
cy_align = com->cy_align;
iobase = com->iobase;
intrsave = save_intr();
disable_intr();
if (intrsave & PSL_I)
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (basecom->car != car)
cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
val = cd_inb(iobase, reg, cy_align);
if (intrsave & PSL_I)
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
return (val);
}
@ -2901,23 +2825,17 @@ cd_setreg(com, reg, val)
struct com_s *basecom;
u_char car;
int cy_align;
int intrsave;
cy_addr iobase;
basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
car = com->unit & CD1400_CAR_CHAN;
cy_align = com->cy_align;
iobase = com->iobase;
intrsave = save_intr();
disable_intr();
if (intrsave & PSL_I)
COM_LOCK();
mtx_lock_spin(&sio_lock);
if (basecom->car != car)
cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
cd_outb(iobase, reg, cy_align, val);
if (intrsave & PSL_I)
COM_UNLOCK();
restore_intr(intrsave);
mtx_unlock_spin(&sio_lock);
}
#ifdef CyDebug