diff options
author | fsmp <fsmp@FreeBSD.org> | 1997-08-20 05:25:48 +0000 |
---|---|---|
committer | fsmp <fsmp@FreeBSD.org> | 1997-08-20 05:25:48 +0000 |
commit | 2c414e3eff799c18e5d3e8edfe37d7dc71f35c7a (patch) | |
tree | 4060f694285dcb8b0a5d572747820da61322b0df /sys/dev | |
parent | ea72b8e976791b005527662091bc146ad0bfd3b6 (diff) | |
download | FreeBSD-src-2c414e3eff799c18e5d3e8edfe37d7dc71f35c7a.zip FreeBSD-src-2c414e3eff799c18e5d3e8edfe37d7dc71f35c7a.tar.gz |
Preperation for moving cpl into critical region access.
Several new fine-grained locks.
New FAST_INTR() methods:
- separate simplelock for FAST_INTR, no more giant lock.
- FAST_INTR()s no longer checks ipending on way out of ISR.
sio made MP-safe (I hope).
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/sio/sio.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index 55944b2..5249698 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.1 1997/08/04 17:58:18 smp Exp smp $ + * $Id: sio.c,v 1.174 1997/08/04 19:12:54 fsmp Exp $ */ #include "opt_comconsole.h" @@ -82,6 +82,15 @@ #include <pccard/slot.h> #endif +#ifdef SMP +#include <machine/smp.h> +#define COM_LOCK() s_lock(&com_lock) +#define COM_UNLOCK() s_unlock(&com_lock) +#else +#define COM_LOCK() +#define COM_UNLOCK() +#endif /* SMP */ + #ifdef APIC_IO /* * INTs are masked in the (global) IO APIC, @@ -559,9 +568,11 @@ static int card_intr(struct pccard_dev *dp) { struct com_s *com; + COM_LOCK(); com = com_addr(dp->isahd.id_unit); if (com && !com_addr(dp->isahd.id_unit)->gone) siointr1(com_addr(dp->isahd.id_unit)); + COM_UNLOCK(); return(1); } #endif /* NCRD > 0 */ @@ -1183,12 +1194,14 @@ open_top: } disable_intr(); + COM_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(); enable_intr(); /* * Handle initial DCD. Callout devices get a fake initial @@ -1417,7 +1430,9 @@ siointr(unit) int unit; { #ifndef COM_MULTIPORT + COM_LOCK(); siointr1(com_addr(unit)); + COM_UNLOCK(); #else /* COM_MULTIPORT */ struct com_s *com; bool_t possibly_more_intrs; @@ -1429,6 +1444,7 @@ siointr(unit) * devices, then the edge from one may be lost because another is * on. */ + COM_LOCK(); do { possibly_more_intrs = FALSE; for (unit = 0; unit < NSIO; ++unit) { @@ -1442,6 +1458,7 @@ siointr(unit) } } } while (possibly_more_intrs); + COM_UNLOCK(); #endif /* COM_MULTIPORT */ } @@ -1821,6 +1838,7 @@ repeat: * loop. */ disable_intr(); + COM_LOCK(); incc = com->iptr - com->ibuf; com->iptr = com->ibuf; if (com->state & CS_CHECKMSR) { @@ -1828,6 +1846,7 @@ repeat: com->state &= ~CS_CHECKMSR; } com_events -= incc; + COM_UNLOCK(); enable_intr(); if (incc != 0) log(LOG_DEBUG, @@ -1843,6 +1862,7 @@ repeat: } else { buf = ibuf; disable_intr(); + COM_LOCK(); incc = com->iptr - buf; com_events -= incc; if (ibuf == com->ibuf1) @@ -1863,6 +1883,7 @@ repeat: && !(tp->t_state & TS_TBLOCK)) outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); + COM_UNLOCK(); enable_intr(); com->ibuf = ibuf; } @@ -1871,11 +1892,13 @@ repeat: u_char delta_modem_status; disable_intr(); + COM_LOCK(); 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(); enable_intr(); if (delta_modem_status & MSR_DCD) (*linesw[tp->t_line].l_modem) @@ -1883,8 +1906,10 @@ repeat: } if (com->state & CS_ODONE) { disable_intr(); + COM_LOCK(); com_events -= LOTS_OF_EVENTS; com->state &= ~CS_ODONE; + COM_UNLOCK(); enable_intr(); if (!(com->state & CS_BUSY) && !(com->extra_state & CSE_BUSYCHECK)) { @@ -2040,9 +2065,11 @@ comparam(tp, t) * error bits, but that is acceptable here. */ disable_intr(); + COM_LOCK(); retry: com->state &= ~CS_TTGO; txtimeout = tp->t_timeout; + COM_UNLOCK(); enable_intr(); while ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY)) != (LSR_TSRE | LSR_TXRDY)) { @@ -2059,7 +2086,9 @@ retry: if (error != 0 && error != EAGAIN) { if (!(tp->t_state & TS_TTSTOP)) { disable_intr(); + COM_LOCK(); com->state |= CS_TTGO; + COM_UNLOCK(); enable_intr(); } splx(s); @@ -2068,6 +2097,7 @@ retry: } disable_intr(); /* very important while com_data is hidden */ + COM_LOCK(); /* * XXX - clearing CS_TTGO is not sufficient to stop further output, @@ -2163,6 +2193,7 @@ retry: if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); + COM_UNLOCK(); enable_intr(); splx(s); comstart(tp); @@ -2181,6 +2212,7 @@ comstart(tp) com = com_addr(unit); s = spltty(); disable_intr(); + COM_LOCK(); if (tp->t_state & TS_TTSTOP) com->state &= ~CS_TTGO; else @@ -2193,6 +2225,7 @@ comstart(tp) && com->state & CS_RTS_IFLOW) outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); } + COM_UNLOCK(); enable_intr(); if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { splx(s); @@ -2209,6 +2242,7 @@ comstart(tp) com->obufs[0].l_next = NULL; com->obufs[0].l_queued = TRUE; disable_intr(); + COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2220,6 +2254,7 @@ comstart(tp) com->obufq.l_next = &com->obufs[0]; com->state |= CS_BUSY; } + COM_UNLOCK(); enable_intr(); } if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { @@ -2229,6 +2264,7 @@ comstart(tp) com->obufs[1].l_next = NULL; com->obufs[1].l_queued = TRUE; disable_intr(); + COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2240,13 +2276,16 @@ comstart(tp) com->obufq.l_next = &com->obufs[1]; com->state |= CS_BUSY; } + COM_UNLOCK(); enable_intr(); } tp->t_state |= TS_BUSY; } disable_intr(); + COM_LOCK(); if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); /* fake interrupt to start output */ + COM_UNLOCK(); enable_intr(); ttwwakeup(tp); splx(s); @@ -2263,6 +2302,7 @@ siostop(tp, rw) if (com->gone) return; disable_intr(); + COM_LOCK(); if (rw & FWRITE) { if (com->hasfifo) #ifdef COM_ESP @@ -2291,6 +2331,7 @@ siostop(tp, rw) com_events -= (com->iptr - com->ibuf); com->iptr = com->ibuf; } + COM_UNLOCK(); enable_intr(); comstart(tp); } @@ -2351,6 +2392,7 @@ commctl(com, bits, how) if (com->gone) return(0); disable_intr(); + COM_LOCK(); switch (how) { case DMSET: outb(com->modem_ctl_port, @@ -2363,6 +2405,7 @@ commctl(com, bits, how) outb(com->modem_ctl_port, com->mcr_image &= ~mcr); break; } + COM_UNLOCK(); enable_intr(); return (0); } @@ -2422,7 +2465,9 @@ comwakeup(chan) if (com != NULL && !com->gone && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { disable_intr(); + COM_LOCK(); siointr1(com); + COM_UNLOCK(); enable_intr(); } } @@ -2446,8 +2491,10 @@ comwakeup(chan) u_long total; disable_intr(); + COM_LOCK(); delta = com->delta_error_counts[errnum]; com->delta_error_counts[errnum] = 0; + COM_UNLOCK(); enable_intr(); if (delta == 0) continue; |