summaryrefslogtreecommitdiff
path: root/sys/dev/pci/autri.c
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/dev/pci/autri.c
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/dev/pci/autri.c')
-rw-r--r--sys/dev/pci/autri.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/sys/dev/pci/autri.c b/sys/dev/pci/autri.c
index 78ba73425a1..12cb19f5cc7 100644
--- a/sys/dev/pci/autri.c
+++ b/sys/dev/pci/autri.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autri.c,v 1.31 2012/03/30 08:18:19 ratchov Exp $ */
+/* $OpenBSD: autri.c,v 1.32 2013/05/15 08:29:24 ratchov Exp $ */
/*
* Copyright (c) 2001 SOMEYA Yoshihiko and KUROSAWA Takahiro.
@@ -803,9 +803,12 @@ autri_intr(p)
u_int32_t cso,eso;
*/
+ mtx_enter(&audio_lock);
intsrc = TREAD4(sc,AUTRI_MISCINT);
- if ((intsrc & (ADDRESS_IRQ|MPU401_IRQ)) == 0)
+ if ((intsrc & (ADDRESS_IRQ|MPU401_IRQ)) == 0) {
+ mtx_leave(&audio_lock);
return 0;
+ }
if (intsrc & ADDRESS_IRQ) {
@@ -861,7 +864,7 @@ autri_intr(p)
autri_reg_set_4(sc,AUTRI_MISCINT,
ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW);
-
+ mtx_leave(&audio_lock);
return 1;
}
@@ -1077,11 +1080,11 @@ autri_halt_output(addr)
struct autri_softc *sc = addr;
DPRINTF(("autri_halt_output()\n"));
-
+ mtx_enter(&audio_lock);
sc->sc_play.intr = NULL;
autri_stopch(sc, sc->sc_play.ch, sc->sc_play.ch_intr);
autri_disable_interrupt(sc, sc->sc_play.ch_intr);
-
+ mtx_leave(&audio_lock);
return 0;
}
@@ -1092,11 +1095,11 @@ autri_halt_input(addr)
struct autri_softc *sc = addr;
DPRINTF(("autri_halt_input()\n"));
-
+ mtx_enter(&audio_lock);
sc->sc_rec.intr = NULL;
autri_stopch(sc, sc->sc_rec.ch, sc->sc_rec.ch_intr);
autri_disable_interrupt(sc, sc->sc_rec.ch_intr);
-
+ mtx_leave(&audio_lock);
return 0;
}
@@ -1431,6 +1434,7 @@ autri_trigger_output(addr, start, end, blksize, intr, arg, param)
sc->sc_play.dma = p;
/* */
+ mtx_enter(&audio_lock);
autri_setup_channel(sc, AUMODE_PLAY, param);
/* volume set to no attenuation */
@@ -1441,7 +1445,7 @@ autri_trigger_output(addr, start, end, blksize, intr, arg, param)
/* start channel */
autri_startch(sc, sc->sc_play.ch, sc->sc_play.ch_intr);
-
+ mtx_leave(&audio_lock);
return 0;
}
@@ -1474,6 +1478,7 @@ autri_trigger_input(addr, start, end, blksize, intr, arg, param)
}
sc->sc_rec.dma = p;
+ mtx_enter(&audio_lock);
/* */
if (sc->sc_devid == AUTRI_DEVICE_ID_4DWAVE_NX) {
@@ -1495,7 +1500,7 @@ autri_trigger_input(addr, start, end, blksize, intr, arg, param)
/* start channel */
autri_startch(sc, sc->sc_rec.ch, sc->sc_rec.ch_intr);
-
+ mtx_leave(&audio_lock);
return 0;
}