summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorsommerfeld <sommerfeld@NetBSD.org>2000-09-23 17:17:11 +0000
committersommerfeld <sommerfeld@NetBSD.org>2000-09-23 17:17:11 +0000
commit6a7186735628cdcb0d2d467522d8ee33d26247bc (patch)
tree083a4238f5e3a7dd81bca65b50254b7269d92807 /sys
parenta48f581877be80c842229eeef70156a161b6a861 (diff)
Add `COM_MPLOCK' option to use a device-instance-specific spinlocks
when running at splserial(). This is a temporary measure (until there's a MP-safe interrupt handling structure); until then, it should be used when MULTIPROCESSOR and IPL_SERIAL > IPL_SCHED.
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/files4
-rw-r--r--sys/dev/ic/com.c57
-rw-r--r--sys/dev/ic/comvar.h8
3 files changed, 63 insertions, 6 deletions
diff --git a/sys/conf/files b/sys/conf/files
index 36ad3227a7f..001647e7178 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.392 2000/09/21 23:29:43 eeh Exp $
+# $NetBSD: files,v 1.393 2000/09/23 17:17:11 sommerfeld Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -392,7 +392,7 @@ file dev/ic/ne2000.c ne | IPKDB_NE
# 8250/16[45]50-based "com" ports
# XXX In a perfect world, this would be done with attributes
-defopt opt_com.h COM16650 COM_HAYESP COM_DEBUG
+defopt opt_com.h COM16650 COM_HAYESP COM_DEBUG COM_MPLOCK
device com { } : tty
file dev/ic/com.c com needs-flag
diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c
index aea2568726e..c6be380cf63 100644
--- a/sys/dev/ic/com.c
+++ b/sys/dev/ic/com.c
@@ -1,4 +1,4 @@
-/* $NetBSD: com.c,v 1.178 2000/09/22 14:46:38 eeh Exp $ */
+/* $NetBSD: com.c,v 1.179 2000/09/23 17:17:12 sommerfeld Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -233,6 +233,18 @@ void com_kgdb_putc __P((void *, int));
#define BW BUS_SPACE_BARRIER_WRITE
#define COM_BARRIER(t, h, f) bus_space_barrier((t), (h), 0, COM_NPORTS, (f))
+#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(COM_MPLOCK)
+
+#define COM_LOCK(sc) simple_lock(&(sc)->sc_lock)
+#define COM_UNLOCK(sc) simple_unlock(&(sc)->sc_lock)
+
+#else
+
+#define COM_LOCK(sc)
+#define COM_UNLOCK(sc)
+
+#endif
+
int
comspeed(speed, frequency)
long speed, frequency;
@@ -379,10 +391,12 @@ com_enable_debugport(sc)
/* Turn on line break interrupt, set carrier. */
s = splserial();
+ COM_LOCK(sc);
sc->sc_ier = IER_ERXRDY;
bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
+ COM_UNLOCK(sc);
splx(s);
}
#endif
@@ -404,6 +418,9 @@ com_attach_subr(sc)
#endif
callout_init(&sc->sc_diag_callout);
+#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
+ simple_lock_init(&sc->sc_lock);
+#endif
/* Disable interrupts before configuring the device. */
sc->sc_ier = 0;
@@ -672,6 +689,7 @@ com_activate(self, act)
int s, rv = 0;
s = splserial();
+ COM_LOCK(sc);
switch (act) {
case DVACT_ACTIVATE:
rv = EOPNOTSUPP;
@@ -689,6 +707,8 @@ com_activate(self, act)
}
break;
}
+
+ COM_UNLOCK(sc);
splx(s);
return (rv);
}
@@ -701,6 +721,7 @@ com_shutdown(sc)
int s;
s = splserial();
+ COM_LOCK(sc);
/* If we were asserting flow control, then deassert it. */
SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
@@ -720,10 +741,12 @@ com_shutdown(sc)
*/
if (ISSET(tp->t_cflag, HUPCL)) {
com_modem(sc, 0);
+ COM_UNLOCK(sc);
splx(s);
/* XXX tsleep will only timeout */
(void) tsleep(sc, TTIPRI, ttclos, hz);
s = splserial();
+ COM_LOCK(sc);
}
/* Turn off interrupts. */
@@ -743,7 +766,7 @@ com_shutdown(sc)
(*sc->disable)(sc);
sc->enabled = 0;
}
-
+ COM_UNLOCK(sc);
splx(s);
}
@@ -792,9 +815,11 @@ comopen(dev, flag, mode, p)
tp->t_dev = dev;
s2 = splserial();
+ COM_LOCK(sc);
if (sc->enable) {
if ((*sc->enable)(sc)) {
+ COM_UNLOCK(sc);
splx(s2);
splx(s);
printf("%s: device enable failed\n",
@@ -816,6 +841,7 @@ comopen(dev, flag, mode, p)
sc->sc_ppsmask = 0;
sc->ppsparam.mode = 0;
+ COM_UNLOCK(sc);
splx(s2);
/*
@@ -846,6 +872,7 @@ comopen(dev, flag, mode, p)
ttsetwater(tp);
s2 = splserial();
+ COM_LOCK(sc);
/*
* Turn on DTR. We must always do this, even if carrier is not
@@ -868,6 +895,7 @@ comopen(dev, flag, mode, p)
comstatus(sc, "comopen ");
#endif
+ COM_UNLOCK(sc);
splx(s2);
}
@@ -993,6 +1021,7 @@ comioctl(dev, cmd, data, flag, p)
error = 0;
s = splserial();
+ COM_LOCK(sc);
switch (cmd) {
case TIOCSBRK:
@@ -1134,6 +1163,7 @@ comioctl(dev, cmd, data, flag, p)
break;
}
+ COM_UNLOCK(sc);
splx(s);
#ifdef COM_DEBUG
@@ -1351,6 +1381,7 @@ comparam(tp, t)
lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag);
s = splserial();
+ COM_LOCK(sc);
sc->sc_lcr = lcr;
@@ -1456,6 +1487,7 @@ comparam(tp, t)
sc->sc_r_lowat = com_rbuf_lowat;
}
+ COM_UNLOCK(sc);
splx(s);
/*
@@ -1552,6 +1584,8 @@ comhwiflow(tp, block)
return (0);
s = splserial();
+ COM_LOCK(sc);
+
if (block) {
if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
SET(sc->sc_rx_flags, RX_TTY_BLOCKED);
@@ -1567,6 +1601,8 @@ comhwiflow(tp, block)
com_hwiflow(sc);
}
}
+
+ COM_UNLOCK(sc);
splx(s);
return (1);
}
@@ -1632,6 +1668,7 @@ comstart(tp)
tbc = ndqb(&tp->t_outq, 0);
(void)splserial();
+ COM_LOCK(sc);
sc->sc_tba = tba;
sc->sc_tbc = tbc;
@@ -1657,6 +1694,7 @@ comstart(tp)
sc->sc_tbc -= n;
sc->sc_tba += n;
}
+ COM_UNLOCK(sc);
out:
splx(s);
return;
@@ -1674,6 +1712,7 @@ comstop(tp, flag)
int s;
s = splserial();
+ COM_LOCK(sc);
if (ISSET(tp->t_state, TS_BUSY)) {
/* Stop transmitting at the next chunk. */
sc->sc_tbc = 0;
@@ -1681,6 +1720,7 @@ comstop(tp, flag)
if (!ISSET(tp->t_state, TS_TTSTOP))
SET(tp->t_state, TS_FLUSH);
}
+ COM_UNLOCK(sc);
splx(s);
}
@@ -1693,11 +1733,13 @@ comdiag(arg)
int s;
s = splserial();
+ COM_LOCK(sc);
overflows = sc->sc_overflows;
sc->sc_overflows = 0;
floods = sc->sc_floods;
sc->sc_floods = 0;
sc->sc_errors = 0;
+ COM_UNLOCK(sc);
splx(s);
log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
@@ -1781,6 +1823,8 @@ com_rxsoft(sc, tp)
if (cc != scc) {
sc->sc_rbget = get;
s = splserial();
+ COM_LOCK(sc);
+
cc = sc->sc_rbavail += scc - cc;
/* Buffers should be ok again, release possible block. */
if (cc >= sc->sc_r_lowat) {
@@ -1794,6 +1838,7 @@ com_rxsoft(sc, tp)
com_hwiflow(sc);
}
}
+ COM_UNLOCK(sc);
splx(s);
}
}
@@ -1821,9 +1866,11 @@ com_stsoft(sc, tp)
int s;
s = splserial();
+ COM_LOCK(sc);
msr = sc->sc_msr;
delta = sc->sc_msr_delta;
sc->sc_msr_delta = 0;
+ COM_UNLOCK(sc);
splx(s);
if (ISSET(delta, sc->sc_msr_dcd)) {
@@ -1938,9 +1985,12 @@ comintr(arg)
if (COM_ISALIVE(sc) == 0)
return (0);
+ COM_LOCK(sc);
iir = bus_space_read_1(iot, ioh, com_iir);
- if (ISSET(iir, IIR_NOPEND))
+ if (ISSET(iir, IIR_NOPEND)) {
+ COM_UNLOCK(sc);
return (0);
+ }
end = sc->sc_ebuf;
put = sc->sc_rbput;
@@ -2145,6 +2195,7 @@ comintr(arg)
}
}
}
+ COM_UNLOCK(sc);
/* Wake up the poller. */
#ifdef __GENERIC_SOFT_INTERRUPTS
diff --git a/sys/dev/ic/comvar.h b/sys/dev/ic/comvar.h
index 82c64b2aa31..41b9812d90f 100644
--- a/sys/dev/ic/comvar.h
+++ b/sys/dev/ic/comvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: comvar.h,v 1.35 2000/09/23 12:08:16 bjh21 Exp $ */
+/* $NetBSD: comvar.h,v 1.36 2000/09/23 17:17:12 sommerfeld Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@@ -37,6 +37,9 @@
#include <sys/callout.h>
#include <sys/timepps.h>
+#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(COM_MPLOCK)
+#include <sys/lock.h>
+#endif
int comcnattach __P((bus_space_tag_t, bus_addr_t, int, int, tcflag_t));
@@ -125,6 +128,9 @@ struct com_softc {
#if NRND > 0 && defined(RND_COM)
rndsource_element_t rnd_source;
#endif
+#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(COM_MPLOCK)
+ struct simplelock sc_lock;
+#endif
};
/* Macros to clear/set/test flags. */