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 | |
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')
37 files changed, 723 insertions, 591 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 diff --git a/sys/dev/audio_if.h b/sys/dev/audio_if.h index 5557edd3067..e86e754511a 100644 --- a/sys/dev/audio_if.h +++ b/sys/dev/audio_if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: audio_if.h,v 1.27 2010/07/15 03:43:11 jakemsr Exp $ */ +/* $OpenBSD: audio_if.h,v 1.28 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: audio_if.h,v 1.24 1998/01/10 14:07:25 tv Exp $ */ /* @@ -38,6 +38,8 @@ #ifndef _SYS_DEV_AUDIO_IF_H_ #define _SYS_DEV_AUDIO_IF_H_ +#include <sys/mutex.h> + #define AUDIO_BPS(bits) (bits) <= 8 ? 1 : ((bits) <= 16 ? 2 : 4) /* @@ -169,5 +171,7 @@ int audioprint(void *, const char *); */ #define AUDIO_MAX_CHANNELS 12 +extern struct mutex audio_lock; + #endif /* _SYS_DEV_AUDIO_IF_H_ */ diff --git a/sys/dev/bluetooth/btsco.c b/sys/dev/bluetooth/btsco.c index 513823652cf..6e8beb39957 100644 --- a/sys/dev/bluetooth/btsco.c +++ b/sys/dev/bluetooth/btsco.c @@ -1,4 +1,4 @@ -/* $OpenBSD: btsco.c,v 1.5 2010/07/15 03:43:11 jakemsr Exp $ */ +/* $OpenBSD: btsco.c,v 1.6 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: btsco.c,v 1.22 2008/08/06 15:01:23 plunky Exp $ */ /*- @@ -461,7 +461,6 @@ static void btsco_sco_disconnected(void *arg, int err) { struct btsco_softc *sc = arg; - int s; DPRINTF("%s sc_state %d\n", sc->sc_name, sc->sc_state); @@ -484,7 +483,7 @@ btsco_sco_disconnected(void *arg, int err) * has completed so that when it tries to send more, we * can indicate an error. */ - s = splaudio(); + mtx_enter(&audio_lock); if (sc->sc_tx_pending > 0) { sc->sc_tx_pending = 0; (*sc->sc_tx_intr)(sc->sc_tx_intrarg); @@ -493,7 +492,7 @@ btsco_sco_disconnected(void *arg, int err) sc->sc_rx_want = 0; (*sc->sc_rx_intr)(sc->sc_rx_intrarg); } - splx(s); + mtx_leave(&audio_lock); break; default: @@ -524,17 +523,16 @@ static void btsco_sco_complete(void *arg, int count) { struct btsco_softc *sc = arg; - int s; DPRINTFN(10, "%s count %d\n", sc->sc_name, count); - s = splaudio(); + mtx_enter(&audio_lock); if (sc->sc_tx_pending > 0) { sc->sc_tx_pending -= count; if (sc->sc_tx_pending == 0) (*sc->sc_tx_intr)(sc->sc_tx_intrarg); } - splx(s); + mtx_leave(&audio_lock); } static void @@ -549,11 +547,11 @@ static void btsco_sco_input(void *arg, struct mbuf *m) { struct btsco_softc *sc = arg; - int len, s; + int len; DPRINTFN(10, "%s len=%d\n", sc->sc_name, m->m_pkthdr.len); - s = splaudio(); + mtx_enter(&audio_lock); if (sc->sc_rx_want == 0) { m_freem(m); } else { @@ -579,7 +577,7 @@ btsco_sco_input(void *arg, struct mbuf *m) if (sc->sc_rx_want == 0) (*sc->sc_rx_intr)(sc->sc_rx_intrarg); } - splx(s); + mtx_leave(&audio_lock); } diff --git a/sys/dev/ic/am7930.c b/sys/dev/ic/am7930.c index f510711e6ce..153c396dcfc 100644 --- a/sys/dev/ic/am7930.c +++ b/sys/dev/ic/am7930.c @@ -1,4 +1,4 @@ -/* $OpenBSD: am7930.c,v 1.3 2011/09/04 20:08:37 miod Exp $ */ +/* $OpenBSD: am7930.c,v 1.4 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: am7930.c,v 1.44 2001/11/13 13:14:34 lukem Exp $ */ /* @@ -354,7 +354,8 @@ am7930_commit_settings(void *addr) gr = gx_coeff[level]; } - s = splaudio(); + /* XXX: this is called before DMA is setup, useful ? */ + mtx_enter(&audio_lock); mmr2 = AM7930_IREAD(sc, AM7930_IREG_MAP_MMR2); if (sc->sc_out_port == AUDIOAMD_SPEAKER_VOL) @@ -379,7 +380,7 @@ am7930_commit_settings(void *addr) AM7930_IWRITE16(sc, AM7930_IREG_MAP_GR, gr); AM7930_IWRITE16(sc, AM7930_IREG_MAP_GER, ger); - splx(s); + mtx_leave(&audio_lock); return 0; } diff --git a/sys/dev/ic/arcofi.c b/sys/dev/ic/arcofi.c index 67c8559cc20..a89825aeb2a 100644 --- a/sys/dev/ic/arcofi.c +++ b/sys/dev/ic/arcofi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: arcofi.c,v 1.5 2012/01/02 17:10:56 miod Exp $ */ +/* $OpenBSD: arcofi.c,v 1.6 2013/05/15 08:29:24 ratchov Exp $ */ /* * Copyright (c) 2011 Miodrag Vallat. @@ -301,16 +301,15 @@ int arcofi_drain(void *v) { struct arcofi_softc *sc = (struct arcofi_softc *)v; - int s; - s = splaudio(); /* not invoked at splaudio if from ioctl() */ + mtx_enter(&audio_lock); if ((arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_OUT_EMPTY) == 0) { /* enable output FIFO empty interrupt... */ arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) | FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY)); /* ...and wait for it to fire */ - if (tsleep(&sc->sc_xmit, 0, "arcofidr", + if (msleep(&sc->sc_xmit, &audio_lock, 0, "arcofidr", 1 + (ARCOFI_FIFO_SIZE * hz) / 8000) != 0) { printf("%s: drain did not complete\n", sc->sc_dev.dv_xname); @@ -319,8 +318,7 @@ arcofi_drain(void *v) ~FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY)); } } - splx(s); - + mtx_leave(&audio_lock); return 0; } @@ -527,7 +525,6 @@ int arcofi_commit_settings(void *v) { struct arcofi_softc *sc = (struct arcofi_softc *)v; - int s; int rc; uint8_t cmd[2], csr, ocsr; @@ -542,7 +539,7 @@ arcofi_commit_settings(void *v) if (bcmp(&sc->sc_active, &sc->sc_shadow, sizeof(sc->sc_active)) == 0) return 0; - s = splaudio(); + mtx_enter(&audio_lock); if (sc->sc_active.gr_idx != sc->sc_shadow.gr_idx) { cmd[0] = arcofi_gains[sc->sc_shadow.gr_idx] >> 8; @@ -591,7 +588,7 @@ arcofi_commit_settings(void *v) rc = 0; error: - splx(s); + mtx_leave(&audio_lock); return rc; } @@ -658,7 +655,7 @@ arcofi_halt_input(void *v) { struct arcofi_softc *sc = (struct arcofi_softc *)v; - splassert(IPL_AUDIO); + mtx_enter(&audio_lock); /* disable input FIFO interrupts */ arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) & @@ -669,6 +666,7 @@ arcofi_halt_input(void *v) arcofi_write(sc, ARCOFI_CSR, arcofi_read(sc, ARCOFI_CSR) & ~CSR_DATA_FIFO_ENABLE); + mtx_leave(&audio_lock); return 0; } @@ -677,7 +675,7 @@ arcofi_halt_output(void *v) { struct arcofi_softc *sc = (struct arcofi_softc *)v; - splassert(IPL_AUDIO); + mtx_enter(&audio_lock); /* disable output FIFO interrupts */ arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) & @@ -688,6 +686,7 @@ arcofi_halt_output(void *v) arcofi_write(sc, ARCOFI_CSR, arcofi_read(sc, ARCOFI_CSR) & ~CSR_DATA_FIFO_ENABLE); + mtx_leave(&audio_lock); return 0; } @@ -1143,15 +1142,15 @@ void arcofi_swintr(void *v) { struct arcofi_softc *sc = (struct arcofi_softc *)v; - int s, action; + int action; action = 0; - s = splaudio(); + mtx_enter(&audio_lock); if (sc->sc_recv.buf != NULL && sc->sc_recv.buf == sc->sc_recv.past) action |= AUMODE_RECORD; if (sc->sc_xmit.buf != NULL && sc->sc_xmit.buf == sc->sc_xmit.past) action |= AUMODE_PLAY; - splx(s); + mtx_leave(&audio_lock); if (action & AUMODE_RECORD) { if (sc->sc_recv.cb) @@ -1194,7 +1193,7 @@ arcofi_cmd(struct arcofi_softc *sc, uint8_t cmd, const uint8_t *data) return EINVAL; len = cmdlen[cmd]; - splassert(IPL_AUDIO); + mtx_enter(&audio_lock); /* * Disable all FIFO processing. @@ -1221,13 +1220,16 @@ arcofi_cmd(struct arcofi_softc *sc, uint8_t cmd, const uint8_t *data) */ cnt = 100; while ((arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_CTRL_EMPTY) == 0) { - if (cnt-- == 0) + if (cnt-- == 0) { + mtx_leave(&audio_lock); return EBUSY; + } delay(10); } arcofi_write(sc, ARCOFI_CSR, csr); + mtx_leave(&audio_lock); return 0; } diff --git a/sys/dev/isa/ad1848.c b/sys/dev/isa/ad1848.c index 6cd62c30489..45cfa9b7a2d 100644 --- a/sys/dev/isa/ad1848.c +++ b/sys/dev/isa/ad1848.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ad1848.c,v 1.38 2010/07/31 08:08:18 ratchov Exp $ */ +/* $OpenBSD: ad1848.c,v 1.39 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: ad1848.c,v 1.45 1998/01/30 02:02:38 augustss Exp $ */ /* @@ -159,12 +159,10 @@ static void wait_for_calibration(struct ad1848_softc *); static int ad_read(struct ad1848_softc *sc, int reg) { - int x, s; + int x; - s = splaudio(); ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit); x = ADREAD(sc, AD1848_IDATA); - splx(s); /* printf("(%02x<-%02x) ", reg|sc->MCE_bit, x); */ return x; @@ -173,10 +171,8 @@ ad_read(struct ad1848_softc *sc, int reg) static void ad_write(struct ad1848_softc *sc, int reg, int data) { - int s = splaudio(); ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit); ADWRITE(sc, AD1848_IDATA, data & 0xff); - splx(s); /* printf("(%02x->%02x) ", reg|sc->MCE_bit, data); */ } @@ -791,7 +787,7 @@ ad1848_mixer_get_port(struct ad1848_softc *ac, struct ad1848_devmap *map, return (ENXIO); dev = entry->dev; - + mtx_enter(&audio_lock); switch (entry->kind) { case AD1848_KIND_LVL: if (cp->type != AUDIO_MIXER_VALUE) @@ -841,7 +837,7 @@ ad1848_mixer_get_port(struct ad1848_softc *ac, struct ad1848_devmap *map, printf("Invalid kind\n"); break; } - + mtx_leave(&audio_lock); return error; } @@ -858,7 +854,7 @@ ad1848_mixer_set_port(struct ad1848_softc *ac, struct ad1848_devmap *map, return (ENXIO); dev = entry->dev; - + mtx_enter(&audio_lock); switch (entry->kind) { case AD1848_KIND_LVL: if (cp->type != AUDIO_MIXER_VALUE) @@ -905,7 +901,7 @@ ad1848_mixer_set_port(struct ad1848_softc *ac, struct ad1848_devmap *map, printf("Invalid kind\n"); break; } - + mtx_leave(&audio_lock); return (error); } @@ -1193,12 +1189,11 @@ ad1848_commit_settings(void *addr) struct ad1848_softc *sc = addr; int timeout; u_char fs; - int s; if (!sc->need_commit) return 0; - s = splaudio(); + mtx_enter(&audio_lock); ad1848_mute_monitor(sc, 1); @@ -1259,7 +1254,7 @@ ad1848_commit_settings(void *addr) ad1848_mute_monitor(sc, 0); - splx(s); + mtx_leave(&audio_lock); sc->need_commit = 0; @@ -1370,7 +1365,7 @@ ad1848_halt_output(void *addr) u_char reg; DPRINTF(("ad1848: ad1848_halt_output\n")); - + mtx_enter(&audio_lock); reg = ad_read(sc, SP_INTERFACE_CONFIG); ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~PLAYBACK_ENABLE)); @@ -1378,7 +1373,7 @@ ad1848_halt_output(void *addr) isa_dmaabort(sc->sc_isa, sc->sc_drq); sc->sc_playrun = 0; } - + mtx_leave(&audio_lock); return 0; } @@ -1389,7 +1384,7 @@ ad1848_halt_input(void *addr) u_char reg; DPRINTF(("ad1848: ad1848_halt_input\n")); - + mtx_enter(&audio_lock); reg = ad_read(sc, SP_INTERFACE_CONFIG); ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~CAPTURE_ENABLE)); @@ -1397,7 +1392,7 @@ ad1848_halt_input(void *addr) isa_dmaabort(sc->sc_isa, sc->sc_recdrq); sc->sc_recrun = 0; } - + mtx_leave(&audio_lock); return 0; } @@ -1412,7 +1407,7 @@ ad1848_trigger_input(void *addr, void *start, void *end, int blksize, DPRINTF(("ad1848_trigger_input: invalid recording drq\n")); return ENXIO; } - + mtx_enter(&audio_lock); isa_dmastart(sc->sc_isa, sc->sc_recdrq, start, (char *)end - (char *)start, NULL, DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT); @@ -1438,7 +1433,7 @@ ad1848_trigger_input(void *addr, void *start, void *end, int blksize, if (ad1848debug > 1) printf("ad1848_trigger_input: started capture\n"); #endif - + mtx_leave(&audio_lock); return 0; } @@ -1449,6 +1444,7 @@ ad1848_trigger_output(void *addr, void *start, void *end, int blksize, struct ad1848_softc *sc = addr; u_char reg; + mtx_enter(&audio_lock); isa_dmastart(sc->sc_isa, sc->sc_drq, start, (char *)end - (char *)start, NULL, DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT); @@ -1469,7 +1465,7 @@ ad1848_trigger_output(void *addr, void *start, void *end, int blksize, if (ad1848debug > 1) printf("ad1848_trigger_output: started playback\n"); #endif - + mtx_leave(&audio_lock); return 0; } @@ -1480,6 +1476,7 @@ ad1848_intr(void *arg) int retval = 0; u_char status; + mtx_enter(&audio_lock); /* Get intr status */ status = ADREAD(sc, AD1848_STATUS); @@ -1518,7 +1515,7 @@ ad1848_intr(void *arg) /* clear interrupt */ ADWRITE(sc, AD1848_STATUS, 0); } - + mtx_leave(&audio_lock); return(retval); } diff --git a/sys/dev/isa/ess.c b/sys/dev/isa/ess.c index c285986ee03..2e54a2b3ff6 100644 --- a/sys/dev/isa/ess.c +++ b/sys/dev/isa/ess.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ess.c,v 1.16 2010/07/15 03:43:11 jakemsr Exp $ */ +/* $OpenBSD: ess.c,v 1.17 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: ess.c,v 1.44.4.1 1999/06/21 01:18:00 thorpej Exp $ */ /* @@ -1301,6 +1301,7 @@ ess_audio1_trigger_output(addr, start, end, blksize, intr, arg, param) struct ess_softc *sc = addr; u_int8_t reg; + mtx_enter(&audio_lock); DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); @@ -1363,7 +1364,7 @@ ess_audio1_trigger_output(addr, start, end, blksize, intr, arg, param) reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE); reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT; ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg); - + mtx_leave(&audio_lock); return (0); } @@ -1379,6 +1380,7 @@ ess_audio2_trigger_output(addr, start, end, blksize, intr, arg, param) struct ess_softc *sc = addr; u_int8_t reg; + mtx_enter(&audio_lock); DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); @@ -1432,7 +1434,7 @@ ess_audio2_trigger_output(addr, start, end, blksize, intr, arg, param) reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE | ESS_AUDIO2_CTRL1_AUTO_INIT; ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg); - + mtx_leave(&audio_lock); return (0); } @@ -1448,6 +1450,7 @@ ess_audio1_trigger_input(addr, start, end, blksize, intr, arg, param) struct ess_softc *sc = addr; u_int8_t reg; + mtx_enter(&audio_lock); DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); @@ -1510,7 +1513,7 @@ ess_audio1_trigger_input(addr, start, end, blksize, intr, arg, param) reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE; reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT; ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg); - + mtx_leave(&audio_lock); return (0); } @@ -1521,7 +1524,7 @@ ess_audio1_halt(addr) struct ess_softc *sc = addr; DPRINTF(("ess_audio1_halt: sc=%p\n", sc)); - + mtx_enter(&audio_lock); if (sc->sc_audio1.active) { ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2, ESS_AUDIO1_CTRL2_FIFO_ENABLE); @@ -1530,7 +1533,7 @@ ess_audio1_halt(addr) timeout_del(&sc->sc_tmo1); sc->sc_audio1.active = 0; } - + mtx_leave(&audio_lock); return (0); } @@ -1541,7 +1544,7 @@ ess_audio2_halt(addr) struct ess_softc *sc = addr; DPRINTF(("ess_audio2_halt: sc=%p\n", sc)); - + mtx_enter(&audio_lock); if (sc->sc_audio2.active) { ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1, ESS_AUDIO2_CTRL1_DAC_ENABLE | @@ -1551,7 +1554,7 @@ ess_audio2_halt(addr) timeout_del(&sc->sc_tmo2); sc->sc_audio2.active = 0; } - + mtx_leave(&audio_lock); return (0); } @@ -1564,19 +1567,25 @@ ess_audio1_intr(arg) DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr)); + mtx_enter(&audio_lock); /* Check and clear interrupt on Audio1. */ reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS); - if ((reg & ESS_DSP_READ_OFLOW) == 0) + if ((reg & ESS_DSP_READ_OFLOW) == 0) { + mtx_leave(&audio_lock); return (0); + } reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR); sc->sc_audio1.nintr++; if (sc->sc_audio1.active) { (*sc->sc_audio1.intr)(sc->sc_audio1.arg); + mtx_leave(&audio_lock); return (1); - } else + } else { + mtx_leave(&audio_lock); return (0); + } } int @@ -1588,10 +1597,13 @@ ess_audio2_intr(arg) DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr)); + mtx_enter(&audio_lock); /* Check and clear interrupt on Audio2. */ reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2); - if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0) + if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0) { + mtx_leave(&audio_lock); return (0); + } reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH; ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg); @@ -1599,9 +1611,12 @@ ess_audio2_intr(arg) if (sc->sc_audio2.active) { (*sc->sc_audio2.intr)(sc->sc_audio2.arg); + mtx_leave(&audio_lock); return (1); - } else + } else { + mtx_leave(&audio_lock); return (0); + } } void @@ -1614,6 +1629,7 @@ ess_audio1_poll(addr) if (!sc->sc_audio1.active) return; + mtx_enter(&audio_lock); sc->sc_audio1.nintr++; dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio1.drq); @@ -1631,8 +1647,8 @@ ess_audio1_poll(addr) #else (*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount); #endif - timeout_add_msec(&sc->sc_tmo1, 1000/30); + mtx_leave(&audio_lock); } void @@ -1645,6 +1661,7 @@ ess_audio2_poll(addr) if (!sc->sc_audio2.active) return; + mtx_enter(&audio_lock); sc->sc_audio2.nintr++; dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio2.drq); @@ -1662,8 +1679,8 @@ ess_audio2_poll(addr) #else (*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount); #endif - timeout_add_msec(&sc->sc_tmo2, 1000/30); + mtx_leave(&audio_lock); } int @@ -2677,14 +2694,13 @@ ess_write_mix_reg(sc, reg, val) { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - int s; DPRINTFN(2,("ess_write_mix_reg: %x=%x\n", reg, val)); - s = splaudio(); + mtx_enter(&audio_lock); EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg); EWRITE1(iot, ioh, ESS_MIX_REG_DATA, val); - splx(s); + mtx_leave(&audio_lock); } /* @@ -2697,13 +2713,12 @@ ess_read_mix_reg(sc, reg) { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - int s; u_char val; - s = splaudio(); + mtx_enter(&audio_lock); EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg); val = EREAD1(iot, ioh, ESS_MIX_REG_DATA); - splx(s); + mtx_leave(&audio_lock); DPRINTFN(2,("ess_read_mix_reg: %x=%x\n", reg, val)); return val; @@ -2736,10 +2751,9 @@ ess_read_multi_mix_reg(sc, reg, datap, count) { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - int s; - s = splaudio(); + mtx_enter(&audio_lock); EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg); bus_space_read_multi_1(iot, ioh, ESS_MIX_REG_DATA, datap, count); - splx(s); + mtx_leave(&audio_lock); } diff --git a/sys/dev/isa/gus.c b/sys/dev/isa/gus.c index d2ed7e17011..92100774283 100644 --- a/sys/dev/isa/gus.c +++ b/sys/dev/isa/gus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gus.c,v 1.35 2012/02/25 22:33:22 miod Exp $ */ +/* $OpenBSD: gus.c,v 1.36 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: gus.c,v 1.51 1998/01/25 23:48:06 mycroft Exp $ */ /*- @@ -530,10 +530,11 @@ gus_dma_output(addr, buf, size, intr, arg) int flags; DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf)); - + mtx_enter(&audio_lock); if (size != sc->sc_blocksize) { DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n", size, sc->sc_blocksize)); + mtx_leave(&audio_lock); return EINVAL; } @@ -556,8 +557,10 @@ gus_dma_output(addr, buf, size, intr, arg) DPRINTF(("gus_dma_output: unpaired samples")); size &= 1; } - if (size == 0) + if (size == 0) { + mtx_leave(&audio_lock); return 0; + } gus_deinterleave(sc, (void *)buffer, size); @@ -596,7 +599,7 @@ gus_dma_output(addr, buf, size, intr, arg) #endif gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size); - + mtx_leave(&audio_lock); return 0; } @@ -674,6 +677,7 @@ gusintr(arg) #endif if (HAS_CODEC(sc)) retval = ad1848_intr(&sc->sc_codec); + mtx_enter(&audio_lock); if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) { DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags)); #ifdef AUDIO_DEBUG @@ -695,8 +699,11 @@ gusintr(arg) #endif retval += gus_voice_intr(sc); } - if (retval) + if (retval) { + mtx_leave(&audio_lock); return 1; + } + mtx_leave(&audio_lock); return retval; } @@ -727,14 +734,13 @@ gus_dmaout_timeout(arg) struct gus_softc *sc = arg; bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh2 = sc->sc_ioh2; - int s; printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname); /* * Stop any DMA. */ - s = splgus(); + mtx_enter(&audio_lock); SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL); bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0); @@ -744,7 +750,7 @@ gus_dmaout_timeout(arg) #endif gus_dmaout_dointr(sc); - splx(s); + mtx_leave(&audio_lock); } @@ -1522,7 +1528,6 @@ gus_set_params(addr, setmode, usemode, p, r) struct audio_params *p, *r; { struct gus_softc *sc = addr; - int s; switch (p->encoding) { case AUDIO_ENCODING_ULAW: @@ -1536,7 +1541,8 @@ gus_set_params(addr, setmode, usemode, p, r) return (EINVAL); } - s = splaudio(); + /* XXX: why?! this is called with interrupts disabled */ + mtx_enter(&audio_lock); if (p->precision == 8) { sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16; @@ -1550,7 +1556,7 @@ gus_set_params(addr, setmode, usemode, p, r) sc->sc_precision = p->precision; sc->sc_channels = p->channels; - splx(s); + mtx_leave(&audio_lock); if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES]) p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES]; @@ -1685,19 +1691,19 @@ gus_commit_settings(addr) void * addr; { struct gus_softc *sc = addr; - int s; DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain)); - s = splgus(); + /* XXX: why?! this is called with interrupts disabled */ + mtx_enter(&audio_lock); gus_set_recrate(sc, sc->sc_irate); gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain); gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain); gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate); gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate); - splx(s); + mtx_leave(&audio_lock); gus_set_chan_addrs(sc); return 0; @@ -2052,9 +2058,9 @@ gusreset(sc, voices) bus_space_handle_t ioh1 = sc->sc_ioh1; bus_space_handle_t ioh2 = sc->sc_ioh2; bus_space_handle_t ioh4 = sc->sc_ioh4; - int i,s; + int i; - s = splgus(); + mtx_enter(&audio_lock); /* * Reset the GF1 chip @@ -2171,7 +2177,7 @@ gusreset(sc, voices) bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE | GUSMASK_IRQ_ENABLE); - splx(s); + mtx_leave(&audio_lock); } @@ -2289,12 +2295,14 @@ gus_dma_input(addr, buf, size, callback, arg) u_char dmac; DMAPRINTF(("gus_dma_input called\n")); + mtx_enter(&audio_lock); /* * Sample SIZE bytes of data from the card, into buffer at BUF. */ - - if (sc->sc_precision == 16) + if (sc->sc_precision == 16) { + mtx_leave(&audio_lock); return EINVAL; /* XXX */ + } /* set DMA modes */ dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START; @@ -2322,7 +2330,7 @@ gus_dma_input(addr, buf, size, callback, arg) DMAPRINTF(("gus_dma_input returning\n")); - + mtx_leave(&audio_lock); return 0; } @@ -2382,6 +2390,7 @@ gus_halt_out_dma(addr) bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh2 = sc->sc_ioh2; + mtx_enter(&audio_lock); DMAPRINTF(("gus_halt_out_dma called\n")); /* * Make sure the GUS _isn't_ setup for DMA @@ -2403,7 +2412,7 @@ gus_halt_out_dma(addr) /* also stop playing */ gus_stop_voice(sc, GUS_VOICE_LEFT, 1); gus_stop_voice(sc, GUS_VOICE_RIGHT, 0); - + mtx_leave(&audio_lock); return 0; } @@ -2417,6 +2426,8 @@ gus_halt_in_dma(addr) struct gus_softc *sc = addr; bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh2 = sc->sc_ioh2; + + mtx_enter(&audio_lock); DMAPRINTF(("gus_halt_in_dma called\n")); /* @@ -2433,7 +2444,7 @@ gus_halt_in_dma(addr) sc->sc_inarg = 0; sc->sc_dmainaddr = 0; sc->sc_dmaincnt = 0; - + mtx_leave(&audio_lock); return 0; } @@ -3636,7 +3647,7 @@ gus_test_iobase (iot, iobase) { bus_space_handle_t ioh1, ioh2, ioh3, ioh4; u_char s1, s2; - int s, rv = 0; + int rv = 0; /* Map i/o space */ if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1)) @@ -3656,7 +3667,7 @@ gus_test_iobase (iot, iobase) * Reset GUS to an initial state before we do anything. */ - s = splgus(); + mtx_enter(&audio_lock); delay(500); SELECT_GUS_REG(iot, ioh2, GUSREG_RESET); @@ -3669,7 +3680,7 @@ gus_test_iobase (iot, iobase) delay(500); - splx(s); + mtx_leave(&audio_lock); /* * See if we can write to the board's memory diff --git a/sys/dev/isa/ics2101.c b/sys/dev/isa/ics2101.c index b6a23fb7a87..925af05f29c 100644 --- a/sys/dev/isa/ics2101.c +++ b/sys/dev/isa/ics2101.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ics2101.c,v 1.7 2008/06/26 05:42:16 ray Exp $ */ +/* $OpenBSD: ics2101.c,v 1.8 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: ics2101.c,v 1.6 1997/10/09 07:57:23 jtc Exp $ */ /*- @@ -78,7 +78,6 @@ ics2101_mix_doit(sc, chan, side, value, flags) register unsigned char ctrl_addr; register unsigned char attn_addr; register unsigned char normal; - int s; if (chan < ICSMIX_CHAN_0 || chan > ICSMIX_CHAN_5) return; @@ -119,7 +118,7 @@ ics2101_mix_doit(sc, chan, side, value, flags) normal = 0x02; } - s = splaudio(); + mtx_enter(&audio_lock); bus_space_write_1(iot, sc->sc_selio_ioh, sc->sc_selio, ctrl_addr); bus_space_write_1(iot, sc->sc_dataio_ioh, sc->sc_dataio, normal); @@ -127,7 +126,7 @@ ics2101_mix_doit(sc, chan, side, value, flags) bus_space_write_1(iot, sc->sc_selio_ioh, sc->sc_selio, attn_addr); bus_space_write_1(iot, sc->sc_dataio_ioh, sc->sc_dataio, (unsigned char) value); - splx(s); + mtx_leave(&audio_lock); } void diff --git a/sys/dev/isa/mpu401.c b/sys/dev/isa/mpu401.c index 593d0b0fd23..adc4c714aea 100644 --- a/sys/dev/isa/mpu401.c +++ b/sys/dev/isa/mpu401.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpu401.c,v 1.12 2012/03/30 08:18:19 ratchov Exp $ */ +/* $OpenBSD: mpu401.c,v 1.13 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: mpu401.c,v 1.3 1998/11/25 22:17:06 augustss Exp $ */ /* @@ -43,6 +43,7 @@ #include <machine/intr.h> #include <machine/bus.h> +#include <dev/audio_if.h> #include <dev/midi_if.h> #include <dev/isa/isavar.h> @@ -50,10 +51,6 @@ #include <dev/ic/mpuvar.h> -#ifndef splaudio -#define splaudio() splbio() /* XXX found in audio_if.h normally */ -#endif - #ifdef AUDIO_DEBUG #define DPRINTF(x) if (mpu401debug) printf x #define DPRINTFN(n,x) if (mpu401debug >= (n)) printf x @@ -121,22 +118,21 @@ mpu_reset(sc) bus_space_tag_t iot = sc->iot; bus_space_handle_t ioh = sc->ioh; int i; - int s; if (mpu_waitready(sc)) { DPRINTF(("mpu_reset: not ready\n")); return EIO; } - s = splaudio(); /* Don't let the interrupt get our ACK. */ + mtx_enter(&audio_lock); /* Don't let the interrupt get our ACK. */ bus_space_write_1(iot, ioh, MPU_COMMAND, MPU_RESET); for(i = 0; i < 2*MPU_MAXWAIT; i++) { if (!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY) && bus_space_read_1(iot, ioh, MPU_DATA) == MPU_ACK) { - splx(s); + mtx_leave(&audio_lock); return 0; } } - splx(s); + mtx_leave(&audio_lock); DPRINTF(("mpu_reset: No ACK\n")); return EIO; } @@ -194,19 +190,19 @@ mpu_readinput(sc) } } +/* + * called with audio_lock + */ int mpu_output(v, d) void *v; int d; { struct mpu_softc *sc = v; - int s; DPRINTFN(3, ("mpu_output: sc=%p 0x%02x\n", sc, d)); if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY)) { - s = splaudio(); mpu_readinput(sc); - splx(s); } if (MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_OUTPUT_BUSY) delay(10); @@ -231,10 +227,13 @@ mpu_intr(v) { struct mpu_softc *sc = v; + mtx_enter(&audio_lock); if (MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY) { + mtx_leave(&audio_lock); DPRINTF(("mpu_intr: no data\n")); return 0; } mpu_readinput(sc); + mtx_leave(&audio_lock); return 1; } diff --git a/sys/dev/isa/sbdsp.c b/sys/dev/isa/sbdsp.c index 5c5a507f13c..c5709065105 100644 --- a/sys/dev/isa/sbdsp.c +++ b/sys/dev/isa/sbdsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sbdsp.c,v 1.32 2012/03/30 08:18:19 ratchov Exp $ */ +/* $OpenBSD: sbdsp.c,v 1.33 2013/05/15 08:29:24 ratchov Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -412,14 +412,13 @@ sbdsp_mix_write(sc, mixerport, val) { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - int s; - s = splaudio(); + mtx_enter(&audio_lock); bus_space_write_1(iot, ioh, SBP_MIXER_ADDR, mixerport); delay(20); bus_space_write_1(iot, ioh, SBP_MIXER_DATA, val); delay(30); - splx(s); + mtx_leave(&audio_lock); } int @@ -430,14 +429,13 @@ sbdsp_mix_read(sc, mixerport) bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; int val; - int s; - s = splaudio(); + mtx_enter(&audio_lock); bus_space_write_1(iot, ioh, SBP_MIXER_ADDR, mixerport); delay(20); val = bus_space_read_1(iot, ioh, SBP_MIXER_DATA); delay(30); - splx(s); + mtx_leave(&audio_lock); return val; } @@ -1191,7 +1189,9 @@ sbdsp_haltdma(addr) DPRINTF(("sbdsp_haltdma: sc=%p\n", sc)); + mtx_enter(&audio_lock); sbdsp_reset(sc); + mtx_leave(&audio_lock); return 0; } @@ -1236,6 +1236,7 @@ sbdsp_trigger_input(addr, start, end, blksize, intr, arg, param) int stereo = param->channels == 2; int width = param->precision * param->factor; int filter; + int rc; #ifdef DIAGNOSTIC if (stereo && (blksize & 1)) { @@ -1251,7 +1252,7 @@ sbdsp_trigger_input(addr, start, end, blksize, intr, arg, param) #ifdef DIAGNOSTIC if (sc->sc_i.dmachan != sc->sc_drq8) { printf("sbdsp_trigger_input: width=%d bad chan %d\n", - width, sc->sc_i.dmachan); + width, sc->sc_i.dmachan); return (EIO); } #endif @@ -1299,10 +1300,12 @@ sbdsp_trigger_input(addr, start, end, blksize, intr, arg, param) DPRINTF(("sbdsp: dma start loop input start=%p end=%p chan=%d\n", start, end, sc->sc_i.dmachan)); + mtx_enter(&audio_lock); isa_dmastart(sc->sc_isa, sc->sc_i.dmachan, start, (char *)end - (char *)start, NULL, DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT); - - return sbdsp_block_input(addr); + rc = sbdsp_block_input(addr); + mtx_leave(&audio_lock); + return rc; } int @@ -1370,6 +1373,7 @@ sbdsp_trigger_output(addr, start, end, blksize, intr, arg, param) int stereo = param->channels == 2; int width = param->precision * param->factor; int cmd; + int rc; #ifdef DIAGNOSTIC if (stereo && (blksize & 1)) { @@ -1434,10 +1438,12 @@ sbdsp_trigger_output(addr, start, end, blksize, intr, arg, param) DPRINTF(("sbdsp: dma start loop output start=%p end=%p chan=%d\n", start, end, sc->sc_o.dmachan)); + mtx_enter(&audio_lock); isa_dmastart(sc->sc_isa, sc->sc_o.dmachan, start, (char *)end - (char *)start, NULL, DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT); - - return sbdsp_block_output(addr); + rc = sbdsp_block_output(addr); + mtx_leave(&audio_lock); + return rc; } int @@ -1509,12 +1515,19 @@ sbdsp_intr(arg) struct sbdsp_softc *sc = arg; u_char irq; + mtx_enter(&audio_lock); DPRINTFN(2, ("sbdsp_intr: intr8=%p, intr16=%p\n", sc->sc_intr8, sc->sc_intr16)); - if (ISSB16CLASS(sc)) { - irq = sbdsp_mix_read(sc, SBP_IRQ_STATUS); + if (ISSB16CLASS(sc)) { + bus_space_write_1(sc->sc_iot, sc->sc_ioh, + SBP_MIXER_ADDR, SBP_IRQ_STATUS); + delay(20); + irq = bus_space_read_1(sc->sc_iot, sc->sc_ioh, + SBP_MIXER_DATA); + delay(30); if ((irq & (SBP_IRQ_DMA8 | SBP_IRQ_DMA16 | SBP_IRQ_MPU401)) == 0) { DPRINTF(("sbdsp_intr: Spurious interrupt 0x%x\n", irq)); + mtx_leave(&audio_lock); return 0; } } else { @@ -1541,6 +1554,7 @@ sbdsp_intr(arg) mpu_intr(&sc->sc_mpu_sc); } #endif + mtx_leave(&audio_lock); return 1; } diff --git a/sys/dev/isa/wss.c b/sys/dev/isa/wss.c index 7eeef51c921..f78b9a93efc 100644 --- a/sys/dev/isa/wss.c +++ b/sys/dev/isa/wss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wss.c,v 1.24 2010/06/30 11:21:35 jakemsr Exp $ */ +/* $OpenBSD: wss.c,v 1.25 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: wss.c,v 1.42 1998/01/19 22:18:23 augustss Exp $ */ /* @@ -375,7 +375,6 @@ mad_read(sc, port) { u_int tmp; int pwd; - int s; switch (sc->mad_chip_type) { /* Output password */ case MAD_82C928: @@ -391,10 +390,10 @@ mad_read(sc, port) default: panic("mad_read: Bad chip type=%d", sc->mad_chip_type); } - s = splaudio(); /* don't want an interrupt between outb&inb */ + mtx_enter(&audio_lock); /* don't want an interrupt between outb&inb */ bus_space_write_1(sc->sc_iot, sc->mad_ioh, MC_PASSWD_REG, pwd); tmp = bus_space_read_1(sc->sc_iot, sc->mad_ioh, port); - splx(s); + mtx_leave(&audio_lock); return tmp; } @@ -405,7 +404,6 @@ mad_write(sc, port, value) int value; { int pwd; - int s; switch (sc->mad_chip_type) { /* Output password */ case MAD_82C928: @@ -421,10 +419,10 @@ mad_write(sc, port, value) default: panic("mad_write: Bad chip type=%d", sc->mad_chip_type); } - s = splaudio(); + mtx_enter(&audio_lock); bus_space_write_1(sc->sc_iot, sc->mad_ioh, MC_PASSWD_REG, pwd); bus_space_write_1(sc->sc_iot, sc->mad_ioh, port, value & 0xff); - splx(s); + mtx_enter(&audio_lock); } void diff --git a/sys/dev/midi.c b/sys/dev/midi.c index 453524f68b4..48f172a64be 100644 --- a/sys/dev/midi.c +++ b/sys/dev/midi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.c,v 1.29 2013/03/15 09:10:52 ratchov Exp $ */ +/* $OpenBSD: midi.c,v 1.30 2013/05/15 08:29:24 ratchov Exp $ */ /* * Copyright (c) 2003, 2004 Alexandre Ratchov @@ -51,6 +51,7 @@ int midiprint(void *, const char *); void midi_iintr(void *, int); void midi_ointr(void *); +void midi_timeout(void *); void midi_out_start(struct midi_softc *); void midi_out_stop(struct midi_softc *); void midi_out_do(struct midi_softc *); @@ -80,7 +81,6 @@ struct filterops midiread_filtops = { 1, NULL, filt_midirdetach, filt_midiread }; - void midi_iintr(void *addr, int data) { @@ -105,34 +105,33 @@ midi_iintr(void *addr, int data) } } - int midiread(dev_t dev, struct uio *uio, int ioflag) { struct midi_softc *sc = MIDI_DEV2SC(dev); struct midi_buffer *mb = &sc->inbuf; - unsigned count; - int s, error; + unsigned int count; + int error; if (!(sc->flags & FREAD)) return ENXIO; /* if there is no data then sleep (unless IO_NDELAY flag is set) */ - s = splaudio(); + mtx_enter(&audio_lock); while (MIDIBUF_ISEMPTY(mb)) { if (sc->isdying) { - splx(s); + mtx_leave(&audio_lock); return EIO; } if (ioflag & IO_NDELAY) { - splx(s); + mtx_leave(&audio_lock); return EWOULDBLOCK; } sc->rchan = 1; - error = tsleep(&sc->rchan, PWAIT|PCATCH, "mid_rd", 0); + error = msleep(&sc->rchan, &audio_lock, PWAIT | PCATCH, "mid_rd", 0); if (error) { - splx(s); + mtx_leave(&audio_lock); return error; } } @@ -147,26 +146,24 @@ midiread(dev_t dev, struct uio *uio, int ioflag) count = uio->uio_resid; error = uiomove(mb->data + mb->start, count, uio); if (error) { - splx(s); + mtx_leave(&audio_lock); return error; } MIDIBUF_REMOVE(mb, count); } - splx(s); + mtx_leave(&audio_lock); return 0; } - void midi_ointr(void *addr) { struct midi_softc *sc = (struct midi_softc *)addr; struct midi_buffer *mb; - int s; + MUTEX_ASSERT_LOCKED(&audio_lock); if (sc->isopen && !sc->isdying) { mb = &sc->outbuf; - s = splaudio(); if (mb->used > 0) { #ifdef MIDI_DEBUG if (!sc->isbusy) { @@ -176,10 +173,16 @@ midi_ointr(void *addr) midi_out_do(sc); } else if (sc->isbusy) midi_out_stop(sc); - splx(s); } } +void +midi_timeout(void *addr) +{ + mtx_enter(&audio_lock); + midi_ointr(addr); + mtx_leave(&audio_lock); +} void midi_out_start(struct midi_softc *sc) @@ -190,7 +193,6 @@ midi_out_start(struct midi_softc *sc) } } - void midi_out_stop(struct midi_softc *sc) { @@ -204,7 +206,6 @@ midi_out_stop(struct midi_softc *sc) psignal(sc->async, SIGIO); } - void midi_out_do(struct midi_softc *sc) { @@ -230,14 +231,13 @@ midi_out_do(struct midi_softc *sc) } } - int midiwrite(dev_t dev, struct uio *uio, int ioflag) { struct midi_softc *sc = MIDI_DEV2SC(dev); struct midi_buffer *mb = &sc->outbuf; - unsigned count; - int s, error; + unsigned int count; + int error; if (!(sc->flags & FWRITE)) return ENXIO; @@ -254,24 +254,25 @@ midiwrite(dev_t dev, struct uio *uio, int ioflag) return EWOULDBLOCK; while (uio->uio_resid > 0) { - s = splaudio(); + mtx_enter(&audio_lock); while (MIDIBUF_ISFULL(mb)) { if (ioflag & IO_NDELAY) { /* * At this stage at least one byte is already * moved so we do not return EWOULDBLOCK */ - splx(s); + mtx_leave(&audio_lock); return 0; } sc->wchan = 1; - error = tsleep(&sc->wchan, PWAIT|PCATCH, "mid_wr", 0); + error = msleep(&sc->wchan, &audio_lock, + PWAIT | PCATCH, "mid_wr", 0); if (error) { - splx(s); + mtx_leave(&audio_lock); return error; } if (sc->isdying) { - splx(s); + mtx_leave(&audio_lock); return EIO; } } @@ -283,28 +284,27 @@ midiwrite(dev_t dev, struct uio *uio, int ioflag) count = uio->uio_resid; error = uiomove(mb->data + MIDIBUF_END(mb), count, uio); if (error) { - splx(s); + mtx_leave(&audio_lock); return error; } mb->used += count; midi_out_start(sc); - splx(s); + mtx_leave(&audio_lock); } return 0; } - int midipoll(dev_t dev, int events, struct proc *p) { struct midi_softc *sc = MIDI_DEV2SC(dev); - int s, revents; + int revents; if (sc->isdying) return POLLERR; revents = 0; - s = splaudio(); + mtx_enter(&audio_lock); if (events & (POLLIN | POLLRDNORM)) { if (!MIDIBUF_ISEMPTY(&sc->inbuf)) revents |= events & (POLLIN | POLLRDNORM); @@ -319,17 +319,15 @@ midipoll(dev_t dev, int events, struct proc *p) if (events & (POLLOUT | POLLWRNORM)) selrecord(p, &sc->wsel); } - splx(s); + mtx_leave(&audio_lock); return (revents); } - int midikqfilter(dev_t dev, struct knote *kn) { struct midi_softc *sc = MIDI_DEV2SC(dev); struct klist *klist; - int s; switch (kn->kn_filter) { case EVFILT_READ: @@ -345,66 +343,59 @@ midikqfilter(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); } - void filt_midirdetach(struct knote *kn) { struct midi_softc *sc = (struct midi_softc *)kn->kn_hook; - int s; - s = splaudio(); + mtx_enter(&audio_lock); SLIST_REMOVE(&sc->rsel.si_note, kn, knote, kn_selnext); - splx(s); + mtx_leave(&audio_lock); } - int filt_midiread(struct knote *kn, long hint) { struct midi_softc *sc = (struct midi_softc *)kn->kn_hook; - int s, retval; + int retval; - s = splaudio(); + mtx_enter(&audio_lock); retval = !MIDIBUF_ISEMPTY(&sc->inbuf); - splx(s); + mtx_leave(&audio_lock); return (retval); } - void filt_midiwdetach(struct knote *kn) { struct midi_softc *sc = (struct midi_softc *)kn->kn_hook; - int s; - s = splaudio(); + mtx_enter(&audio_lock); SLIST_REMOVE(&sc->wsel.si_note, kn, knote, kn_selnext); - splx(s); + mtx_leave(&audio_lock); } - int filt_midiwrite(struct knote *kn, long hint) { struct midi_softc *sc = (struct midi_softc *)kn->kn_hook; - int s, retval; + int retval; - s = splaudio(); + mtx_enter(&audio_lock); retval = !MIDIBUF_ISFULL(&sc->outbuf); - splx(s); + mtx_leave(&audio_lock); return (retval); } - int midiioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) { @@ -431,12 +422,11 @@ midiioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) return 0; } - int midiopen(dev_t dev, int flags, int mode, struct proc *p) { struct midi_softc *sc; - int err; + int err; if (MIDI_UNIT(dev) >= midi_cd.cd_ndevs) return ENXIO; @@ -462,28 +452,27 @@ midiopen(dev_t dev, int flags, int mode, struct proc *p) return 0; } - int midiclose(dev_t dev, int fflag, int devtype, struct proc *p) { struct midi_softc *sc = MIDI_DEV2SC(dev); struct midi_buffer *mb; - int error; - int s; + int error; mb = &sc->outbuf; if (!sc->isdying) { /* start draining output buffer */ - s = splaudio(); + mtx_enter(&audio_lock); if (!MIDIBUF_ISEMPTY(mb)) midi_out_start(sc); while (sc->isbusy) { sc->wchan = 1; - error = tsleep(&sc->wchan, PWAIT, "mid_dr", 5 * hz); + error = msleep(&sc->wchan, &audio_lock, + PWAIT, "mid_dr", 5 * hz); if (error || sc->isdying) break; } - splx(s); + mtx_leave(&audio_lock); } /* @@ -499,7 +488,6 @@ midiclose(dev_t dev, int fflag, int devtype, struct proc *p) return 0; } - int midiprobe(struct device *parent, void *match, void *aux) { @@ -508,21 +496,19 @@ midiprobe(struct device *parent, void *match, void *aux) return (sa != NULL && (sa->type == AUDIODEV_TYPE_MIDI) ? 1 : 0); } - void midi_attach(struct midi_softc *sc, struct device *parent) { - struct midi_info mi; + struct midi_info mi; sc->isdying = 0; sc->hw_if->getinfo(sc->hw_hdl, &mi); sc->props = mi.props; sc->isopen = 0; - timeout_set(&sc->timeo, midi_ointr, sc); + timeout_set(&sc->timeo, midi_timeout, sc); printf(": <%s>\n", mi.name); } - void midiattach(struct device *parent, struct device *self, void *aux) { @@ -546,12 +532,11 @@ midiattach(struct device *parent, struct device *self, void *aux) midi_attach(sc, parent); } - int mididetach(struct device *self, int flags) { struct midi_softc *sc = (struct midi_softc *)self; - int maj, mn; + int maj, mn; sc->isdying = 1; if (sc->wchan) { @@ -574,7 +559,6 @@ mididetach(struct device *self, int flags) return 0; } - int midiprint(void *aux, const char *pnp) { @@ -583,7 +567,6 @@ midiprint(void *aux, const char *pnp) return (UNCONF); } - void midi_getinfo(dev_t dev, struct midi_info *mi) { @@ -597,7 +580,6 @@ midi_getinfo(dev_t dev, struct midi_info *mi) sc->hw_if->getinfo(sc->hw_hdl, mi); } - struct device * midi_attach_mi(struct midi_hw_if *hwif, void *hdl, struct device *dev) { diff --git a/sys/dev/pci/auacer.c b/sys/dev/pci/auacer.c index 84762bbc3ea..1729bfa1536 100644 --- a/sys/dev/pci/auacer.c +++ b/sys/dev/pci/auacer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auacer.c,v 1.12 2011/07/03 15:47:16 matthew Exp $ */ +/* $OpenBSD: auacer.c,v 1.13 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: auacer.c,v 1.3 2004/11/10 04:20:26 kent Exp $ */ /*- @@ -704,7 +704,9 @@ auacer_halt_output(void *v) struct auacer_softc *sc = v; DPRINTF(ALI_DEBUG_DMA, ("auacer_halt_output\n")); + mtx_enter(&audio_lock); auacer_halt(sc, &sc->sc_pcmo); + mtx_leave(&audio_lock); return (0); } @@ -895,6 +897,7 @@ auacer_intr(void *v) struct auacer_softc *sc = v; int ret, intrs; + mtx_enter(&audio_lock); intrs = READ4(sc, ALI_INTERRUPTSR); DPRINTF(ALI_DEBUG_INTR, ("auacer_intr: intrs=0x%x\n", intrs)); @@ -903,7 +906,7 @@ auacer_intr(void *v) auacer_upd_chan(sc, &sc->sc_pcmo); ret++; } - + mtx_leave(&audio_lock); return ret != 0; } @@ -962,9 +965,10 @@ auacer_trigger_output(void *v, void *start, void *end, int blksize, } size = (char *)end - (char *)start; + mtx_enter(&audio_lock); auacer_setup_chan(sc, &sc->sc_pcmo, DMAADDR(p), size, blksize, intr, arg); - + mtx_leave(&audio_lock); return 0; } diff --git a/sys/dev/pci/auglx.c b/sys/dev/pci/auglx.c index 69175f52339..697e9c46ea0 100644 --- a/sys/dev/pci/auglx.c +++ b/sys/dev/pci/auglx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auglx.c,v 1.8 2011/07/03 15:47:16 matthew Exp $ */ +/* $OpenBSD: auglx.c,v 1.9 2013/05/15 08:29:24 ratchov Exp $ */ /* * Copyright (c) 2008 Marc Balmer <mbalmer@openbsd.org> @@ -1056,9 +1056,12 @@ auglx_intr(void *v) u_int16_t irq_sts; u_int8_t bm_sts; + mtx_enter(&audio_lock); irq_sts = bus_space_read_2(sc->sc_iot, sc->sc_ioh, ACC_IRQ_STATUS); - if (irq_sts == 0) + if (irq_sts == 0) { + mtx_leave(&audio_lock); return 0; + } if (irq_sts & BM0_IRQ_STS) { bm_sts = bus_space_read_1(sc->sc_iot, sc->sc_ioh, @@ -1079,8 +1082,10 @@ auglx_intr(void *v) } else { DPRINTF(AUGLX_DBG_IRQ, ("%s: stray intr, status = 0x%04x\n", sc->sc_dev.dv_xname, irq_sts)); + mtx_leave(&audio_lock); return -1; } + mtx_leave(&audio_lock); return 1; } @@ -1134,12 +1139,14 @@ auglx_trigger_output(void *v, void *start, void *end, int blksize, sc->bm0.intr = intr; sc->bm0.arg = arg; + mtx_enter(&audio_lock); /* Program the BM0 PRD register */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_PRD, sc->bm0.sc_prd->dm_segs[0].ds_addr); /* Start Audio Bus Master 0 */ bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD, BMx_CMD_BM_CTL_EN); + mtx_leave(&audio_lock); return 0; } @@ -1193,12 +1200,14 @@ auglx_trigger_input(void *v, void *start, void *end, int blksize, sc->bm1.intr = intr; sc->bm1.arg = arg; - /* Program the BM1 PRD register */ + mtx_enter(&audio_lock); + /* Program the BM1 PRD register */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM1_PRD, sc->bm1.sc_prd->dm_segs[0].ds_addr); /* Start Audio Bus Master 0 */ bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM1_CMD, BMx_CMD_RW | BMx_CMD_BM_CTL_EN); + mtx_leave(&audio_lock); return 0; } diff --git a/sys/dev/pci/auich.c b/sys/dev/pci/auich.c index 4ad6df0a432..ea0923e33ac 100644 --- a/sys/dev/pci/auich.c +++ b/sys/dev/pci/auich.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auich.c,v 1.96 2012/01/11 16:22:33 dhill Exp $ */ +/* $OpenBSD: auich.c,v 1.97 2013/05/15 08:29:24 ratchov Exp $ */ /* * Copyright (c) 2000,2001 Michael Shalayeff @@ -1234,10 +1234,11 @@ auich_halt_output(void *v) DPRINTF(AUICH_DEBUG_DMA, ("%s: halt_output\n", sc->sc_dev.dv_xname)); + mtx_enter(&audio_lock); auich_halt_pipe(sc, AUICH_PCMO, &sc->pcmo); sc->pcmo.intr = NULL; - + mtx_leave(&audio_lock); return 0; } @@ -1250,12 +1251,12 @@ auich_halt_input(void *v) ("%s: halt_input\n", sc->sc_dev.dv_xname)); /* XXX halt both unless known otherwise */ - + mtx_enter(&audio_lock); auich_halt_pipe(sc, AUICH_PCMI, &sc->pcmi); auich_halt_pipe(sc, AUICH_MICI, &sc->mici); sc->pcmi.intr = NULL; - + mtx_leave(&audio_lock); return 0; } @@ -1385,6 +1386,7 @@ auich_intr(void *v) struct auich_softc *sc = v; int ret = 0, sts, gsts; + mtx_enter(&audio_lock); gsts = bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GSTS); DPRINTF(AUICH_DEBUG_INTR, ("auich_intr: gsts=%b\n", gsts, AUICH_GSTS_BITS)); @@ -1479,7 +1481,7 @@ auich_intr(void *v) bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_GSTS, AUICH_MINT); ret++; } - + mtx_leave(&audio_lock); return ret; } @@ -1604,10 +1606,11 @@ auich_trigger_output(void *v, void *start, void *end, int blksize, sc->pcmo.end = sc->pcmo.start + size; sc->pcmo.blksize = blksize; + mtx_enter(&audio_lock); bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_BDBAR, sc->sc_cddma + AUICH_PCMO_OFF(0)); auich_trigger_pipe(sc, AUICH_PCMO, &sc->pcmo); - + mtx_leave(&audio_lock); return 0; } @@ -1651,11 +1654,11 @@ auich_trigger_input(v, start, end, blksize, intr, arg, param) sc->pcmi.p = sc->pcmi.start; sc->pcmi.end = sc->pcmi.start + size; sc->pcmi.blksize = blksize; - + mtx_enter(&audio_lock); bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_BDBAR, sc->sc_cddma + AUICH_PCMI_OFF(0)); auich_trigger_pipe(sc, AUICH_PCMI, &sc->pcmi); - + mtx_leave(&audio_lock); return 0; } diff --git a/sys/dev/pci/auixp.c b/sys/dev/pci/auixp.c index 91901654e3e..325d37c6990 100644 --- a/sys/dev/pci/auixp.c +++ b/sys/dev/pci/auixp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auixp.c,v 1.29 2011/07/03 15:47:16 matthew Exp $ */ +/* $OpenBSD: auixp.c,v 1.30 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: auixp.c,v 1.9 2005/06/27 21:13:09 thorpej Exp $ */ /* @@ -957,10 +957,12 @@ auixp_trigger_output(void *hdl, void *start, void *end, int blksize, auixp_program_dma_chain(sc, chain_dma); /* mark we are now able to run now */ + mtx_enter(&audio_lock); chain_dma->running = 1; /* update bus-flags; XXX programs more flags XXX */ auixp_update_busbusy(sc); + mtx_leave(&audio_lock); /* callbacks happen in interrupt routine */ return 0; @@ -975,6 +977,7 @@ auixp_halt_output(void *hdl) struct auixp_softc *sc; struct auixp_dma *dma; + mtx_enter(&audio_lock); co = (struct auixp_codec *) hdl; sc = co->sc; dma = sc->sc_output_dma; @@ -982,7 +985,7 @@ auixp_halt_output(void *hdl) dma->running = 0; auixp_update_busbusy(sc); - + mtx_leave(&audio_lock); return 0; } @@ -1032,10 +1035,12 @@ auixp_trigger_input(void *hdl, void *start, void *end, int blksize, auixp_program_dma_chain(sc, chain_dma); /* mark we are now able to run now */ + mtx_enter(&audio_lock); chain_dma->running = 1; /* update bus-flags; XXX programs more flags XXX */ auixp_update_busbusy(sc); + mtx_leave(&audio_lock); /* callbacks happen in interrupt routine */ return 0; @@ -1050,6 +1055,7 @@ auixp_halt_input(void *hdl) struct auixp_softc *sc; struct auixp_dma *dma; + mtx_enter(&audio_lock); co = (struct auixp_codec *) hdl; sc = co->sc; dma = sc->sc_input_dma; @@ -1058,6 +1064,7 @@ auixp_halt_input(void *hdl) dma->running = 0; auixp_update_busbusy(sc); + mtx_leave(&audio_lock); return 0; } @@ -1079,6 +1086,7 @@ auixp_intr(void *softc) u_int32_t status, enable, detected_codecs; int ret; + mtx_enter(&audio_lock); sc = softc; iot = sc->sc_iot; ioh = sc->sc_ioh; @@ -1086,8 +1094,10 @@ auixp_intr(void *softc) /* get status from the interrupt status register */ status = bus_space_read_4(iot, ioh, ATI_REG_ISR); - if (status == 0) + if (status == 0) { + mtx_leave(&audio_lock); return 0; + } DPRINTF(("%s: (status = %x)\n", sc->sc_dev.dv_xname, status)); @@ -1127,7 +1137,7 @@ auixp_intr(void *softc) /* acknowledge interrupt sources */ bus_space_write_4(iot, ioh, ATI_REG_ISR, status); - + mtx_leave(&audio_lock); return ret; } 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; } diff --git a/sys/dev/pci/auvia.c b/sys/dev/pci/auvia.c index 827764dd22a..474b0378d89 100644 --- a/sys/dev/pci/auvia.c +++ b/sys/dev/pci/auvia.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auvia.c,v 1.49 2011/07/03 15:47:16 matthew Exp $ */ +/* $OpenBSD: auvia.c,v 1.50 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: auvia.c,v 1.28 2002/11/04 16:38:49 kent Exp $ */ /*- @@ -511,6 +511,7 @@ auvia_close(void *addr) struct auvia_softc *sc = addr; sc->codec_if->vtbl->unlock(sc->codec_if); + /* XXX: already called by audio_close() */ auvia_halt_output(sc); auvia_halt_input(sc); @@ -1061,7 +1062,7 @@ auvia_trigger_output(void *addr, void *start, void *end, int blksize, CH_WRITE4(sc, ch, AUVIA_RP_DMAOPS_BASE, ch->sc_dma_ops_dma->map->dm_segs[0].ds_addr); - + mtx_enter(&audio_lock); if (sc->sc_flags & AUVIA_FLAGS_VT8233) { if (ch->sc_base != VIA8233_MP_BASE) { CH_WRITE1(sc, ch, VIA8233_RP_DXS_LVOL, 0); @@ -1074,7 +1075,7 @@ auvia_trigger_output(void *addr, void *start, void *end, int blksize, CH_WRITE1(sc, ch, AUVIA_RP_MODE, ch->sc_reg); CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_START); } - + mtx_leave(&audio_lock); return 0; } @@ -1103,6 +1104,7 @@ auvia_trigger_input(void *addr, void *start, void *end, int blksize, CH_WRITE4(sc, ch, AUVIA_RP_DMAOPS_BASE, ch->sc_dma_ops_dma->map->dm_segs[0].ds_addr); + mtx_enter(&audio_lock); if (sc->sc_flags & AUVIA_FLAGS_VT8233) { if (ch->sc_base != VIA8233_MP_BASE) { CH_WRITE1(sc, ch, VIA8233_RP_DXS_LVOL, 0); @@ -1115,6 +1117,7 @@ auvia_trigger_input(void *addr, void *start, void *end, int blksize, CH_WRITE1(sc, ch, AUVIA_RP_MODE, ch->sc_reg); CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_START); } + mtx_leave(&audio_lock); return 0; } @@ -1127,7 +1130,7 @@ auvia_intr(void *arg) u_int8_t r; int i = 0; - + mtx_enter(&audio_lock); ch = &sc->sc_record; r = CH_READ1(sc, ch, AUVIA_RP_STAT); if (r & AUVIA_RPSTAT_INTR) { @@ -1150,7 +1153,7 @@ auvia_intr(void *arg) i++; } - + mtx_leave(&audio_lock); return (i? 1 : 0); } diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c index 57282ace881..29ae80ea464 100644 --- a/sys/dev/pci/azalia.c +++ b/sys/dev/pci/azalia.c @@ -1,4 +1,4 @@ -/* $OpenBSD: azalia.c,v 1.203 2013/02/09 21:02:17 miod Exp $ */ +/* $OpenBSD: azalia.c,v 1.204 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */ /*- @@ -665,16 +665,39 @@ azalia_pci_detach(struct device *self, int flags) return 0; } +/* +#define AZALIA_LOG_MP +*/ +#ifdef AZALIA_LOG_MP +#include <machine/lock.h> +#include <machine/cpufunc.h> +#endif + int azalia_intr(void *v) { +#ifdef AZALIA_LOG_MP + volatile struct cpu_info *ci; +#endif azalia_t *az = v; uint32_t intsts; int ret = 0; +#ifdef AZALIA_LOG_MP + ci = kernel_lock.mpl_cpu; + if (ci == NULL) + printf("azalia_intr: mp not held\n"); + else { + printf("azalia_intr: lock held by %p, id = %u\n", + ci, ci->ci_cpuid); + } +#endif + mtx_enter(&audio_lock); intsts = AZ_READ_4(az, INTSTS); - if (intsts == 0 || intsts == 0xffffffff) + if (intsts == 0 || intsts == 0xffffffff) { + mtx_leave(&audio_lock); return (ret); + } AZ_WRITE_4(az, INTSTS, intsts); @@ -694,7 +717,7 @@ azalia_intr(void *v) azalia_rirb_intr(az); ret = 1; } - + mtx_leave(&audio_lock); return (ret); } @@ -1143,17 +1166,16 @@ int azalia_comresp(const codec_t *codec, nid_t nid, uint32_t control, uint32_t param, uint32_t* result) { - int err, s; + int err; - s = splaudio(); + mtx_enter(&audio_lock); err = azalia_set_command(codec->az, codec->address, nid, control, param); if (err) goto exit; err = azalia_get_response(codec->az, result); exit: - splx(s); - + mtx_leave(&audio_lock); return(err); } @@ -3763,7 +3785,6 @@ azalia_stream_start(stream_t *this) STR_WRITE_1(this, CTL, STR_READ_1(this, CTL) | HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE | HDA_SD_CTL_RUN); - return (0); } diff --git a/sys/dev/pci/cmpci.c b/sys/dev/pci/cmpci.c index 96a7cfb3d2b..6a14efd705a 100644 --- a/sys/dev/pci/cmpci.c +++ b/sys/dev/pci/cmpci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmpci.c,v 1.33 2011/07/03 15:47:17 matthew Exp $ */ +/* $OpenBSD: cmpci.c,v 1.34 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: cmpci.c,v 1.25 2004/10/26 06:32:20 xtraeme Exp $ */ /* @@ -561,11 +561,14 @@ cmpci_intr(void *handle) uint32_t intrstat; uint16_t hwpos; + mtx_enter(&audio_lock); intrstat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_INTR_STATUS); - if (!(intrstat & CMPCI_REG_ANY_INTR)) + if (!(intrstat & CMPCI_REG_ANY_INTR)) { + mtx_leave(&audio_lock); return 0; + } delay(10); @@ -629,6 +632,7 @@ cmpci_intr(void *handle) mpu_intr(sc->sc_mpudev); #endif + mtx_leave(&audio_lock); return 1; } @@ -994,9 +998,8 @@ cmpci_halt_output(void *handle) { struct cmpci_softc *sc = handle; uint32_t reg_intr, reg_enable, reg_reset; - int s; - s = splaudio(); + mtx_enter(&audio_lock); if (sc->sc_play_channel == 1) { sc->sc_ch1.intr = NULL; reg_intr = CMPCI_REG_CH1_INTR_ENABLE; @@ -1014,8 +1017,7 @@ cmpci_halt_output(void *handle) cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_reset); delay(10); cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_reset); - splx(s); - + mtx_leave(&audio_lock); return 0; } @@ -1023,9 +1025,8 @@ int cmpci_halt_input(void *handle) { struct cmpci_softc *sc = handle; - int s; - s = splaudio(); + mtx_enter(&audio_lock); sc->sc_ch1.intr = NULL; cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); @@ -1033,8 +1034,7 @@ cmpci_halt_input(void *handle) cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); delay(10); cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); - splx(s); - + mtx_leave(&audio_lock); return 0; } @@ -2046,10 +2046,11 @@ cmpci_trigger_output(void *handle, void *start, void *end, int blksize, delay(10); /* start DMA */ + mtx_enter(&audio_lock); cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_dir); /* PLAY */ cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, reg_intr_enable); cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_enable); - + mtx_leave(&audio_lock); return 0; } @@ -2090,10 +2091,11 @@ cmpci_trigger_input(void *handle, void *start, void *end, int blksize, delay(10); /* start DMA */ + mtx_enter(&audio_lock); cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR); /* REC */ cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); - + mtx_leave(&audio_lock); return 0; } diff --git a/sys/dev/pci/cs4280.c b/sys/dev/pci/cs4280.c index b24d20a84e7..357479d221c 100644 --- a/sys/dev/pci/cs4280.c +++ b/sys/dev/pci/cs4280.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cs4280.c,v 1.41 2012/01/11 16:22:33 dhill Exp $ */ +/* $OpenBSD: cs4280.c,v 1.42 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: cs4280.c,v 1.5 2000/06/26 04:56:23 simonb Exp $ */ /* @@ -680,6 +680,7 @@ cs4280_intr(void *p) char * empty_dma; int handled = 0; + mtx_enter(&audio_lock); /* grab interrupt register then clear it */ intr = BA0READ4(sc, CS4280_HISR); BA0WRITE4(sc, CS4280_HICR, HICR_CHGM | HICR_IEV); @@ -812,7 +813,7 @@ cs4280_intr(void *p) DPRINTF(("\n")); } #endif - + mtx_leave(&audio_lock); return handled; } @@ -1007,6 +1008,7 @@ cs4280_close(void *addr) { struct cs4280_softc *sc = addr; + /* XXX: already called in audio_close() */ cs4280_halt_output(sc); cs4280_halt_input(sc); @@ -1257,11 +1259,13 @@ cs4280_halt_output(void *addr) struct cs4280_softc *sc = addr; u_int32_t mem; + mtx_enter(&audio_lock); mem = BA1READ4(sc, CS4280_PCTL); BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK); #ifdef DIAGNOSTIC sc->sc_prun = 0; #endif + mtx_leave(&audio_lock); return (0); } @@ -1271,11 +1275,13 @@ cs4280_halt_input(void *addr) struct cs4280_softc *sc = addr; u_int32_t mem; + mtx_enter(&audio_lock); mem = BA1READ4(sc, CS4280_CCTL); BA1WRITE4(sc, CS4280_CCTL, mem & ~CCTL_MASK); #ifdef DIAGNOSTIC sc->sc_rrun = 0; #endif + mtx_leave(&audio_lock); return (0); } @@ -1425,7 +1431,6 @@ cs4280_trigger_output(void *addr, void *start, void *end, int blksize, printf("cs4280_trigger_output: already running\n"); sc->sc_prun = 1; #endif - DPRINTF(("cs4280_trigger_output: sc=%p start=%p end=%p " "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); sc->sc_pintr = intr; @@ -1473,6 +1478,7 @@ cs4280_trigger_output(void *addr, void *start, void *end, int blksize, } /* initiate playback dma */ + mtx_enter(&audio_lock); BA1WRITE4(sc, CS4280_PBA, DMAADDR(p)); /* set PFIE */ @@ -1497,6 +1503,7 @@ cs4280_trigger_output(void *addr, void *start, void *end, int blksize, pctl = BA1READ4(sc, CS4280_PCTL) & ~PCTL_MASK; pctl |= sc->pctl; BA1WRITE4(sc, CS4280_PCTL, pctl); + mtx_leave(&audio_lock); return (0); } @@ -1554,6 +1561,7 @@ cs4280_trigger_input(void *addr, void *start, void *end, int blksize, sc->sc_rbuf = KERNADDR(p); /* initiate capture dma */ + mtx_enter(&audio_lock); BA1WRITE4(sc, CS4280_CBA, DMAADDR(p)); /* set CIE */ @@ -1565,6 +1573,7 @@ cs4280_trigger_input(void *addr, void *start, void *end, int blksize, cctl = BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK; cctl |= sc->cctl; BA1WRITE4(sc, CS4280_CCTL, cctl); + mtx_leave(&audio_lock); return (0); } diff --git a/sys/dev/pci/cs4281.c b/sys/dev/pci/cs4281.c index 6c3fe26f45b..a9462efe027 100644 --- a/sys/dev/pci/cs4281.c +++ b/sys/dev/pci/cs4281.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cs4281.c,v 1.27 2011/04/03 15:36:02 jasper Exp $ */ +/* $OpenBSD: cs4281.c,v 1.28 2013/05/15 08:29:24 ratchov Exp $ */ /* $Tera: cs4281.c,v 1.18 2000/12/27 14:24:45 tacha Exp $ */ /* @@ -376,9 +376,11 @@ cs4281_intr(p) u_int32_t intr, val; char *empty_dma; + mtx_enter(&audio_lock); intr = BA0READ4(sc, CS4281_HISR); if (!(intr & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) { BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM); + mtx_leave(&audio_lock); return (0); } DPRINTF(("cs4281_intr:")); @@ -429,6 +431,7 @@ cs4281_intr(p) } } DPRINTF(("\n")); + mtx_leave(&audio_lock); return (1); } @@ -638,6 +641,7 @@ cs4281_trigger_output(addr, start, end, blksize, intr, arg, param) ; if (p == NULL) { printf("cs4281_trigger_output: bad addr %p\n", start); + mtx_leave(&audio_lock); return (EINVAL); } @@ -686,6 +690,7 @@ cs4281_trigger_output(addr, start, end, blksize, intr, arg, param) cs4281_set_dac_rate(sc, param->sample_rate); /* start DMA */ + mtx_enter(&audio_lock); BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) & ~DCRn_MSK); /* Enable interrupts */ BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM); @@ -703,7 +708,7 @@ cs4281_trigger_output(addr, start, end, blksize, intr, arg, param) DPRINTF(("SRCSA=0x%08x(expected 0x0b0a0100)\n", BA0READ4(sc, CS4281_SRCSA))); DPRINTF(("SSPM&SSPM_PSRCEN =0x%08x(expected 0x00000010)\n", BA0READ4(sc, CS4281_SSPM) & SSPM_PSRCEN)); - + mtx_leave(&audio_lock); return (0); } @@ -779,6 +784,7 @@ cs4281_trigger_input(addr, start, end, blksize, intr, arg, param) cs4281_set_adc_rate(sc, param->sample_rate); /* Start DMA */ + mtx_enter(&audio_lock); BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) & ~DCRn_MSK); /* Enable interrupts */ BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM); @@ -787,7 +793,7 @@ cs4281_trigger_input(addr, start, end, blksize, intr, arg, param) DPRINTF(("HIMR=0x%08x\n", BA0READ4(sc, CS4281_HIMR))); DPRINTF(("DMR1=0x%08x\n", BA0READ4(sc, CS4281_DMR1))); DPRINTF(("DCR1=0x%08x\n", BA0READ4(sc, CS4281_DCR1))); - + mtx_leave(&audio_lock); return (0); } 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); } diff --git a/sys/dev/pci/emuxki.c b/sys/dev/pci/emuxki.c index d2bc624829b..a1733765b05 100644 --- a/sys/dev/pci/emuxki.c +++ b/sys/dev/pci/emuxki.c @@ -1,4 +1,4 @@ -/* $OpenBSD: emuxki.c,v 1.40 2011/07/03 15:47:17 matthew Exp $ */ +/* $OpenBSD: emuxki.c,v 1.41 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: emuxki.c,v 1.1 2001/10/17 18:39:41 jdolecek Exp $ */ /*- @@ -619,7 +619,6 @@ emuxki_read(struct emuxki_softc *sc, u_int16_t chano, u_int32_t reg) { u_int32_t ptr, mask = 0xffffffff; u_int8_t size, offset = 0; - int s; ptr = ((((u_int32_t) reg) << 16) & (sc->sc_flags & EMUXKI_AUDIGY ? @@ -631,12 +630,9 @@ emuxki_read(struct emuxki_softc *sc, u_int16_t chano, u_int32_t reg) mask = ((1 << size) - 1) << offset; } - s = splaudio(); bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_PTR, ptr); ptr = (bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_DATA) & mask) >> offset; - splx(s); - return (ptr); } @@ -646,7 +642,6 @@ emuxki_write(struct emuxki_softc *sc, u_int16_t chano, { u_int32_t ptr, mask; u_int8_t size, offset; - int s; ptr = ((((u_int32_t) reg) << 16) & (sc->sc_flags & EMUXKI_AUDIGY ? @@ -665,10 +660,8 @@ emuxki_write(struct emuxki_softc *sc, u_int16_t chano, (emuxki_read(sc, chano, reg & 0xffff) & ~mask); } - s = splaudio(); bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_PTR, ptr); bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_DATA, data); - splx(s); } /* Microcode should this go in /sys/dev/microcode ? */ @@ -1051,7 +1044,7 @@ emuxki_mem_delete(struct emuxki_mem *mem, int type) void * emuxki_pmem_alloc(struct emuxki_softc *sc, size_t size, int type, int flags) { - int i, j, s; + int i, j; size_t numblocks; struct emuxki_mem *mem; u_int32_t *ptb, silentpage; @@ -1065,7 +1058,6 @@ emuxki_pmem_alloc(struct emuxki_softc *sc, size_t size, int type, int flags) for (i = 0; i < EMU_MAXPTE; i++) if ((letoh32(ptb[i]) & EMU_CHAN_MAP_PTE_MASK) == silentpage) { /* We look for a free PTE */ - s = splaudio(); for (j = 0; j < numblocks; j++) if ((letoh32(ptb[i + j]) & EMU_CHAN_MAP_PTE_MASK) @@ -1074,19 +1066,18 @@ emuxki_pmem_alloc(struct emuxki_softc *sc, size_t size, int type, int flags) if (j == numblocks) { if ((mem = emuxki_mem_new(sc, i, size, type, flags)) == NULL) { - splx(s); return (NULL); } for (j = 0; j < numblocks; j++) ptb[i + j] = htole32((((DMAADDR(mem->dmamem) + j * EMU_PTESIZE)) << 1) | (i + j)); + mtx_enter(&audio_lock); LIST_INSERT_HEAD(&(sc->mem), mem, next); - splx(s); + mtx_leave(&audio_lock); return (KERNADDR(mem->dmamem)); } else i += j; - splx(s); } return (NULL); } @@ -1095,15 +1086,14 @@ void * emuxki_rmem_alloc(struct emuxki_softc *sc, size_t size, int type, int flags) { struct emuxki_mem *mem; - int s; mem = emuxki_mem_new(sc, EMU_RMEM, size, type, flags); if (mem == NULL) return (NULL); - s = splaudio(); + mtx_enter(&audio_lock); LIST_INSERT_HEAD(&(sc->mem), mem, next); - splx(s); + mtx_leave(&audio_lock); return (KERNADDR(mem->dmamem)); } @@ -1296,13 +1286,12 @@ emuxki_channel_commit_parms(struct emuxki_channel *chan) struct emuxki_softc *sc = voice->sc; u_int32_t start, mapval; u_int8_t chano = chan->num; - int s; start = chan->loop.start + (voice->stereo ? 28 : 30) * (voice->b16 + 1); mapval = DMAADDR(sc->silentpage) << 1 | EMU_CHAN_MAP_PTI_MASK; - s = splaudio(); + mtx_enter(&audio_lock); emuxki_write(sc, chano, EMU_CHAN_CPF_STEREO, voice->stereo); emuxki_channel_commit_fx(chan); @@ -1347,7 +1336,7 @@ emuxki_channel_commit_parms(struct emuxki_channel *chan) emuxki_write(sc, chano, EMU_CHAN_PEFE, (chan->pitch.envelope_amount << 8) | chan->filter.envelope_amount); - splx(s); + mtx_leave(&audio_lock); } void @@ -1357,13 +1346,11 @@ emuxki_channel_start(struct emuxki_channel *chan) struct emuxki_softc *sc = voice->sc; u_int8_t cache_sample, cache_invalid_size, chano = chan->num; u_int32_t sample; - int s; cache_sample = voice->stereo ? 4 : 2; sample = voice->b16 ? 0x00000000 : 0x80808080; cache_invalid_size = (voice->stereo ? 28 : 30) * (voice->b16 + 1); - s = splaudio(); while (cache_sample--) { emuxki_write(sc, chano, EMU_CHAN_CD0 + cache_sample, sample); @@ -1393,25 +1380,20 @@ emuxki_channel_start(struct emuxki_channel *chan) emuxki_write(sc, chano, EMU_CHAN_CPF_PITCH, chan->pitch.current); emuxki_write(sc, chano, EMU_CHAN_IP, chan->pitch.initial); - - splx(s); } void emuxki_channel_stop(struct emuxki_channel *chan) { - int s; u_int8_t chano = chan->num; struct emuxki_softc *sc = chan->voice->sc; - s = splaudio(); emuxki_write(sc, chano, EMU_CHAN_PTRX_PITCHTARGET, 0); emuxki_write(sc, chano, EMU_CHAN_CPF_PITCH, 0); emuxki_write(sc, chano, EMU_CHAN_IFATN_ATTENUATION, 0xff); emuxki_write(sc, chano, EMU_CHAN_VTFT_VOLUMETARGET, 0); emuxki_write(sc, chano, EMU_CHAN_CVCF_CURRVOL, 0); emuxki_write(sc, chano, EMU_CHAN_IP, 0); - splx(s); } /* @@ -1427,18 +1409,15 @@ emuxki_voice_channel_create(struct emuxki_voice *voice) { struct emuxki_channel **channel = voice->sc->channel; u_int8_t i, stereo = voice->stereo; - int s; for (i = 0; i < EMU_NUMCHAN; i += stereo + 1) { if ((stereo && (channel[i + 1] != NULL)) || (channel[i] != NULL)) /* Looking for free channels */ continue; - s = splaudio(); if (stereo) { voice->dataloc.chan[1] = emuxki_channel_new(voice, i + 1); if (voice->dataloc.chan[1] == NULL) { - splx(s); return (ENOMEM); } } @@ -1448,10 +1427,8 @@ emuxki_voice_channel_create(struct emuxki_voice *voice) emuxki_channel_delete(voice->dataloc.chan[1]); voice->dataloc.chan[1] = NULL; } - splx(s); return (ENOMEM); } - splx(s); return (0); } return (EAGAIN); @@ -1530,12 +1507,11 @@ struct emuxki_voice * emuxki_voice_new(struct emuxki_softc *sc, u_int8_t use) { struct emuxki_voice *voice; - int s; - s = splaudio(); + mtx_enter(&audio_lock); voice = sc->lvoice; sc->lvoice = NULL; - splx(s); + mtx_leave(&audio_lock); if (!voice) { if (!(voice = malloc(sizeof(*voice), M_DEVBUF, M_WAITOK))) @@ -1563,9 +1539,9 @@ emuxki_voice_new(struct emuxki_softc *sc, u_int8_t use) voice->use = use; skip_initialize: - s = splaudio(); + mtx_enter(&audio_lock); LIST_INSERT_HEAD((&sc->voices), voice, next); - splx(s); + mtx_leave(&audio_lock); return (voice); } @@ -1575,16 +1551,15 @@ emuxki_voice_delete(struct emuxki_voice *voice) { struct emuxki_softc *sc = voice->sc; struct emuxki_voice *lvoice; - int s; if (voice->state & EMU_VOICE_STATE_STARTED) emuxki_voice_halt(voice); - s = splaudio(); + mtx_enter(&audio_lock); LIST_REMOVE(voice, next); lvoice = sc->lvoice; sc->lvoice = voice; - splx(s); + mtx_leave(&audio_lock); if (lvoice) { emuxki_voice_dataloc_destroy(lvoice); @@ -1754,12 +1729,13 @@ emuxki_voice_set_bufparms(struct emuxki_voice *voice, void *ptr, #endif return (EINVAL); } + mtx_enter(&audio_lock); emuxki_write(voice->sc, 0, emuxki_recsrc_szreg[voice->dataloc.source], idx); emuxki_write(voice->sc, 0, emuxki_recsrc_bufaddrreg[voice->dataloc.source], DMAADDR(mem->dmamem)); - + mtx_leave(&audio_lock); /* Use timer to emulate DMA completion interrupt */ voice->timerate = (u_int32_t) 48000 * blksize / (voice->sample_rate * sample_size); @@ -1832,9 +1808,7 @@ emuxki_resched_timer(struct emuxki_softc *sc) struct emuxki_voice *voice; u_int16_t timerate = 1024; u_int8_t active = 0; - int s; - s = splaudio(); LIST_FOREACH(voice, &sc->voices, next) { if ((voice->state & EMU_VOICE_STATE_STARTED) == 0) continue; @@ -1857,7 +1831,6 @@ emuxki_resched_timer(struct emuxki_softc *sc) EMU_INTE_INTERTIMERENB); sc->timerstate |= EMU_TIMER_STATE_ENABLED; } - splx(s); } int @@ -1919,6 +1892,7 @@ emuxki_voice_start(struct emuxki_voice *voice, { u_int32_t val; + mtx_enter(&audio_lock); voice->inth = inth; voice->inthparam = inthparam; if (voice->use & EMU_VOICE_USE_PLAY) { @@ -1955,21 +1929,20 @@ emuxki_voice_start(struct emuxki_voice *voice, } #if 0 /* DMA completion interrupt is useless; use timer */ - int s; - s = splaudio(); val = emu_rd(sc, INTE, 4); val |= emuxki_recsrc_intrmasks[voice->dataloc.source]; emu_wr(sc, INTE, val, 4); - splx(s); #endif } voice->state |= EMU_VOICE_STATE_STARTED; emuxki_resched_timer(voice->sc); + mtx_leave(&audio_lock); } void emuxki_voice_halt(struct emuxki_voice *voice) { + mtx_enter(&audio_lock); if (voice->use & EMU_VOICE_USE_PLAY) { emuxki_channel_stop(voice->dataloc.chan[0]); if (voice->stereo) @@ -1991,16 +1964,14 @@ emuxki_voice_halt(struct emuxki_voice *voice) emuxki_recsrc_szreg[voice->dataloc.source], EMU_RECBS_BUFSIZE_NONE); #if 0 - int s; - s = splaudio(); val = emu_rd(sc, INTE, 4); val &= ~emuxki_recsrc_intrmasks[voice->dataloc.source]; emu_wr(sc, INTE, val, 4); - splx(s); #endif } voice->state &= ~EMU_VOICE_STATE_STARTED; emuxki_resched_timer(voice->sc); + mtx_leave(&audio_lock); } /* @@ -2013,6 +1984,7 @@ emuxki_intr(void *arg) u_int32_t ipr, curblk, us = 0; struct emuxki_voice *voice; + mtx_enter(&audio_lock); while ((ipr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_IPR))) { if (ipr & EMU_IPR_INTERVALTIMER) { LIST_FOREACH(voice, &sc->voices, next) { @@ -2045,7 +2017,7 @@ emuxki_intr(void *arg) /* Got interrupt */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_IPR, ipr); } - + mtx_leave(&audio_lock); return (us); } @@ -2380,7 +2352,7 @@ void emuxki_freem(void *addr, void *ptr, int type) { struct emuxki_softc *sc = addr; - int i, s; + int i; struct emuxki_mem *mem; size_t numblocks; u_int32_t *ptb, silentpage; @@ -2391,7 +2363,7 @@ emuxki_freem(void *addr, void *ptr, int type) if (KERNADDR(mem->dmamem) != ptr) continue; - s = splaudio(); + mtx_enter(&audio_lock); if (mem->ptbidx != EMU_RMEM) { numblocks = DMASIZE(mem->dmamem) / EMU_PTESIZE; if (DMASIZE(mem->dmamem) % EMU_PTESIZE) @@ -2401,7 +2373,7 @@ emuxki_freem(void *addr, void *ptr, int type) htole32(silentpage | (mem->ptbidx + i)); } LIST_REMOVE(mem, next); - splx(s); + mtx_leave(&audio_lock); emuxki_mem_delete(mem, type); break; @@ -2498,7 +2470,6 @@ emuxki_trigger_output(void *addr, void *start, void *end, int blksize, return (error); emuxki_voice_commit_parms(voice); emuxki_voice_start(voice, inth, inthparam); - return (0); } @@ -2521,7 +2492,6 @@ emuxki_trigger_input(void *addr, void *start, void *end, int blksize, blksize))) return (error); emuxki_voice_start(voice, inth, inthparam); - return (0); } @@ -2543,12 +2513,11 @@ int emuxki_ac97_read(void *arg, u_int8_t reg, u_int16_t *val) { struct emuxki_softc *sc = arg; - int s; - s = splaudio(); + mtx_enter(&audio_lock); bus_space_write_1(sc->sc_iot, sc->sc_ioh, EMU_AC97ADDR, reg); *val = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EMU_AC97DATA); - splx(s); + mtx_leave(&audio_lock); return (0); } @@ -2557,12 +2526,11 @@ int emuxki_ac97_write(void *arg, u_int8_t reg, u_int16_t val) { struct emuxki_softc *sc = arg; - int s; - s = splaudio(); + mtx_enter(&audio_lock); bus_space_write_1(sc->sc_iot, sc->sc_ioh, EMU_AC97ADDR, reg); bus_space_write_2(sc->sc_iot, sc->sc_ioh, EMU_AC97DATA, val); - splx(s); + mtx_leave(&audio_lock); return (0); } diff --git a/sys/dev/pci/envy.c b/sys/dev/pci/envy.c index 35e7738d3d5..430829deea8 100644 --- a/sys/dev/pci/envy.c +++ b/sys/dev/pci/envy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: envy.c,v 1.54 2013/04/22 15:10:55 deraadt Exp $ */ +/* $OpenBSD: envy.c,v 1.55 2013/05/15 08:29:24 ratchov Exp $ */ /* * Copyright (c) 2007 Alexandre Ratchov <alex@caoua.org> * @@ -1946,10 +1946,13 @@ envy_intr(void *self) int st, err, ctl; int max; + mtx_enter(&audio_lock); st = envy_mt_read_1(sc, ENVY_MT_INTR); mintr = envy_ccs_read(sc, ENVY_CCS_INTSTAT); - if (!(st & ENVY_MT_INTR_ALL) && !(mintr & ENVY_CCS_INT_MIDI0)) + if (!(st & ENVY_MT_INTR_ALL) && !(mintr & ENVY_CCS_INT_MIDI0)) { + mtx_leave(&audio_lock); return 0; + } if (st & ENVY_MT_INTR_ERR) { err = envy_mt_read_1(sc, ENVY_MT_ERR); envy_mt_write_1(sc, ENVY_MT_ERR, err); @@ -2018,6 +2021,7 @@ envy_intr(void *self) #endif } } + mtx_leave(&audio_lock); return 1; } @@ -2027,7 +2031,7 @@ envy_trigger_output(void *self, void *start, void *end, int blksz, { struct envy_softc *sc = (struct envy_softc *)self; size_t bufsz; - int s, st; + int st; bufsz = (char *)end - (char *)start; #ifdef ENVY_DEBUG @@ -2040,7 +2044,7 @@ envy_trigger_output(void *self, void *start, void *end, int blksz, return EINVAL; } #endif - s = splaudio(); + mtx_enter(&audio_lock); envy_mt_write_2(sc, ENVY_MT_PBUFSZ, bufsz / 4 - 1); envy_mt_write_2(sc, ENVY_MT_PBLKSZ(sc), blksz / 4 - 1); @@ -2060,7 +2064,7 @@ envy_trigger_output(void *self, void *start, void *end, int blksz, st = envy_mt_read_1(sc, ENVY_MT_CTL); st |= ENVY_MT_CTL_PSTART; envy_mt_write_1(sc, ENVY_MT_CTL, st); - splx(s); + mtx_leave(&audio_lock); return 0; } @@ -2070,7 +2074,7 @@ envy_trigger_input(void *self, void *start, void *end, int blksz, { struct envy_softc *sc = (struct envy_softc *)self; size_t bufsz; - int s, st; + int st; bufsz = (char *)end - (char *)start; #ifdef ENVY_DEBUG @@ -2083,7 +2087,7 @@ envy_trigger_input(void *self, void *start, void *end, int blksz, return EINVAL; } #endif - s = splaudio(); + mtx_enter(&audio_lock); envy_mt_write_2(sc, ENVY_MT_RBUFSZ, bufsz / 4 - 1); envy_mt_write_2(sc, ENVY_MT_RBLKSZ, blksz / 4 - 1); @@ -2103,7 +2107,7 @@ envy_trigger_input(void *self, void *start, void *end, int blksz, st = envy_mt_read_1(sc, ENVY_MT_CTL); st |= ENVY_MT_CTL_RSTART(sc); envy_mt_write_1(sc, ENVY_MT_CTL, st); - splx(s); + mtx_leave(&audio_lock); return 0; } @@ -2111,20 +2115,20 @@ int envy_halt_output(void *self) { struct envy_softc *sc = (struct envy_softc *)self; - int s, err; + int err; - s = splaudio(); + mtx_enter(&audio_lock); sc->oactive = 0; if (sc->obusy) { - err = tsleep(&sc->obusy, PWAIT, "envyobus", 4 * hz); + err = msleep(&sc->obusy, &audio_lock, PWAIT, "envyobus", 4 * hz); if (err) printf("%s: output DMA halt timeout\n", DEVNAME(sc)); } - splx(s); #ifdef ENVY_DEBUG if (!sc->iactive) envy_pintr(sc); #endif + mtx_leave(&audio_lock); return 0; } @@ -2132,12 +2136,12 @@ int envy_halt_input(void *self) { struct envy_softc *sc = (struct envy_softc *)self; - int s, err; + int err; - s = splaudio(); + mtx_enter(&audio_lock); sc->iactive = 0; if (sc->ibusy) { - err = tsleep(&sc->ibusy, PWAIT, "envyibus", 4 * hz); + err = msleep(&sc->ibusy, &audio_lock, PWAIT, "envyibus", 4 * hz); if (err) printf("%s: input DMA halt timeout\n", DEVNAME(sc)); } @@ -2145,7 +2149,7 @@ envy_halt_input(void *self) if (!sc->oactive) envy_pintr(sc); #endif - splx(s); + mtx_leave(&audio_lock); return 0; } @@ -2360,13 +2364,12 @@ envy_midi_open(void *self, int flags, void *arg) { struct envy_softc *sc = (struct envy_softc *)self; - int s; - s = splaudio(); + mtx_enter(&audio_lock); sc->midi_in = in; sc->midi_out = out; sc->midi_arg = arg; - splx(s); + mtx_leave(&audio_lock); return 0; } @@ -2374,13 +2377,12 @@ void envy_midi_close(void *self) { struct envy_softc *sc = (struct envy_softc *)self; - int s; tsleep(sc, PWAIT, "envymid", hz / 10); - s = splaudio(); + mtx_enter(&audio_lock); sc->midi_in = NULL; sc->midi_out = NULL; - splx(s); + mtx_leave(&audio_lock); } int diff --git a/sys/dev/pci/esa.c b/sys/dev/pci/esa.c index a1f8b53e9b8..ddd85bb3617 100644 --- a/sys/dev/pci/esa.c +++ b/sys/dev/pci/esa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: esa.c,v 1.25 2012/10/11 15:45:00 deraadt Exp $ */ +/* $OpenBSD: esa.c,v 1.26 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: esa.c,v 1.12 2002/03/24 14:17:35 jmcneill Exp $ */ /* @@ -433,6 +433,7 @@ esa_halt_output(void *hdl) if (vc->play.active == 0) return (0); + mtx_enter(&audio_lock); vc->play.active = 0; esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, @@ -456,7 +457,7 @@ esa_halt_output(void *hdl) esa_remove_list(vc, &sc->mixer_list, vc->index); esa_remove_list(vc, &sc->dma_list, vc->index); esa_remove_list(vc, &sc->msrc_list, vc->index); - + mtx_leave(&audio_lock); return (0); } @@ -472,6 +473,7 @@ esa_halt_input(void *hdl) if (vc->rec.active == 0) return (0); + mtx_enter(&audio_lock); vc->rec.active = 0; sc->sc_ntimers--; @@ -494,7 +496,7 @@ esa_halt_input(void *hdl) esa_remove_list(vc, &sc->adc1_list, vc->index + ESA_NUM_VOICES); esa_remove_list(vc, &sc->dma_list, vc->index + ESA_NUM_VOICES); esa_remove_list(vc, &sc->msrc_list, vc->index + ESA_NUM_VOICES); - + mtx_leave(&audio_lock); return (0); } @@ -644,6 +646,7 @@ esa_trigger_output(void *hdl, void *start, void *end, int blksize, #define LO(x) ((x) & 0x0000ffff) #define HI(x) ((x) >> 16) + mtx_enter(&audio_lock); esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + ESA_CDATA_HOST_SRC_ADDRL, LO(bufaddr)); esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data + @@ -725,7 +728,7 @@ esa_trigger_output(void *hdl, void *start, void *end, int blksize, esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_MIXER_TASK_NUMBER, sc->mixer_list.indexmap[vc->index]); - + mtx_leave(&audio_lock); return (0); } @@ -782,7 +785,7 @@ esa_trigger_input(void *hdl, void *start, void *end, int blksize, #define LO(x) ((x) & 0x0000ffff) #define HI(x) ((x) >> 16) - + mtx_enter(&audio_lock); esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + ESA_CDATA_HOST_SRC_ADDRL, LO(bufaddr)); esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data + @@ -856,7 +859,7 @@ esa_trigger_input(void *hdl, void *start, void *end, int blksize, ESA_CDATA_INSTANCE_READY, 1); esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_ADC1_REQUEST, 1); - + mtx_leave(&audio_lock); return (0); } @@ -876,9 +879,12 @@ esa_intr(void *hdl) u_int32_t rec_blksize, rec_bufsize; int i, claimed = 0; + mtx_enter(&audio_lock); status = bus_space_read_1(iot, ioh, ESA_HOST_INT_STATUS); - if (status == 0xff) + if (status == 0xff) { + mtx_leave(&audio_lock); return (0); + } /* ack the interrupt */ bus_space_write_1(iot, ioh, ESA_HOST_INT_STATUS, status); @@ -948,7 +954,7 @@ esa_intr(void *hdl) } claimed = 1; } - + mtx_leave(&audio_lock); return (claimed); } diff --git a/sys/dev/pci/eso.c b/sys/dev/pci/eso.c index 82aaca6f19b..2153cc41676 100644 --- a/sys/dev/pci/eso.c +++ b/sys/dev/pci/eso.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eso.c,v 1.35 2010/09/21 20:11:44 jakemsr Exp $ */ +/* $OpenBSD: eso.c,v 1.36 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: eso.c,v 1.48 2006/12/18 23:13:39 kleink Exp $ */ /* @@ -534,27 +534,19 @@ eso_read_ctlreg(struct eso_softc *sc, uint8_t reg) void eso_write_mixreg(struct eso_softc *sc, uint8_t reg, uint8_t val) { - int s; - /* DPRINTF(("mixreg 0x%02x = 0x%02x\n", reg, val)); */ - s = splaudio(); bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERADDR, reg); bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERDATA, val); - splx(s); } uint8_t eso_read_mixreg(struct eso_softc *sc, uint8_t reg) { - int s; uint8_t val; - s = splaudio(); bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERADDR, reg); val = bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERDATA); - splx(s); - return (val); } @@ -564,12 +556,15 @@ eso_intr(void *hdl) struct eso_softc *sc = hdl; uint8_t irqctl; + mtx_enter(&audio_lock); irqctl = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL); /* If it wasn't ours, that's all she wrote. */ if ((irqctl & (ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ | - ESO_IO_IRQCTL_HVIRQ | ESO_IO_IRQCTL_MPUIRQ)) == 0) + ESO_IO_IRQCTL_HVIRQ | ESO_IO_IRQCTL_MPUIRQ)) == 0) { + mtx_leave(&audio_lock); return (0); + } if (irqctl & ESO_IO_IRQCTL_A1IRQ) { /* Clear interrupt. */ @@ -613,6 +608,7 @@ eso_intr(void *hdl) mpu_intr(sc->sc_mpudev); #endif + mtx_leave(&audio_lock); return (1); } @@ -846,7 +842,7 @@ int eso_halt_output(void *hdl) { struct eso_softc *sc = hdl; - int error, s; + int error; DPRINTF(("%s: halt_output\n", sc->sc_dev.dv_xname)); @@ -861,15 +857,15 @@ eso_halt_output(void *hdl) * state with the least hair. (Besides, that item needs to be * rephrased for trigger_*()-based DMA environments.) */ - s = splaudio(); + mtx_enter(&audio_lock); eso_write_mixreg(sc, ESO_MIXREG_A2C1, ESO_MIXREG_A2C1_FIFOENB | ESO_MIXREG_A2C1_DMAENB); bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, ESO_IO_A2DMAM_DMAENB); sc->sc_pintr = NULL; - error = tsleep(&sc->sc_pintr, PWAIT, "esoho", sc->sc_pdrain); - splx(s); + error = msleep(&sc->sc_pintr, &audio_lock, PWAIT, "esoho", sc->sc_pdrain); + mtx_leave(&audio_lock); /* Shut down DMA completely. */ eso_write_mixreg(sc, ESO_MIXREG_A2C1, 0); @@ -882,12 +878,12 @@ int eso_halt_input(void *hdl) { struct eso_softc *sc = hdl; - int error, s; + int error; DPRINTF(("%s: halt_input\n", sc->sc_dev.dv_xname)); /* Just like eso_halt_output(), but for Audio 1. */ - s = splaudio(); + mtx_enter(&audio_lock); eso_write_ctlreg(sc, ESO_CTLREG_A1C2, ESO_CTLREG_A1C2_READ | ESO_CTLREG_A1C2_ADC | ESO_CTLREG_A1C2_DMAENB); @@ -895,8 +891,8 @@ eso_halt_input(void *hdl) DMA37MD_WRITE | DMA37MD_DEMAND); sc->sc_rintr = NULL; - error = tsleep(&sc->sc_rintr, PWAIT, "esohi", sc->sc_rdrain); - splx(s); + error = msleep(&sc->sc_rintr, &audio_lock, PWAIT, "esohi", sc->sc_rdrain); + mtx_leave(&audio_lock); /* Shut down DMA completely. */ eso_write_ctlreg(sc, ESO_CTLREG_A1C2, @@ -931,7 +927,9 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) struct eso_softc *sc = hdl; uint lgain, rgain; uint8_t tmp; + int rc = 0; + mtx_enter(&audio_lock); switch (cp->dev) { case ESO_DAC_PLAY_VOL: case ESO_MIC_PLAY_VOL: @@ -947,7 +945,7 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) case ESO_CD_REC_VOL: case ESO_AUXB_REC_VOL: if (cp->type != AUDIO_MIXER_VALUE) - return (EINVAL); + goto error; /* * Stereo-capable mixer ports: if we get a single-channel @@ -966,7 +964,7 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); break; default: - return (EINVAL); + goto error; } sc->sc_gain[cp->dev][ESO_LEFT] = lgain; @@ -976,7 +974,7 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) case ESO_MASTER_VOL: if (cp->type != AUDIO_MIXER_VALUE) - return (EINVAL); + goto error; /* Like above, but a precision of 6 bits. */ switch (cp->un.value.num_channels) { @@ -991,7 +989,7 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); break; default: - return (EINVAL); + goto error; } sc->sc_gain[cp->dev][ESO_LEFT] = lgain; @@ -1002,7 +1000,7 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) case ESO_SPATIALIZER: if (cp->type != AUDIO_MIXER_VALUE || cp->un.value.num_channels != 1) - return (EINVAL); + goto error; sc->sc_gain[cp->dev][ESO_LEFT] = sc->sc_gain[cp->dev][ESO_RIGHT] = @@ -1015,7 +1013,7 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) case ESO_MONO_REC_VOL: if (cp->type != AUDIO_MIXER_VALUE || cp->un.value.num_channels != 1) - return (EINVAL); + goto error; sc->sc_gain[cp->dev][ESO_LEFT] = sc->sc_gain[cp->dev][ESO_RIGHT] = @@ -1027,7 +1025,7 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) case ESO_PCSPEAKER_VOL: if (cp->type != AUDIO_MIXER_VALUE || cp->un.value.num_channels != 1) - return (EINVAL); + goto error; sc->sc_gain[cp->dev][ESO_LEFT] = sc->sc_gain[cp->dev][ESO_RIGHT] = @@ -1038,7 +1036,7 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) case ESO_SPATIALIZER_ENABLE: if (cp->type != AUDIO_MIXER_ENUM) - return (EINVAL); + goto error; sc->sc_spatializer = (cp->un.ord != 0); @@ -1053,7 +1051,7 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) case ESO_MASTER_MUTE: if (cp->type != AUDIO_MIXER_ENUM) - return (EINVAL); + goto error; sc->sc_mvmute = (cp->un.ord != 0); @@ -1076,19 +1074,21 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) case ESO_MONOOUT_SOURCE: if (cp->type != AUDIO_MIXER_ENUM) - return (EINVAL); + goto error; - return (eso_set_monooutsrc(sc, cp->un.ord)); + rc = eso_set_monooutsrc(sc, cp->un.ord); + break; case ESO_MONOIN_BYPASS: if (cp->type != AUDIO_MIXER_ENUM) - return (EINVAL); + goto error; - return (eso_set_monoinbypass(sc, cp->un.ord)); + rc = eso_set_monoinbypass(sc, cp->un.ord); + break; case ESO_RECORD_MONITOR: if (cp->type != AUDIO_MIXER_ENUM) - return (EINVAL); + goto error; sc->sc_recmon = (cp->un.ord != 0); @@ -1102,21 +1102,27 @@ eso_set_port(void *hdl, mixer_ctrl_t *cp) case ESO_RECORD_SOURCE: if (cp->type != AUDIO_MIXER_ENUM) - return (EINVAL); + goto error; - return (eso_set_recsrc(sc, cp->un.ord)); + rc = eso_set_recsrc(sc, cp->un.ord); + break; case ESO_MIC_PREAMP: if (cp->type != AUDIO_MIXER_ENUM) - return (EINVAL); + goto error; - return (eso_set_preamp(sc, cp->un.ord)); + rc = eso_set_preamp(sc, cp->un.ord); + break; default: - return (EINVAL); + goto error; } - return (0); + mtx_leave(&audio_lock); + return rc; +error: + mtx_leave(&audio_lock); + return EINVAL; } int @@ -1124,6 +1130,7 @@ eso_get_port(void *hdl, mixer_ctrl_t *cp) { struct eso_softc *sc = hdl; + mtx_enter(&audio_lock); switch (cp->dev) { case ESO_MASTER_VOL: /* Reload from mixer after hardware volume control use. */ @@ -1160,7 +1167,7 @@ eso_get_port(void *hdl, mixer_ctrl_t *cp) sc->sc_gain[cp->dev][ESO_RIGHT]; break; default: - return (EINVAL); + goto error; } break; @@ -1169,7 +1176,7 @@ eso_get_port(void *hdl, mixer_ctrl_t *cp) case ESO_MONO_REC_VOL: case ESO_SPATIALIZER: if (cp->un.value.num_channels != 1) - return (EINVAL); + goto error; cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_gain[cp->dev][ESO_LEFT]; break; @@ -1206,11 +1213,14 @@ eso_get_port(void *hdl, mixer_ctrl_t *cp) break; default: - return (EINVAL); + goto error; } - return (0); - + mtx_leave(&audio_lock); + return 0; +error: + mtx_leave(&audio_lock); + return EINVAL; } int @@ -1771,12 +1781,13 @@ eso_trigger_output(void *hdl, void *start, void *end, int blksize, ESO_IO_A2DMAM_DMAENB | ESO_IO_A2DMAM_AUTO); /* Start DMA. */ + mtx_enter(&audio_lock); a2c1 = eso_read_mixreg(sc, ESO_MIXREG_A2C1); a2c1 &= ~ESO_MIXREG_A2C1_RESV0; /* Paranoia? XXX bit 5 */ a2c1 |= ESO_MIXREG_A2C1_FIFOENB | ESO_MIXREG_A2C1_DMAENB | ESO_MIXREG_A2C1_AUTO; eso_write_mixreg(sc, ESO_MIXREG_A2C1, a2c1); - + mtx_leave(&audio_lock); return (0); } @@ -1872,10 +1883,11 @@ eso_trigger_input(void *hdl, void *start, void *end, int blksize, bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK, 0); /* Start DMA. */ + mtx_enter(&audio_lock); eso_write_ctlreg(sc, ESO_CTLREG_A1C2, ESO_CTLREG_A1C2_DMAENB | ESO_CTLREG_A1C2_READ | ESO_CTLREG_A1C2_AUTO | ESO_CTLREG_A1C2_ADC); - + mtx_leave(&audio_lock); return (0); } diff --git a/sys/dev/pci/fms.c b/sys/dev/pci/fms.c index ec021d39fca..20a538782b8 100644 --- a/sys/dev/pci/fms.c +++ b/sys/dev/pci/fms.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fms.c,v 1.22 2010/07/15 03:43:11 jakemsr Exp $ */ +/* $OpenBSD: fms.c,v 1.23 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: fms.c,v 1.5.4.1 2000/06/30 16:27:50 simonb Exp $ */ /*- @@ -391,6 +391,7 @@ fms_intr(arg) struct fms_softc *sc = arg; u_int16_t istat; + mtx_enter(&audio_lock); istat = bus_space_read_2(sc->sc_iot, sc->sc_ioh, FM_INTSTATUS); if (istat & FM_INTSTATUS_PLAY) { @@ -430,7 +431,7 @@ fms_intr(arg) bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_INTSTATUS, istat & (FM_INTSTATUS_PLAY | FM_INTSTATUS_REC)); - + mtx_leave(&audio_lock); return 1; } @@ -660,12 +661,13 @@ fms_halt_output(addr) { struct fms_softc *sc = addr; u_int16_t k1; - + + mtx_enter(&audio_lock); k1 = bus_space_read_2(sc->sc_iot, sc->sc_ioh, FM_PLAY_CTL); bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_PLAY_CTL, (k1 & ~(FM_PLAY_STOPNOW | FM_PLAY_START)) | FM_PLAY_BUF1_LAST | FM_PLAY_BUF2_LAST); - + mtx_leave(&audio_lock); return 0; } @@ -675,12 +677,13 @@ fms_halt_input(addr) { struct fms_softc *sc = addr; u_int16_t k1; - + + mtx_enter(&audio_lock); k1 = bus_space_read_2(sc->sc_iot, sc->sc_ioh, FM_REC_CTL); bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_REC_CTL, (k1 & ~(FM_REC_STOPNOW | FM_REC_START)) | FM_REC_BUF1_LAST | FM_REC_BUF2_LAST); - + mtx_leave(&audio_lock); return 0; } @@ -866,6 +869,7 @@ fms_trigger_output(addr, start, end, blksize, intr, arg, param) sc->sc_play_blksize = blksize; sc->sc_play_nextblk = sc->sc_play_start + sc->sc_play_blksize; sc->sc_play_flip = 0; + mtx_enter(&audio_lock); bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_PLAY_DMALEN, blksize - 1); bus_space_write_4(sc->sc_iot, sc->sc_ioh, FM_PLAY_DMABUF1, sc->sc_play_start); @@ -873,6 +877,7 @@ fms_trigger_output(addr, start, end, blksize, intr, arg, param) sc->sc_play_nextblk); bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_PLAY_CTL, FM_PLAY_START | FM_PLAY_STOPNOW | sc->sc_play_reg); + mtx_leave(&audio_lock); return 0; } @@ -904,6 +909,7 @@ fms_trigger_input(addr, start, end, blksize, intr, arg, param) sc->sc_rec_blksize = blksize; sc->sc_rec_nextblk = sc->sc_rec_start + sc->sc_rec_blksize; sc->sc_rec_flip = 0; + mtx_enter(&audio_lock); bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_REC_DMALEN, blksize - 1); bus_space_write_4(sc->sc_iot, sc->sc_ioh, FM_REC_DMABUF1, sc->sc_rec_start); @@ -911,6 +917,7 @@ fms_trigger_input(addr, start, end, blksize, intr, arg, param) sc->sc_rec_nextblk); bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_REC_CTL, FM_REC_START | FM_REC_STOPNOW | sc->sc_rec_reg); + mtx_leave(&audio_lock); return 0; } diff --git a/sys/dev/pci/maestro.c b/sys/dev/pci/maestro.c index 36cd75ccd8e..1d584d7c511 100644 --- a/sys/dev/pci/maestro.c +++ b/sys/dev/pci/maestro.c @@ -1,4 +1,4 @@ -/* $OpenBSD: maestro.c,v 1.33 2012/10/21 16:50:58 deraadt Exp $ */ +/* $OpenBSD: maestro.c,v 1.34 2013/05/15 08:29:24 ratchov Exp $ */ /* $FreeBSD: /c/ncvs/src/sys/dev/sound/pci/maestro.c,v 1.3 2000/11/21 12:22:11 julian Exp $ */ /* * FreeBSD's ESS Agogo/Maestro driver @@ -920,10 +920,15 @@ maestro_set_port(self, cp) mixer_ctrl_t *cp; { struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if; - - if (c) - return (c->vtbl->mixer_set_port(c, cp)); - else + int rc; + + if (c) { + /* interrupts use the mixer */ + mtx_enter(&audio_lock); + rc = c->vtbl->mixer_set_port(c, cp); + mtx_leave(&audio_lock); + return rc; + } else return (ENXIO); } @@ -933,10 +938,15 @@ maestro_get_port(self, cp) mixer_ctrl_t *cp; { struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if; - - if (c) - return (c->vtbl->mixer_get_port(c, cp)); - else + int rc; + + if (c) { + /* interrupts use the mixer */ + mtx_enter(&audio_lock); + rc = c->vtbl->mixer_get_port(c, cp); + mtx_leave(&audio_lock); + return rc; + } else return (ENXIO); } @@ -946,10 +956,15 @@ maestro_query_devinfo(self, cp) mixer_devinfo_t *cp; { struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if; - - if (c) - return (c->vtbl->query_devinfo(c, cp)); - else + int rc; + + if (c) { + /* interrupts use the mixer */ + mtx_enter(&audio_lock); + rc = c->vtbl->query_devinfo(c, cp); + mtx_leave(&audio_lock); + return rc; + } else return (ENXIO); } @@ -1160,9 +1175,12 @@ maestro_halt_input(hdl) void *hdl; { struct maestro_softc *sc = (struct maestro_softc *)hdl; + + mtx_enter(&audio_lock); maestro_channel_stop(&sc->record); sc->record.mode &= ~MAESTRO_RUNNING; maestro_update_timer(sc); + mtx_leave(&audio_lock); return 0; } @@ -1172,9 +1190,11 @@ maestro_halt_output(hdl) { struct maestro_softc *sc = (struct maestro_softc *)hdl; + mtx_enter(&audio_lock); maestro_channel_stop(&sc->play); sc->play.mode &= ~MAESTRO_RUNNING; maestro_update_timer(sc); + mtx_leave(&audio_lock); return 0; } @@ -1189,6 +1209,7 @@ maestro_trigger_input(hdl, start, end, blksize, intr, arg, param) { struct maestro_softc *sc = (struct maestro_softc *)hdl; + mtx_enter(&audio_lock); sc->record.mode |= MAESTRO_RUNNING; sc->record.blocksize = blksize; @@ -1196,6 +1217,7 @@ maestro_trigger_input(hdl, start, end, blksize, intr, arg, param) sc->record.threshold = sc->record.start; maestro_update_timer(sc); + mtx_leave(&audio_lock); return 0; } @@ -1289,9 +1311,10 @@ maestro_trigger_output(hdl, start, end, blksize, intr, arg, param) struct audio_params *param; { struct maestro_softc *sc = (struct maestro_softc *)hdl; - u_int offset = ((caddr_t)start - sc->dmabase) >> 1; u_int size = ((char *)end - (char *)start) >> 1; + + mtx_enter(&audio_lock); sc->play.mode |= MAESTRO_RUNNING; sc->play.wpwa = APU_USE_SYSMEM | (offset >> 8); DPRINTF(("maestro_trigger_output: start=%x, end=%x, blksize=%x ", @@ -1314,7 +1337,7 @@ maestro_trigger_output(hdl, start, end, blksize, intr, arg, param) sc->play.threshold = sc->play.start; maestro_update_timer(sc); - + mtx_leave(&audio_lock); return 0; } @@ -1588,6 +1611,8 @@ maestro_intr(arg) if (status == 0) return 0; /* Not for us? */ + mtx_enter(&audio_lock); + /* Acknowledge all. */ bus_space_write_2(sc->iot, sc->ioh, PORT_INT_STAT, 1); bus_space_write_1(sc->iot, sc->ioh, PORT_HOSTINT_STAT, status); @@ -1640,6 +1665,7 @@ maestro_intr(arg) if (sc->record.mode & MAESTRO_RUNNING) maestro_channel_advance_dma(&sc->record); + mtx_leave(&audio_lock); return 1; } diff --git a/sys/dev/pci/neo.c b/sys/dev/pci/neo.c index 5b4c2320510..d6d3c810c71 100644 --- a/sys/dev/pci/neo.c +++ b/sys/dev/pci/neo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: neo.c,v 1.26 2010/09/07 16:21:45 deraadt Exp $ */ +/* $OpenBSD: neo.c,v 1.27 2013/05/15 08:29:24 ratchov Exp $ */ /* * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> @@ -441,6 +441,7 @@ neo_intr(void *p) int status, x; int rv = 0; + mtx_enter(&audio_lock); status = nm_rd(sc, NM_INT_REG, sc->irsz); if (status & sc->playint) { @@ -492,7 +493,7 @@ neo_intr(void *p) printf("%s: unknown int\n", sc->dev.dv_xname); rv = 1; } - + mtx_leave(&audio_lock); return (rv); } @@ -946,6 +947,7 @@ neo_trigger_output(addr, start, end, blksize, intr, arg, param) struct neo_softc *sc = addr; int ssz; + mtx_enter(&audio_lock); sc->pintr = intr; sc->parg = arg; @@ -956,7 +958,6 @@ neo_trigger_output(addr, start, end, blksize, intr, arg, param) sc->pbufsize = ((char *)end - (char *)start); sc->pblksize = blksize; sc->pwmark = blksize; - nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4); nm_wr(sc, NM_PBUFFER_END, sc->pbuf + sc->pbufsize - ssz, 4); nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4); @@ -964,7 +965,7 @@ neo_trigger_output(addr, start, end, blksize, intr, arg, param) nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN | NM_PLAYBACK_ENABLE_FLAG, 1); nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2); - + mtx_leave(&audio_lock); return (0); } @@ -982,6 +983,7 @@ neo_trigger_input(addr, start, end, blksize, intr, arg, param) struct neo_softc *sc = addr; int ssz; + mtx_enter(&audio_lock); sc->rintr = intr; sc->rarg = arg; @@ -992,14 +994,13 @@ neo_trigger_input(addr, start, end, blksize, intr, arg, param) sc->rbufsize = ((char *)end - (char *)start); sc->rblksize = blksize; sc->rwmark = blksize; - nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4); nm_wr(sc, NM_RBUFFER_END, sc->rbuf + sc->rbufsize, 4); nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4); nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rwmark, 4); nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN | NM_RECORD_ENABLE_FLAG, 1); - + mtx_leave(&audio_lock); return (0); } @@ -1009,11 +1010,12 @@ neo_halt_output(addr) { struct neo_softc *sc = (struct neo_softc *)addr; + mtx_enter(&audio_lock); nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1); nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2); sc->pintr = 0; - + mtx_leave(&audio_lock); return (0); } @@ -1023,10 +1025,11 @@ neo_halt_input(addr) { struct neo_softc *sc = (struct neo_softc *)addr; + mtx_enter(&audio_lock); nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); sc->rintr = 0; - + mtx_leave(&audio_lock); return (0); } diff --git a/sys/dev/pci/sv.c b/sys/dev/pci/sv.c index 6d608fadf46..27b2a4413f3 100644 --- a/sys/dev/pci/sv.c +++ b/sys/dev/pci/sv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sv.c,v 1.27 2010/07/15 03:43:11 jakemsr Exp $ */ +/* $OpenBSD: sv.c,v 1.28 2013/05/15 08:29:24 ratchov Exp $ */ /* * Copyright (c) 1998 Constantine Paul Sapuntzakis @@ -431,10 +431,13 @@ sv_intr(p) struct sv_softc *sc = p; u_int8_t intr; + mtx_enter(&audio_lock); intr = sv_read(sc, SV_CODEC_STATUS); - if (!(intr & (SV_INTSTATUS_DMAA | SV_INTSTATUS_DMAC))) + if (!(intr & (SV_INTSTATUS_DMAA | SV_INTSTATUS_DMAC))) { + mtx_leave(&audio_lock); return (0); + } if (intr & SV_INTSTATUS_DMAA) { if (sc->sc_pintr) @@ -445,7 +448,7 @@ sv_intr(p) if (sc->sc_rintr) sc->sc_rintr(sc->sc_rarg); } - + mtx_leave(&audio_lock); return (1); } @@ -849,7 +852,7 @@ sv_dma_init_output(addr, buf, cc) struct sv_dma *p; int dma_count; - DPRINTF(("eap: dma start loop output buf=%p cc=%d\n", buf, cc)); + DPRINTF(("sv: dma start loop output buf=%p cc=%d\n", buf, cc)); for (p = sc->sc_dmas; p && KERNADDR(p) != buf; p = p->next) ; if (!p) { @@ -883,7 +886,6 @@ sv_dma_output(addr, p, cc, intr, arg) DPRINTFN(1, ("sv_dma_output: sc=%p buf=%p cc=%d intr=%p(%p)\n", addr, p, cc, intr, arg)); - sc->sc_pintr = intr; sc->sc_parg = arg; if (!(sc->sc_enable & SV_PLAY_ENABLE)) { @@ -936,12 +938,13 @@ sv_halt_out_dma(addr) struct sv_softc *sc = addr; u_int8_t mode; - DPRINTF(("eap: sv_halt_out_dma\n")); + DPRINTF(("sv: sv_halt_out_dma\n")); + mtx_enter(&audio_lock); mode = sv_read_indirect(sc, SV_PLAY_RECORD_ENABLE); mode &= ~SV_PLAY_ENABLE; sc->sc_enable &= ~SV_PLAY_ENABLE; sv_write_indirect(sc, SV_PLAY_RECORD_ENABLE, mode); - + mtx_leave(&audio_lock); return (0); } @@ -952,12 +955,13 @@ sv_halt_in_dma(addr) struct sv_softc *sc = addr; u_int8_t mode; - DPRINTF(("eap: sv_halt_in_dma\n")); + DPRINTF(("sv: sv_halt_in_dma\n")); + mtx_enter(&audio_lock); mode = sv_read_indirect(sc, SV_PLAY_RECORD_ENABLE); mode &= ~SV_RECORD_ENABLE; sc->sc_enable &= ~SV_RECORD_ENABLE; sv_write_indirect(sc, SV_PLAY_RECORD_ENABLE, mode); - + mtx_leave(&audio_lock); return (0); } diff --git a/sys/dev/pci/yds.c b/sys/dev/pci/yds.c index 1311c3c6ec5..a099677fc35 100644 --- a/sys/dev/pci/yds.c +++ b/sys/dev/pci/yds.c @@ -1,4 +1,4 @@ -/* $OpenBSD: yds.c,v 1.41 2012/03/03 20:21:39 miod Exp $ */ +/* $OpenBSD: yds.c,v 1.42 2013/05/15 08:29:24 ratchov Exp $ */ /* $NetBSD: yds.c,v 1.5 2001/05/21 23:55:04 minoura Exp $ */ /* @@ -908,6 +908,7 @@ yds_intr(void *p) struct yds_softc *sc = p; u_int status; + mtx_enter(&audio_lock); status = YREAD4(sc, YDS_STATUS); DPRINTFN(1, ("yds_intr: status=%08x\n", status)); if ((status & (YDS_STAT_INT|YDS_STAT_TINT)) == 0) { @@ -915,6 +916,7 @@ yds_intr(void *p) if (sc->sc_mpu) return mpu_intr(sc->sc_mpu); #endif + mtx_leave(&audio_lock); return 0; } @@ -1013,7 +1015,7 @@ yds_intr(void *p) } } } - + mtx_leave(&audio_lock); return 1; } @@ -1317,11 +1319,11 @@ yds_trigger_output(void *addr, void *start, void *end, int blksize, int i; int p44, channels; + mtx_enter(&audio_lock); #ifdef DIAGNOSTIC if (sc->sc_play.intr) panic("yds_trigger_output: already running"); #endif - sc->sc_play.intr = intr; sc->sc_play.intr_arg = arg; sc->sc_play.offset = 0; @@ -1333,6 +1335,7 @@ yds_trigger_output(void *addr, void *start, void *end, int blksize, p = yds_find_dma(sc, start); if (!p) { printf("yds_trigger_output: bad addr %p\n", start); + mtx_leave(&audio_lock); return (EINVAL); } sc->sc_play.dma = p; @@ -1434,7 +1437,7 @@ yds_trigger_output(void *addr, void *start, void *end, int blksize, /* HERE WE GO!! */ YWRITE4(sc, YDS_MODE, YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2); - + mtx_leave(&audio_lock); return 0; } #undef P44 @@ -1450,6 +1453,7 @@ yds_trigger_input(void *addr, void *start, void *end, int blksize, bus_addr_t s; size_t l; + mtx_enter(&audio_lock); #ifdef DIAGNOSTIC if (sc->sc_rec.intr) panic("yds_trigger_input: already running"); @@ -1468,6 +1472,7 @@ yds_trigger_input(void *addr, void *start, void *end, int blksize, p = yds_find_dma(sc, start); if (!p) { printf("yds_trigger_input: bad addr %p\n", start); + mtx_leave(&audio_lock); return (EINVAL); } sc->sc_rec.dma = p; @@ -1522,7 +1527,7 @@ yds_trigger_input(void *addr, void *start, void *end, int blksize, /* HERE WE GO!! */ YWRITE4(sc, YDS_MODE, YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2); - + mtx_leave(&audio_lock); return 0; } @@ -1552,6 +1557,7 @@ yds_halt_output(void *addr) struct yds_softc *sc = addr; DPRINTF(("yds: yds_halt_output\n")); + mtx_enter(&audio_lock); if (sc->sc_play.intr) { sc->sc_play.intr = 0; /* Sync play slot control data */ @@ -1569,7 +1575,7 @@ yds_halt_output(void *addr) bus_dmamap_sync(sc->sc_dmatag, sc->sc_play.dma->map, 0, sc->sc_play.length, BUS_DMASYNC_POSTWRITE); } - + mtx_leave(&audio_lock); return 0; } @@ -1579,6 +1585,7 @@ yds_halt_input(void *addr) struct yds_softc *sc = addr; DPRINTF(("yds: yds_halt_input\n")); + mtx_enter(&audio_lock); if (sc->sc_rec.intr) { /* Stop the rec slot operation */ YWRITE4(sc, YDS_MAPOF_REC, 0); @@ -1594,7 +1601,7 @@ yds_halt_input(void *addr) 0, sc->sc_rec.length, BUS_DMASYNC_POSTREAD); } sc->sc_rec.intr = NULL; - + mtx_leave(&audio_lock); return 0; } diff --git a/sys/dev/sbus/cs4231.c b/sys/dev/sbus/cs4231.c index cac922a1e11..d569da895cc 100644 --- a/sys/dev/sbus/cs4231.c +++ b/sys/dev/sbus/cs4231.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cs4231.c,v 1.31 2011/04/05 19:54:35 jasper Exp $ */ +/* $OpenBSD: cs4231.c,v 1.32 2013/05/15 08:29:24 ratchov Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -659,7 +659,7 @@ int cs4231_commit_settings(void *vsc) { struct cs4231_softc *sc = (struct cs4231_softc *)vsc; - int s, tries; + int tries; u_int8_t r, fs; if (sc->sc_need_commit == 0) @@ -669,7 +669,8 @@ cs4231_commit_settings(void *vsc) if (sc->sc_channels == 2) fs |= FMT_STEREO; - s = splaudio(); + /* XXX: this is called before DMA is setup, useful ? */ + mtx_enter(&audio_lock); r = cs4231_read(sc, SP_INTERFACE_CONFIG) | AUTO_CAL_ENABLE; CS_WRITE(sc, AD1848_IADDR, MODE_CHANGE_ENABLE); @@ -712,7 +713,7 @@ cs4231_commit_settings(void *vsc) printf("%s: timeout waiting for autocalibration\n", sc->sc_dev.dv_xname); - splx(s); + mtx_leave(&audio_lock); sc->sc_need_commit = 0; return (0); @@ -724,12 +725,14 @@ cs4231_halt_output(void *vsc) struct cs4231_softc *sc = (struct cs4231_softc *)vsc; /* XXX Kills some capture bits */ + mtx_enter(&audio_lock); APC_WRITE(sc, APC_CSR, APC_READ(sc, APC_CSR) & ~(APC_CSR_EI | APC_CSR_GIE | APC_CSR_PIE | APC_CSR_EIE | APC_CSR_PDMA_GO | APC_CSR_PMIE)); cs4231_write(sc, SP_INTERFACE_CONFIG, cs4231_read(sc, SP_INTERFACE_CONFIG) & (~PLAYBACK_ENABLE)); sc->sc_playback.cs_locked = 0; + mtx_leave(&audio_lock); return (0); } @@ -739,10 +742,12 @@ cs4231_halt_input(void *vsc) struct cs4231_softc *sc = (struct cs4231_softc *)vsc; /* XXX Kills some playback bits */ + mtx_enter(&audio_lock); APC_WRITE(sc, APC_CSR, APC_CSR_CAPTURE_PAUSE); cs4231_write(sc, SP_INTERFACE_CONFIG, cs4231_read(sc, SP_INTERFACE_CONFIG) & (~CAPTURE_ENABLE)); sc->sc_capture.cs_locked = 0; + mtx_leave(&audio_lock); return (0); } @@ -1326,6 +1331,7 @@ cs4231_intr(void *vsc) struct cs_dma *p; int r = 0; + mtx_enter(&audio_lock); csr = APC_READ(sc, APC_CSR); APC_WRITE(sc, APC_CSR, csr); @@ -1418,6 +1424,7 @@ cs4231_intr(void *vsc) r = 1; } + mtx_leave(&audio_lock); return (r); } @@ -1530,6 +1537,7 @@ cs4231_trigger_output(void *vsc, void *start, void *end, int blksize, chan->cs_cnt = n; + mtx_enter(&audio_lock); csr = APC_READ(sc, APC_CSR); APC_WRITE(sc, APC_PNVA, (u_long)p->dmamap->dm_segs[0].ds_addr); @@ -1546,6 +1554,7 @@ cs4231_trigger_output(void *vsc, void *start, void *end, int blksize, cs4231_write(sc, SP_INTERFACE_CONFIG, cs4231_read(sc, SP_INTERFACE_CONFIG) | PLAYBACK_ENABLE); } + mtx_leave(&audio_lock); return (0); } @@ -1590,6 +1599,7 @@ cs4231_trigger_input(void *vsc, void *start, void *end, int blksize, n = chan->cs_blksz; chan->cs_cnt = n; + mtx_enter(&audio_lock); APC_WRITE(sc, APC_CNVA, p->dmamap->dm_segs[0].ds_addr); APC_WRITE(sc, APC_CNC, (u_long)n); @@ -1624,5 +1634,6 @@ cs4231_trigger_input(void *vsc, void *start, void *end, int blksize, APC_WRITE(sc, APC_CNC, togo); } + mtx_leave(&audio_lock); return (0); } diff --git a/sys/dev/tc/bba.c b/sys/dev/tc/bba.c index 5ab8476457a..2b234462cd9 100644 --- a/sys/dev/tc/bba.c +++ b/sys/dev/tc/bba.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bba.c,v 1.2 2011/09/05 16:54:41 miod Exp $ */ +/* $OpenBSD: bba.c,v 1.3 2013/05/15 08:29:26 ratchov Exp $ */ /* $NetBSD: bba.c,v 1.38 2011/06/04 01:27:57 tsutsui Exp $ */ /* * Copyright (c) 2011 Miodrag Vallat. @@ -377,6 +377,7 @@ bba_halt_output(void *v) struct bba_dma_state *d; uint32_t ssr; + mtx_enter(&audio_lock); d = &sc->sc_tx_dma_state; /* disable any DMA */ ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR); @@ -384,6 +385,7 @@ bba_halt_output(void *v) bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr); bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_DMAPTR, 0); bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_NEXTPTR, 0); + mtx_leave(&audio_lock); if (d->active) { bus_dmamap_sync(sc->sc_dmat, d->dmam, 0, d->size, @@ -403,6 +405,7 @@ bba_halt_input(void *v) struct bba_dma_state *d; uint32_t ssr; + mtx_enter(&audio_lock); d = &sc->sc_rx_dma_state; /* disable any DMA */ ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR); @@ -410,6 +413,7 @@ bba_halt_input(void *v) bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr); bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_DMAPTR, 0); bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_NEXTPTR, 0); + mtx_leave(&audio_lock); if (d->active) { bus_dmamap_sync(sc->sc_dmat, d->dmam, 0, d->size, @@ -481,11 +485,12 @@ bba_trigger_output(void *v, void *start, void *end, int blksize, IOASIC_DMA_ADDR(nphys)); /* kick off DMA */ + mtx_enter(&audio_lock); ssr |= IOASIC_CSR_DMAEN_ISDN_T; bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr); d->active = 1; - + mtx_leave(&audio_lock); return 0; bad: @@ -548,11 +553,12 @@ bba_trigger_input(void *v, void *start, void *end, int blksize, IOASIC_DMA_ADDR(nphys)); /* kick off DMA */ + mtx_enter(&audio_lock); ssr |= IOASIC_CSR_DMAEN_ISDN_R; bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr); d->active = 1; - + mtx_leave(&audio_lock); return 0; bad: @@ -569,9 +575,9 @@ bba_intr(void *v) struct bba_softc *sc = v; struct bba_dma_state *d; tc_addr_t nphys; - int s, mask; + int mask; - s = splaudio(); + mtx_enter(&audio_lock); mask = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_INTR); @@ -594,7 +600,7 @@ bba_intr(void *v) (*d->intr)(d->intr_arg); } - splx(s); + mtx_leave(&audio_lock); return 0; } diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index 29777f31b62..7ba0db0f611 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uaudio.c,v 1.99 2013/04/15 09:23:01 mglocker Exp $ */ +/* $OpenBSD: uaudio.c,v 1.100 2013/05/15 08:29:26 ratchov Exp $ */ /* $NetBSD: uaudio.c,v 1.90 2004/10/29 17:12:53 kent Exp $ */ /* @@ -2897,7 +2897,6 @@ uaudio_chan_ptransfer(struct chan *ch) struct chanbuf *cb; u_char *pos; int i, n, size, residue, total; - int s; if (ch->sc->sc_dying) return; @@ -2945,9 +2944,9 @@ uaudio_chan_ptransfer(struct chan *ch) if (ch->transferred >= ch->blksize) { DPRINTFN(5,("uaudio_chan_ptransfer: call %p(%p)\n", ch->intr, ch->arg)); - s = splaudio(); + mtx_enter(&audio_lock); ch->intr(ch->arg); - splx(s); + mtx_leave(&audio_lock); ch->transferred -= ch->blksize; } } @@ -3136,7 +3135,7 @@ uaudio_chan_rintr(struct usbd_xfer *xfer, void *priv, struct chan *ch = cb->chan; u_int16_t pos; u_int32_t count; - int s, i, n, frsize; + int i, n, frsize; /* Return if we are aborting. */ if (status == USBD_CANCELLED) @@ -3176,9 +3175,9 @@ uaudio_chan_rintr(struct usbd_xfer *xfer, void *priv, if (ch->transferred >= ch->blksize) { DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n", ch->intr, ch->arg)); - s = splaudio(); + mtx_enter(&audio_lock); ch->intr(ch->arg); - splx(s); + mtx_leave(&audio_lock); ch->transferred -= ch->blksize; } if (count < n) diff --git a/sys/dev/usb/umidi.c b/sys/dev/usb/umidi.c index 7db162c750a..8bc85cc916a 100644 --- a/sys/dev/usb/umidi.c +++ b/sys/dev/usb/umidi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: umidi.c,v 1.36 2013/04/15 09:23:02 mglocker Exp $ */ +/* $OpenBSD: umidi.c,v 1.37 2013/05/15 08:29:26 ratchov Exp $ */ /* $NetBSD: umidi.c,v 1.16 2002/07/11 21:14:32 augustss Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -50,6 +50,7 @@ #include <dev/usb/umidivar.h> #include <dev/usb/umidi_quirks.h> +#include <dev/audio_if.h> #include <dev/midi_if.h> #ifdef UMIDI_DEBUG @@ -791,7 +792,7 @@ free_all_jacks(struct umidi_softc *sc) { int s; - s = splaudio(); + s = splusb(); if (sc->sc_out_jacks) { free(sc->sc_jacks, M_USBDEV); sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL; @@ -1228,8 +1229,10 @@ in_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) if (cn < ep->num_jacks && (jack = ep->jacks[cn]) && jack->binded && jack->opened && jack->u.in.intr) { evlen = packet_length[GET_CIN(buf[0])]; + mtx_enter(&audio_lock); for (i=0; i<evlen; i++) (*jack->u.in.intr)(jack->arg, buf[i+1]); + mtx_leave(&audio_lock); } buf += UMIDI_PACKET_SIZE; remain -= UMIDI_PACKET_SIZE; @@ -1261,8 +1264,10 @@ out_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) SIMPLEQ_REMOVE_HEAD(&ep->intrq, intrq_entry); ep->pending--; j->intr = 0; + mtx_enter(&audio_lock); if (j->opened && j->u.out.intr) (*j->u.out.intr)(j->arg); + mtx_leave(&audio_lock); } } |