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/dev/pci/eap.c | |
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/dev/pci/eap.c')
-rw-r--r-- | sys/dev/pci/eap.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/sys/dev/pci/eap.c b/sys/dev/pci/eap.c index 7382cf5fcd5..dc7b7be4dac 100644 --- a/sys/dev/pci/eap.c +++ b/sys/dev/pci/eap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eap.c,v 1.44 2012/03/30 08:18:19 ratchov Exp $ */ +/* $OpenBSD: eap.c,v 1.45 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: eap.c,v 1.46 2001/09/03 15:07:37 reinoud Exp $ */ /* @@ -340,7 +340,7 @@ eap1370_write_codec(struct eap_softc *sc, int a, int d) static __inline void eap1371_ready_codec(struct eap_softc *sc, u_int8_t a, u_int32_t wd) { - int to, s; + int to; u_int32_t src, t; for (to = 0; to < EAP_WRITE_TIMEOUT; to++) { @@ -352,7 +352,7 @@ eap1371_ready_codec(struct eap_softc *sc, u_int8_t a, u_int32_t wd) printf("%s: eap1371_ready_codec timeout 1\n", sc->sc_dev.dv_xname); - s = splaudio(); + mtx_enter(&audio_lock); src = eap1371_src_wait(sc) & E1371_SRC_CTLMASK; EWRITE4(sc, E1371_SRC, src | E1371_SRC_STATE_OK); @@ -381,7 +381,7 @@ eap1371_ready_codec(struct eap_softc *sc, u_int8_t a, u_int32_t wd) eap1371_src_wait(sc); EWRITE4(sc, E1371_SRC, src); - splx(s); + mtx_leave(&audio_lock); } int @@ -717,15 +717,14 @@ eap1371_reset_codec(void *sc_) { struct eap_softc *sc = sc_; u_int32_t icsc; - int s; - s = splaudio(); + mtx_enter(&audio_lock); icsc = EREAD4(sc, EAP_ICSC); EWRITE4(sc, EAP_ICSC, icsc | E1371_SYNC_RES); delay(20); EWRITE4(sc, EAP_ICSC, icsc & ~E1371_SYNC_RES); delay(1); - splx(s); + mtx_leave(&audio_lock); return; } @@ -736,9 +735,12 @@ eap_intr(void *p) struct eap_softc *sc = p; u_int32_t intr, sic; + mtx_enter(&audio_lock); intr = EREAD4(sc, EAP_ICSS); - if (!(intr & EAP_INTR)) + if (!(intr & EAP_INTR)) { + mtx_leave(&audio_lock); return (0); + } sic = EREAD4(sc, EAP_SIC); DPRINTFN(5, ("eap_intr: ICSS=0x%08x, SIC=0x%08x\n", intr, sic)); if (intr & EAP_I_ADC) { @@ -795,6 +797,7 @@ eap_intr(void *p) } } #endif + mtx_leave(&audio_lock); return (1); } @@ -1078,7 +1081,7 @@ eap_trigger_output( "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); sc->sc_pintr = intr; sc->sc_parg = arg; - + mtx_enter(&audio_lock); sic = EREAD4(sc, EAP_SIC); sic &= ~(EAP_P2_S_EB | EAP_P2_S_MB | EAP_INC_BITS); sic |= EAP_SET_P2_ST_INC(0) | EAP_SET_P2_END_INC(param->precision * param->factor / 8); @@ -1118,7 +1121,7 @@ eap_trigger_output( EWRITE4(sc, EAP_ICSC, icsc | EAP_DAC2_EN); DPRINTFN(1, ("eap_trigger_output: set ICSC = 0x%08x\n", icsc)); - + mtx_leave(&audio_lock); return (0); } @@ -1147,7 +1150,7 @@ eap_trigger_input( addr, start, end, blksize, intr, arg)); sc->sc_rintr = intr; sc->sc_rarg = arg; - + mtx_enter(&audio_lock); sic = EREAD4(sc, EAP_SIC); sic &= ~(EAP_R1_S_EB | EAP_R1_S_MB); sampshift = 0; @@ -1186,7 +1189,7 @@ eap_trigger_input( EWRITE4(sc, EAP_ICSC, icsc | EAP_ADC_EN); DPRINTFN(1, ("eap_trigger_input: set ICSC = 0x%08x\n", icsc)); - + mtx_leave(&audio_lock); return (0); } @@ -1197,11 +1200,13 @@ eap_halt_output(void *addr) u_int32_t icsc; DPRINTF(("eap: eap_halt_output\n")); + mtx_enter(&audio_lock); icsc = EREAD4(sc, EAP_ICSC); EWRITE4(sc, EAP_ICSC, icsc & ~EAP_DAC2_EN); #ifdef DIAGNOSTIC sc->sc_prun = 0; #endif + mtx_leave(&audio_lock); return (0); } @@ -1212,11 +1217,13 @@ eap_halt_input(void *addr) u_int32_t icsc; DPRINTF(("eap: eap_halt_input\n")); + mtx_enter(&audio_lock); icsc = EREAD4(sc, EAP_ICSC); EWRITE4(sc, EAP_ICSC, icsc & ~EAP_ADC_EN); #ifdef DIAGNOSTIC sc->sc_rrun = 0; #endif + mtx_leave(&audio_lock); return (0); } |