summaryrefslogtreecommitdiff
path: root/sys/dev/audio.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/audio.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/audio.c')
-rw-r--r--sys/dev/audio.c206
1 files changed, 92 insertions, 114 deletions
diff --git a/sys/dev/audio.c b/sys/dev/audio.c
index 9698dc547cf..d51c63f0093 100644
--- a/sys/dev/audio.c
+++ b/sys/dev/audio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: audio.c,v 1.114 2011/07/03 15:47:16 matthew Exp $ */
+/* $OpenBSD: audio.c,v 1.115 2013/05/15 08:29:24 ratchov Exp $ */
/* $NetBSD: audio.c,v 1.119 1999/11/09 16:50:47 augustss Exp $ */
/*
@@ -34,33 +34,6 @@
* SUCH DAMAGE.
*/
-/*
- * This is a (partially) SunOS-compatible /dev/audio driver for NetBSD.
- *
- * This code tries to do something half-way sensible with
- * half-duplex hardware, such as with the SoundBlaster hardware. With
- * half-duplex hardware allowing O_RDWR access doesn't really make
- * sense. However, closing and opening the device to "turn around the
- * line" is relatively expensive and costs a card reset (which can
- * take some time, at least for the SoundBlaster hardware). Instead
- * we allow O_RDWR access, and provide an ioctl to set the "mode",
- * i.e. playing or recording.
- *
- * If you write to a half-duplex device in record mode, the data is
- * tossed. If you read from the device in play mode, you get silence
- * filled buffers at the rate at which samples are naturally
- * generated.
- *
- * If you try to set both play and record mode on a half-duplex
- * device, playing takes precedence.
- */
-
-/*
- * Todo:
- * - Add softaudio() isr processing for wakeup, poll, signals,
- * and silence fill.
- */
-
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
@@ -247,6 +220,22 @@ struct filterops audioread_filtops =
int wskbd_set_mixervolume(long, int);
#endif
+/*
+ * This mutex protects data structures (including registers on the
+ * sound-card) that are manipulated by both the interrupt handler and
+ * syscall code-paths.
+ *
+ * Note that driver methods may sleep (e.g. in malloc); consequently the
+ * audio layer calls them with the mutex unlocked. Driver methods are
+ * responsible for locking the mutex when they manipulate data used by
+ * the interrupt handler and interrupts may occur.
+ *
+ * Similarly, the driver is responsible for locking the mutex in its
+ * interrupt handler and to call the audio layer call-backs (i.e.
+ * audio_{p,r}int()) with the mutex locked.
+ */
+struct mutex audio_lock = MUTEX_INITIALIZER(IPL_AUDIO);
+
int
audioprobe(struct device *parent, void *match, void *aux)
{
@@ -392,7 +381,6 @@ audiodetach(struct device *self, int flags)
{
struct audio_softc *sc = (struct audio_softc *)self;
int maj, mn;
- int s;
DPRINTF(("audio_detach: sc=%p flags=%d\n", sc, flags));
@@ -402,13 +390,13 @@ audiodetach(struct device *self, int flags)
wakeup(&sc->sc_quiesce);
wakeup(&sc->sc_wchan);
wakeup(&sc->sc_rchan);
- s = splaudio();
+ mtx_enter(&audio_lock);
if (--sc->sc_refcnt >= 0) {
- if (tsleep(&sc->sc_refcnt, PZERO, "auddet", hz * 120))
+ if (msleep(&sc->sc_refcnt, &audio_lock, PZERO, "auddet", hz * 120))
printf("audiodetach: %s didn't detach\n",
sc->dev.dv_xname);
}
- splx(s);
+ mtx_leave(&audio_lock);
/* free resources */
audio_free_ring(sc, &sc->sc_pr);
@@ -942,7 +930,7 @@ audio_sleep_timo(int *chan, char *label, int timo)
DPRINTFN(3, ("audio_sleep_timo: chan=%p, label=%s, timo=%d\n",
chan, label, timo));
*chan = 1;
- st = tsleep(chan, PWAIT | PCATCH, label, timo);
+ st = msleep(chan, &audio_lock, PWAIT | PCATCH, label, timo);
*chan = 0;
#ifdef AUDIO_DEBUG
if (st != 0)
@@ -957,7 +945,7 @@ audio_sleep(int *chan, char *label)
return audio_sleep_timo(chan, label, 0);
}
-/* call at splaudio() */
+/* call with audio_lock */
static __inline void
audio_wakeup(int *chan)
{
@@ -1083,12 +1071,10 @@ bad:
void
audio_init_record(struct audio_softc *sc)
{
- int s = splaudio();
-
+ MUTEX_ASSERT_UNLOCKED(&audio_lock);
if (sc->hw_if->speaker_ctl &&
(!sc->sc_full_duplex || (sc->sc_mode & AUMODE_PLAY) == 0))
sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_OFF);
- splx(s);
}
/*
@@ -1097,12 +1083,10 @@ audio_init_record(struct audio_softc *sc)
void
audio_init_play(struct audio_softc *sc)
{
- int s = splaudio();
-
+ MUTEX_ASSERT_UNLOCKED(&audio_lock);
sc->sc_wstamp = sc->sc_pr.stamp;
if (sc->hw_if->speaker_ctl)
sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_ON);
- splx(s);
}
int
@@ -1110,8 +1094,8 @@ audio_drain(struct audio_softc *sc)
{
int error, drops;
struct audio_ringbuffer *cb = &sc->sc_pr;
- int s;
+ MUTEX_ASSERT_UNLOCKED(&audio_lock);
DPRINTF(("audio_drain: enter busy=%d used=%d\n",
sc->sc_pbus, sc->sc_pr.used));
if (sc->sc_pr.mmapped || sc->sc_pr.used <= 0)
@@ -1133,11 +1117,9 @@ audio_drain(struct audio_softc *sc)
inp += cc;
if (inp >= cb->end)
inp = cb->start;
- s = splaudio();
cb->used += cc;
cb->inp = inp;
error = audiostartp(sc);
- splx(s);
if (error)
return error;
}
@@ -1147,20 +1129,20 @@ audio_drain(struct audio_softc *sc)
* XXX This should be done some other way to avoid
* playing silence.
*/
+ mtx_enter(&audio_lock);
drops = cb->drops;
error = 0;
- s = splaudio();
while (cb->drops == drops && !error) {
DPRINTF(("audio_drain: used=%d, drops=%ld\n", sc->sc_pr.used, cb->drops));
/*
* When the process is exiting, it ignores all signals and
* we can't interrupt this sleep, so we set a timeout just in case.
*/
- error = audio_sleep_timo(&sc->sc_wchan, "aud_dr", 30*hz);
+ error = audio_sleep_timo(&sc->sc_wchan, "aud_dr", 30 * hz);
if (sc->sc_dying)
error = EIO;
}
- splx(s);
+ mtx_leave(&audio_lock);
return error;
}
@@ -1169,10 +1151,12 @@ audio_quiesce(struct audio_softc *sc)
{
sc->sc_quiesce = AUDIO_QUIESCE_START;
+ mtx_enter(&audio_lock);
while (sc->sc_pbus && !sc->sc_pqui)
audio_sleep(&sc->sc_wchan, "audpqui");
while (sc->sc_rbus && !sc->sc_rqui)
audio_sleep(&sc->sc_rchan, "audrqui");
+ mtx_leave(&audio_lock);
sc->sc_quiesce = AUDIO_QUIESCE_SILENT;
@@ -1255,11 +1239,10 @@ audio_close(dev_t dev, int flags, int ifmt, struct proc *p)
int unit = AUDIOUNIT(dev);
struct audio_softc *sc = audio_cd.cd_devs[unit];
struct audio_hw_if *hw = sc->hw_if;
- int s;
DPRINTF(("audio_close: unit=%d flags=0x%x\n", unit, flags));
- s = splaudio();
+
/* Stop recording. */
if ((flags & FREAD) && sc->sc_rbus) {
/*
@@ -1267,21 +1250,30 @@ audio_close(dev_t dev, int flags, int ifmt, struct proc *p)
* to halt input and output so don't halt input if
* in full duplex mode. These drivers should be fixed.
*/
- if (!sc->sc_full_duplex || sc->hw_if->halt_input != sc->hw_if->halt_output)
+ if (!sc->sc_full_duplex ||
+ sc->hw_if->halt_input != sc->hw_if->halt_output) {
sc->hw_if->halt_input(sc->hw_hdl);
+ }
sc->sc_rbus = 0;
}
- /*
- * Block until output drains, but allow ^C interrupt.
- */
- sc->sc_pr.usedlow = sc->sc_pr.blksize; /* avoid excessive wakeups */
+
/*
* If there is pending output, let it drain (unless
* the output is paused).
*/
if ((flags & FWRITE) && sc->sc_pbus) {
- if (!sc->sc_pr.pause && !audio_drain(sc) && hw->drain)
- (void)hw->drain(sc->hw_hdl);
+ /*
+ * Block until output drains, but allow ^C interrupt.
+ * XXX: drain is never used, remove it!
+ */
+ mtx_enter(&audio_lock);
+ /* avoid excessive wakeups */
+ sc->sc_pr.usedlow = sc->sc_pr.blksize;
+ mtx_leave(&audio_lock);
+ if (!sc->sc_pr.pause) {
+ if (!audio_drain(sc) && hw->drain)
+ (void)hw->drain(sc->hw_hdl);
+ }
sc->hw_if->halt_output(sc->hw_hdl);
sc->sc_pbus = 0;
}
@@ -1304,9 +1296,7 @@ audio_close(dev_t dev, int flags, int ifmt, struct proc *p)
sc->sc_async_audio = 0;
sc->sc_full_duplex = 0;
- splx(s);
DPRINTF(("audio_close: done\n"));
-
return (0);
}
@@ -1317,7 +1307,7 @@ audio_read(dev_t dev, struct uio *uio, int ioflag)
struct audio_softc *sc = audio_cd.cd_devs[unit];
struct audio_ringbuffer *cb = &sc->sc_rr;
u_char *outp;
- int error, s, cc, n, resid;
+ int error, cc, n, resid;
if (cb->mmapped)
return EINVAL;
@@ -1341,7 +1331,7 @@ audio_read(dev_t dev, struct uio *uio, int ioflag)
if (!sc->sc_full_duplex &&
(sc->sc_mode & AUMODE_PLAY)) {
while (uio->uio_resid > 0 && !error) {
- s = splaudio();
+ mtx_enter(&audio_lock);
for(;;) {
cc = sc->sc_pr.stamp - sc->sc_wstamp;
if (cc > 0)
@@ -1349,18 +1339,18 @@ audio_read(dev_t dev, struct uio *uio, int ioflag)
DPRINTF(("audio_read: stamp=%lu, wstamp=%lu\n",
sc->sc_pr.stamp, sc->sc_wstamp));
if (ioflag & IO_NDELAY) {
- splx(s);
+ mtx_leave(&audio_lock);
return EWOULDBLOCK;
}
error = audio_sleep(&sc->sc_rchan, "aud_hr");
if (sc->sc_dying)
error = EIO;
if (error) {
- splx(s);
+ mtx_leave(&audio_lock);
return error;
}
}
- splx(s);
+ mtx_leave(&audio_lock);
if (uio->uio_resid < cc / sc->sc_rparams.factor)
cc = uio->uio_resid * sc->sc_rparams.factor;
@@ -1372,17 +1362,18 @@ audio_read(dev_t dev, struct uio *uio, int ioflag)
return (error);
}
while (uio->uio_resid > 0) {
- s = splaudio();
+ mtx_enter(&audio_lock);
while (cb->used <= 0) {
if (!sc->sc_rbus && !sc->sc_rr.pause) {
+ mtx_leave(&audio_lock);
error = audiostartr(sc);
- if (error) {
- splx(s);
+ if (error)
return error;
- }
+ mtx_enter(&audio_lock);
+ continue;
}
if (ioflag & IO_NDELAY) {
- splx(s);
+ mtx_leave(&audio_lock);
return (EWOULDBLOCK);
}
DPRINTFN(2, ("audio_read: sleep used=%d\n", cb->used));
@@ -1390,7 +1381,7 @@ audio_read(dev_t dev, struct uio *uio, int ioflag)
if (sc->sc_dying)
error = EIO;
if (error) {
- splx(s);
+ mtx_leave(&audio_lock);
return error;
}
}
@@ -1407,7 +1398,7 @@ audio_read(dev_t dev, struct uio *uio, int ioflag)
cb->outp += cc;
if (cb->outp >= cb->end)
cb->outp = cb->start;
- splx(s);
+ mtx_leave(&audio_lock);
DPRINTFN(1,("audio_read: outp=%p, cc=%d\n", outp, cc));
if (sc->sc_rparams.sw_code)
sc->sc_rparams.sw_code(sc->hw_hdl, outp, cc);
@@ -1421,8 +1412,7 @@ audio_read(dev_t dev, struct uio *uio, int ioflag)
void
audio_clear(struct audio_softc *sc)
{
- int s = splaudio();
-
+ MUTEX_ASSERT_UNLOCKED(&audio_lock);
if (sc->sc_rbus) {
audio_wakeup(&sc->sc_rchan);
sc->hw_if->halt_input(sc->hw_hdl);
@@ -1433,7 +1423,6 @@ audio_clear(struct audio_softc *sc)
sc->hw_if->halt_output(sc->hw_hdl);
sc->sc_pbus = 0;
}
- splx(s);
}
void
@@ -1565,7 +1554,7 @@ audio_write(dev_t dev, struct uio *uio, int ioflag)
struct audio_softc *sc = audio_cd.cd_devs[unit];
struct audio_ringbuffer *cb = &sc->sc_pr;
u_char *inp;
- int error, s, n, cc, resid, avail;
+ int error, n, cc, resid, avail;
DPRINTFN(2, ("audio_write: sc=%p(unit=%d) count=%d used=%d(hi=%d)\n", sc, unit,
uio->uio_resid, sc->sc_pr.used, sc->sc_pr.usedhigh));
@@ -1613,19 +1602,19 @@ audio_write(dev_t dev, struct uio *uio, int ioflag)
sc->sc_pparams.sw_code, sc->sc_pparams.factor));
while (uio->uio_resid > 0) {
- s = splaudio();
+ mtx_enter(&audio_lock);
while (cb->used >= cb->usedhigh) {
DPRINTFN(2, ("audio_write: sleep used=%d lowat=%d hiwat=%d\n",
cb->used, cb->usedlow, cb->usedhigh));
if (ioflag & IO_NDELAY) {
- splx(s);
+ mtx_leave(&audio_lock);
return (EWOULDBLOCK);
}
error = audio_sleep(&sc->sc_wchan, "aud_wr");
if (sc->sc_dying)
error = EIO;
if (error) {
- splx(s);
+ mtx_leave(&audio_lock);
return error;
}
}
@@ -1647,13 +1636,12 @@ audio_write(dev_t dev, struct uio *uio, int ioflag)
*/
sc->sc_sil_count = 0;
if (!sc->sc_pbus && !cb->pause && cb->used >= cb->blksize) {
+ mtx_leave(&audio_lock);
error = audiostartp(sc);
- if (error) {
- splx(s);
+ if (error)
return error;
- }
- }
- splx(s);
+ } else
+ mtx_leave(&audio_lock);
cc /= sc->sc_pparams.factor;
DPRINTFN(1, ("audio_write: uiomove cc=%d inp=%p, left=%d\n",
cc, inp, uio->uio_resid));
@@ -1676,7 +1664,7 @@ audio_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
struct audio_hw_if *hw = sc->hw_if;
struct audio_offset *ao;
struct audio_info ai;
- int error = 0, s, offs, fd;
+ int error = 0, offs, fd;
int rbus, pbus;
/*
@@ -1710,10 +1698,8 @@ audio_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
rbus = sc->sc_rbus;
pbus = sc->sc_pbus;
audio_clear(sc);
- s = splaudio();
error = audio_initbufs(sc);
if (error) {
- splx(s);
return error;
}
sc->sc_rr.pause = 0;
@@ -1723,7 +1709,6 @@ audio_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
if (!error &&
(sc->sc_mode & AUMODE_RECORD) && !sc->sc_rbus && rbus)
error = audiostartr(sc);
- splx(s);
break;
/*
@@ -1757,18 +1742,18 @@ audio_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
* Offsets into buffer.
*/
case AUDIO_GETIOFFS:
- s = splaudio();
+ mtx_enter(&audio_lock);
/* figure out where next DMA will start */
ao = (struct audio_offset *)addr;
ao->samples = sc->sc_rr.stamp / sc->sc_rparams.factor;
ao->deltablks = (sc->sc_rr.stamp - sc->sc_rr.stamp_last) / sc->sc_rr.blksize;
sc->sc_rr.stamp_last = sc->sc_rr.stamp;
ao->offset = (sc->sc_rr.inp - sc->sc_rr.start) / sc->sc_rparams.factor;
- splx(s);
+ mtx_leave(&audio_lock);
break;
case AUDIO_GETOOFFS:
- s = splaudio();
+ mtx_enter(&audio_lock);
/* figure out where next DMA will start */
ao = (struct audio_offset *)addr;
offs = sc->sc_pr.outp - sc->sc_pr.start + sc->sc_pr.blksize;
@@ -1778,7 +1763,7 @@ audio_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
ao->deltablks = (sc->sc_pr.stamp - sc->sc_pr.stamp_last) / sc->sc_pr.blksize;
sc->sc_pr.stamp_last = sc->sc_pr.stamp;
ao->offset = offs / sc->sc_pparams.factor;
- splx(s);
+ mtx_leave(&audio_lock);
break;
/*
@@ -1902,7 +1887,9 @@ audio_poll(dev_t dev, int events, struct proc *p)
{
int unit = AUDIOUNIT(dev);
struct audio_softc *sc = audio_cd.cd_devs[unit];
- int revents = 0, s = splaudio();
+ int revents = 0;
+
+ mtx_enter(&audio_lock);
DPRINTF(("audio_poll: events=0x%x mode=%d\n", events, sc->sc_mode));
@@ -1920,14 +1907,13 @@ audio_poll(dev_t dev, int events, struct proc *p)
if (events & (POLLOUT | POLLWRNORM))
selrecord(p, &sc->sc_wsel);
}
- splx(s);
+ mtx_leave(&audio_lock);
return (revents);
}
paddr_t
audio_mmap(dev_t dev, off_t off, int prot)
{
- int s;
int unit = AUDIOUNIT(dev);
struct audio_softc *sc = audio_cd.cd_devs[unit];
struct audio_hw_if *hw = sc->hw_if;
@@ -1967,15 +1953,11 @@ audio_mmap(dev_t dev, off_t off, int prot)
cb->mmapped = 1;
if (cb == &sc->sc_pr) {
audio_fill_silence(&sc->sc_pparams, cb->start, cb->start, cb->bufsize);
- s = splaudio();
if (!sc->sc_pbus && !sc->sc_pr.pause)
(void)audiostartp(sc);
- splx(s);
} else {
- s = splaudio();
if (!sc->sc_rbus && !sc->sc_rr.pause)
(void)audiostartr(sc);
- splx(s);
}
}
@@ -1987,6 +1969,7 @@ audiostartr(struct audio_softc *sc)
{
int error;
+ MUTEX_ASSERT_UNLOCKED(&audio_lock);
DPRINTF(("audiostartr: start=%p used=%d(hi=%d) mmapped=%d\n",
sc->sc_rr.start, sc->sc_rr.used, sc->sc_rr.usedhigh,
sc->sc_rr.mmapped));
@@ -2011,6 +1994,7 @@ audiostartp(struct audio_softc *sc)
{
int error;
+ MUTEX_ASSERT_UNLOCKED(&audio_lock);
DPRINTF(("audiostartp: start=%p used=%d(hi=%d) mmapped=%d\n",
sc->sc_pr.start, sc->sc_pr.used, sc->sc_pr.usedhigh,
sc->sc_pr.mmapped));
@@ -2045,7 +2029,7 @@ audiostartp(struct audio_softc *sc)
*/
/* XXX
* Putting silence into the output buffer should not really be done
- * at splaudio, but there is no softaudio level to do it at yet.
+ * with audio_lock, but there is no softaudio level to do it at yet.
*/
static __inline void
audio_pint_silence(struct audio_softc *sc, struct audio_ringbuffer *cb,
@@ -2112,6 +2096,7 @@ audio_pint(void *v)
int blksize;
int error;
+ MUTEX_ASSERT_LOCKED(&audio_lock);
if (!sc->sc_open)
return; /* ignore interrupt if not open */
@@ -2191,7 +2176,6 @@ audio_pint(void *v)
if (error) {
/* XXX does this really help? */
DPRINTF(("audio_pint restart failed: %d\n", error));
- audio_clear(sc);
}
}
@@ -2231,6 +2215,7 @@ audio_rint(void *v)
int blksize;
int error;
+ MUTEX_ASSERT_LOCKED(&audio_lock);
if (!sc->sc_open)
return; /* ignore interrupt if not open */
@@ -2306,7 +2291,6 @@ audio_rint(void *v)
if (error) {
/* XXX does this really help? */
DPRINTF(("audio_rint: restart failed: %d\n", error));
- audio_clear(sc);
}
}
@@ -2704,7 +2688,7 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
{
struct audio_prinfo *r = &ai->record, *p = &ai->play;
int cleared;
- int s, setmode, modechange = 0;
+ int setmode, modechange = 0;
int error;
struct audio_hw_if *hw = sc->hw_if;
struct audio_params pp, rp;
@@ -2986,9 +2970,9 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
}
if (cleared) {
- s = splaudio();
error = audio_initbufs(sc);
- if (error) goto err;
+ if (error)
+ goto err;
if (sc->sc_pr.blksize != oldpblksize ||
sc->sc_rr.blksize != oldrblksize)
audio_calcwater(sc);
@@ -3000,7 +2984,6 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
rbus && !sc->sc_rbus && !sc->sc_rr.pause)
error = audiostartr(sc);
err:
- splx(s);
if (error)
return error;
}
@@ -3028,9 +3011,7 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
if (p->pause != (u_char)~0) {
sc->sc_pr.pause = p->pause;
if (!p->pause && !sc->sc_pbus && (sc->sc_mode & AUMODE_PLAY)) {
- s = splaudio();
error = audiostartp(sc);
- splx(s);
if (error)
return error;
}
@@ -3038,9 +3019,7 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
if (r->pause != (u_char)~0) {
sc->sc_rr.pause = r->pause;
if (!r->pause && !sc->sc_rbus && (sc->sc_mode & AUMODE_RECORD)) {
- s = splaudio();
error = audiostartr(sc);
- splx(s);
if (error)
return error;
}
@@ -3295,7 +3274,6 @@ audiokqfilter(dev_t dev, struct knote *kn)
int unit = AUDIOUNIT(dev);
struct audio_softc *sc = audio_cd.cd_devs[unit];
struct klist *klist;
- int s;
switch (kn->kn_filter) {
case EVFILT_READ:
@@ -3311,9 +3289,9 @@ audiokqfilter(dev_t dev, struct knote *kn)
}
kn->kn_hook = (void *)sc;
- s = splaudio();
+ mtx_enter(&audio_lock);
SLIST_INSERT_HEAD(klist, kn, kn_selnext);
- splx(s);
+ mtx_leave(&audio_lock);
return (0);
}
@@ -3322,10 +3300,10 @@ void
filt_audiordetach(struct knote *kn)
{
struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
- int s = splaudio();
+ mtx_enter(&audio_lock);
SLIST_REMOVE(&sc->sc_rsel.si_note, kn, knote, kn_selnext);
- splx(s);
+ mtx_leave(&audio_lock);
}
int
@@ -3340,10 +3318,10 @@ void
filt_audiowdetach(struct knote *kn)
{
struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
- int s = splaudio();
+ mtx_enter(&audio_lock);
SLIST_REMOVE(&sc->sc_wsel.si_note, kn, knote, kn_selnext);
- splx(s);
+ mtx_leave(&audio_lock);
}
int