diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2013-05-15 08:29:27 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2013-05-15 08:29:27 +0000 |
commit | e4d6a0a80573196dfd09b1201d79c9b77536c745 (patch) | |
tree | e7cc60514c99640b6483947ee3bfb09d9b2d58bb /sys/arch/macppc | |
parent | 2af0efdd18ad07b832c93f5c98d654ace8e0524e (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.c | 24 | ||||
-rw-r--r-- | sys/arch/macppc/dev/i2s.c | 18 |
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; } |