diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c index 9fef976e4074..2d26234fe706 100644 --- a/sys/pc98/cbus/sio.c +++ b/sys/pc98/cbus/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.31 1997/07/21 13:11:12 kato Exp $ + * $Id: sio.c,v 1.32 1997/08/06 09:42:57 kato Exp $ */ #include "opt_comconsole.h" @@ -160,6 +160,15 @@ #include #endif +#ifdef SMP +#include +#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, @@ -791,9 +800,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 */ @@ -1549,6 +1560,7 @@ open_top: } disable_intr(); + COM_LOCK(); #ifdef PC98 if(IS_8251(com->pc98_if_type)){ com_tiocm_bis(com, TIOCM_LE); @@ -1566,6 +1578,7 @@ open_top: #ifdef PC98 } #endif + COM_UNLOCK(); enable_intr(); /* * Handle initial DCD. Callout devices get a fake initial @@ -1845,7 +1858,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; @@ -1857,6 +1872,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) { @@ -1877,6 +1893,7 @@ siointr(unit) } } } while (possibly_more_intrs); + COM_UNLOCK(); #endif /* COM_MULTIPORT */ } @@ -2383,6 +2400,7 @@ repeat: * loop. */ disable_intr(); + COM_LOCK(); incc = com->iptr - com->ibuf; com->iptr = com->ibuf; if (com->state & CS_CHECKMSR) { @@ -2390,6 +2408,7 @@ repeat: com->state &= ~CS_CHECKMSR; } com_events -= incc; + COM_UNLOCK(); enable_intr(); if (incc != 0) log(LOG_DEBUG, @@ -2405,6 +2424,7 @@ repeat: } else { buf = ibuf; disable_intr(); + COM_LOCK(); incc = com->iptr - buf; com_events -= incc; if (ibuf == com->ibuf1) @@ -2440,6 +2460,7 @@ repeat: #endif outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); + COM_UNLOCK(); enable_intr(); com->ibuf = ibuf; } @@ -2451,11 +2472,13 @@ repeat: if(!IS_8251(com->pc98_if_type)){ #endif 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) @@ -2466,8 +2489,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)) { @@ -2655,9 +2680,11 @@ comparam(tp, t) } #endif disable_intr(); + COM_LOCK(); retry: com->state &= ~CS_TTGO; txtimeout = tp->t_timeout; + COM_UNLOCK(); enable_intr(); #ifdef PC98 if(IS_8251(com->pc98_if_type)){ @@ -2685,7 +2712,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); @@ -2694,6 +2723,7 @@ retry: } disable_intr(); /* very important while com_data is hidden */ + COM_LOCK(); /* * XXX - clearing CS_TTGO is not sufficient to stop further output, @@ -2814,6 +2844,7 @@ retry: if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); + COM_UNLOCK(); enable_intr(); splx(s); comstart(tp); @@ -2835,6 +2866,7 @@ comstart(tp) com = com_addr(unit); s = spltty(); disable_intr(); + COM_LOCK(); if (tp->t_state & TS_TTSTOP) com->state &= ~CS_TTGO; else @@ -2874,6 +2906,7 @@ comstart(tp) #endif outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); } + COM_UNLOCK(); enable_intr(); if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { #ifdef PC98 @@ -2894,6 +2927,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) @@ -2905,6 +2939,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) { @@ -2914,6 +2949,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) @@ -2925,13 +2961,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(); #ifdef PC98 /* if(IS_8251(com->pc98_if_type)) @@ -2952,6 +2991,7 @@ siostop(tp, rw) if (com->gone) return; disable_intr(); + COM_LOCK(); if (rw & FWRITE) { if (com->hasfifo) #ifdef COM_ESP @@ -2980,6 +3020,7 @@ siostop(tp, rw) com_events -= (com->iptr - com->ibuf); com->iptr = com->ibuf; } + COM_UNLOCK(); enable_intr(); comstart(tp); } @@ -3040,6 +3081,7 @@ commctl(com, bits, how) if (com->gone) return(0); disable_intr(); + COM_LOCK(); switch (how) { case DMSET: outb(com->modem_ctl_port, @@ -3052,6 +3094,7 @@ commctl(com, bits, how) outb(com->modem_ctl_port, com->mcr_image &= ~mcr); break; } + COM_UNLOCK(); enable_intr(); return (0); } @@ -3111,7 +3154,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(); } } @@ -3135,8 +3180,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; diff --git a/sys/pc98/i386/trap.c b/sys/pc98/i386/trap.c index 4727c1a02099..7d4df49366a2 100644 --- a/sys/pc98/i386/trap.c +++ b/sys/pc98/i386/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.29 1997/08/13 11:00:09 kato Exp $ + * $Id: trap.c,v 1.30 1997/08/18 11:29:58 kato Exp $ */ /* @@ -828,6 +828,14 @@ trap_fatal(frame) printf("bio "); if (cpl == 0) printf("none"); +#ifdef SMP +/** + * XXX FIXME: + * we probably SHOULD have stopped the other CPUs before now! + * another CPU COULD have been touching cpl at this moment... + */ + printf(" <- SMP: XXX"); +#endif printf("\n"); #ifdef KDB diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c index 9fef976e4074..2d26234fe706 100644 --- a/sys/pc98/pc98/sio.c +++ b/sys/pc98/pc98/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.31 1997/07/21 13:11:12 kato Exp $ + * $Id: sio.c,v 1.32 1997/08/06 09:42:57 kato Exp $ */ #include "opt_comconsole.h" @@ -160,6 +160,15 @@ #include #endif +#ifdef SMP +#include +#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, @@ -791,9 +800,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 */ @@ -1549,6 +1560,7 @@ open_top: } disable_intr(); + COM_LOCK(); #ifdef PC98 if(IS_8251(com->pc98_if_type)){ com_tiocm_bis(com, TIOCM_LE); @@ -1566,6 +1578,7 @@ open_top: #ifdef PC98 } #endif + COM_UNLOCK(); enable_intr(); /* * Handle initial DCD. Callout devices get a fake initial @@ -1845,7 +1858,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; @@ -1857,6 +1872,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) { @@ -1877,6 +1893,7 @@ siointr(unit) } } } while (possibly_more_intrs); + COM_UNLOCK(); #endif /* COM_MULTIPORT */ } @@ -2383,6 +2400,7 @@ repeat: * loop. */ disable_intr(); + COM_LOCK(); incc = com->iptr - com->ibuf; com->iptr = com->ibuf; if (com->state & CS_CHECKMSR) { @@ -2390,6 +2408,7 @@ repeat: com->state &= ~CS_CHECKMSR; } com_events -= incc; + COM_UNLOCK(); enable_intr(); if (incc != 0) log(LOG_DEBUG, @@ -2405,6 +2424,7 @@ repeat: } else { buf = ibuf; disable_intr(); + COM_LOCK(); incc = com->iptr - buf; com_events -= incc; if (ibuf == com->ibuf1) @@ -2440,6 +2460,7 @@ repeat: #endif outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); + COM_UNLOCK(); enable_intr(); com->ibuf = ibuf; } @@ -2451,11 +2472,13 @@ repeat: if(!IS_8251(com->pc98_if_type)){ #endif 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) @@ -2466,8 +2489,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)) { @@ -2655,9 +2680,11 @@ comparam(tp, t) } #endif disable_intr(); + COM_LOCK(); retry: com->state &= ~CS_TTGO; txtimeout = tp->t_timeout; + COM_UNLOCK(); enable_intr(); #ifdef PC98 if(IS_8251(com->pc98_if_type)){ @@ -2685,7 +2712,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); @@ -2694,6 +2723,7 @@ retry: } disable_intr(); /* very important while com_data is hidden */ + COM_LOCK(); /* * XXX - clearing CS_TTGO is not sufficient to stop further output, @@ -2814,6 +2844,7 @@ retry: if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); + COM_UNLOCK(); enable_intr(); splx(s); comstart(tp); @@ -2835,6 +2866,7 @@ comstart(tp) com = com_addr(unit); s = spltty(); disable_intr(); + COM_LOCK(); if (tp->t_state & TS_TTSTOP) com->state &= ~CS_TTGO; else @@ -2874,6 +2906,7 @@ comstart(tp) #endif outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); } + COM_UNLOCK(); enable_intr(); if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { #ifdef PC98 @@ -2894,6 +2927,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) @@ -2905,6 +2939,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) { @@ -2914,6 +2949,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) @@ -2925,13 +2961,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(); #ifdef PC98 /* if(IS_8251(com->pc98_if_type)) @@ -2952,6 +2991,7 @@ siostop(tp, rw) if (com->gone) return; disable_intr(); + COM_LOCK(); if (rw & FWRITE) { if (com->hasfifo) #ifdef COM_ESP @@ -2980,6 +3020,7 @@ siostop(tp, rw) com_events -= (com->iptr - com->ibuf); com->iptr = com->ibuf; } + COM_UNLOCK(); enable_intr(); comstart(tp); } @@ -3040,6 +3081,7 @@ commctl(com, bits, how) if (com->gone) return(0); disable_intr(); + COM_LOCK(); switch (how) { case DMSET: outb(com->modem_ctl_port, @@ -3052,6 +3094,7 @@ commctl(com, bits, how) outb(com->modem_ctl_port, com->mcr_image &= ~mcr); break; } + COM_UNLOCK(); enable_intr(); return (0); } @@ -3111,7 +3154,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(); } } @@ -3135,8 +3180,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;