summaryrefslogtreecommitdiff
path: root/sys/arch/macppc
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2013-05-15 08:29:27 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2013-05-15 08:29:27 +0000
commite4d6a0a80573196dfd09b1201d79c9b77536c745 (patch)
treee7cc60514c99640b6483947ee3bfb09d9b2d58bb /sys/arch/macppc
parent2af0efdd18ad07b832c93f5c98d654ace8e0524e (diff)
Introduce a global interrupt-aware mutex protecting data
structures (including sound-card registers) from concurent access by syscall and interrupt code-paths. Since critical sections remain the same, calls to splraise/spllower can be safely replaced by calls to mtx_enter/mtx_leave with two exceptions: (1) mutexes are not reentrant (the inner splraise is thus removed), and (2) we're not allowed to sleep with a mutex (either msleep is used or the mutex is released before sleeping). ok and help from kettenis, a lot of work from armani
Diffstat (limited to 'sys/arch/macppc')
-rw-r--r--sys/arch/macppc/dev/awacs.c24
-rw-r--r--sys/arch/macppc/dev/i2s.c18
2 files changed, 31 insertions, 11 deletions
diff --git a/sys/arch/macppc/dev/awacs.c b/sys/arch/macppc/dev/awacs.c
index 071e40035dc..cb8e625033c 100644
--- a/sys/arch/macppc/dev/awacs.c
+++ b/sys/arch/macppc/dev/awacs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: awacs.c,v 1.27 2011/09/04 18:48:10 miod Exp $ */
+/* $OpenBSD: awacs.c,v 1.28 2013/05/15 08:29:23 ratchov Exp $ */
/* $NetBSD: awacs.c,v 1.4 2001/02/26 21:07:51 wiz Exp $ */
/*-
@@ -387,8 +387,9 @@ awacs_intr(void *v)
{
int reason;
struct awacs_softc *sc = v;
- reason = awacs_read_reg(sc, AWACS_SOUND_CTRL);
+ mtx_enter(&audio_lock);
+ reason = awacs_read_reg(sc, AWACS_SOUND_CTRL);
if (reason & AWACS_CTL_CNTRLERR) {
/* change outputs ?? */
}
@@ -413,6 +414,7 @@ awacs_intr(void *v)
}
awacs_write_reg(sc, AWACS_SOUND_CTRL, reason); /* clear interrupt */
+ mtx_leave(&audio_lock);
return 1;
}
@@ -425,8 +427,8 @@ awacs_tx_intr(void *v)
/* if not set we are not running */
if (!cmd)
- return (0);
-
+ return (0);
+ mtx_enter(&audio_lock);
c = in16rb(&cmd->d_command);
status = in16rb(&cmd->d_status);
@@ -441,7 +443,7 @@ awacs_tx_intr(void *v)
if (sc->sc_ointr)
(*sc->sc_ointr)(sc->sc_oarg);
}
-
+ mtx_leave(&audio_lock);
return (1);
}
int
@@ -455,6 +457,7 @@ awacs_rx_intr(void *v)
if (!cmd)
return (0);
+ mtx_enter(&audio_lock);
c = in16rb(&cmd->d_command);
status = in16rb(&cmd->d_status);
@@ -469,7 +472,7 @@ awacs_rx_intr(void *v)
if (sc->sc_iintr)
(*sc->sc_iintr)(sc->sc_iarg);
}
-
+ mtx_leave(&audio_lock);
return (1);
}
@@ -487,6 +490,7 @@ awacs_close(void *h)
{
struct awacs_softc *sc = h;
+ /* XXX: halt_xxx() already called by upper layer */
awacs_halt_output(sc);
awacs_halt_input(sc);
@@ -679,10 +683,12 @@ awacs_halt_output(void *h)
{
struct awacs_softc *sc = h;
+ mtx_enter(&audio_lock);
dbdma_stop(sc->sc_odma);
dbdma_reset(sc->sc_odma);
dbdma_stop(sc->sc_odma);
sc->sc_odmap = NULL;
+ mtx_leave(&audio_lock);
return 0;
}
@@ -691,8 +697,10 @@ awacs_halt_input(void *h)
{
struct awacs_softc *sc = h;
+ mtx_enter(&audio_lock);
dbdma_stop(sc->sc_idma);
dbdma_reset(sc->sc_idma);
+ mtx_leave(&audio_lock);
return 0;
}
@@ -1041,6 +1049,7 @@ awacs_trigger_output(void *h, void *start, void *end, int bsize,
sc->sc_oarg = arg;
sc->sc_odmap = sc->sc_odmacmd;
+ mtx_enter(&audio_lock);
spa = p->segs[0].ds_addr;
c = DBDMA_CMD_OUT_MORE;
for (pa = spa, epa = spa + (end - start);
@@ -1059,6 +1068,7 @@ awacs_trigger_output(void *h, void *start, void *end, int bsize,
dbdma_start(sc->sc_odma, sc->sc_odbdma);
+ mtx_leave(&audio_lock);
return 0;
}
@@ -1082,6 +1092,7 @@ awacs_trigger_input(void *h, void *start, void *end, int bsize,
sc->sc_iarg = arg;
sc->sc_idmap = sc->sc_idmacmd;
+ mtx_enter(&audio_lock);
spa = p->segs[0].ds_addr;
c = DBDMA_CMD_IN_MORE;
for (pa = spa, epa = spa + (end - start);
@@ -1100,6 +1111,7 @@ awacs_trigger_input(void *h, void *start, void *end, int bsize,
dbdma_start(sc->sc_idma, sc->sc_idbdma);
+ mtx_leave(&audio_lock);
return 0;
}
diff --git a/sys/arch/macppc/dev/i2s.c b/sys/arch/macppc/dev/i2s.c
index a5f18639fae..5f21a986a1c 100644
--- a/sys/arch/macppc/dev/i2s.c
+++ b/sys/arch/macppc/dev/i2s.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i2s.c,v 1.22 2011/06/07 16:29:51 mpi Exp $ */
+/* $OpenBSD: i2s.c,v 1.23 2013/05/15 08:29:23 ratchov Exp $ */
/* $NetBSD: i2s.c,v 1.1 2003/12/27 02:19:34 grant Exp $ */
/*-
@@ -132,9 +132,13 @@ i2s_intr(v)
struct dbdma_command *cmd = sc->sc_odmap;
u_int16_t c, status;
+ mtx_enter(&audio_lock);
+
/* if not set we are not running */
- if (!cmd)
+ if (!cmd) {
+ mtx_leave(&audio_lock);
return (0);
+ }
DPRINTF(("i2s_intr: cmd %x\n", cmd));
c = in16rb(&cmd->d_command);
@@ -151,7 +155,7 @@ i2s_intr(v)
if (sc->sc_ointr)
(*sc->sc_ointr)(sc->sc_oarg);
}
-
+ mtx_leave(&audio_lock);
return 1;
}
@@ -163,9 +167,13 @@ i2s_iintr(v)
struct dbdma_command *cmd = sc->sc_idmap;
u_int16_t c, status;
+ mtx_enter(&audio_lock);
+
/* if not set we are not running */
- if (!cmd)
+ if (!cmd) {
+ mtx_leave(&audio_lock);
return (0);
+ }
DPRINTF(("i2s_intr: cmd %x\n", cmd));
c = in16rb(&cmd->d_command);
@@ -182,7 +190,7 @@ i2s_iintr(v)
if (sc->sc_iintr)
(*sc->sc_iintr)(sc->sc_iarg);
}
-
+ mtx_leave(&audio_lock);
return 1;
}