summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2013-05-15 08:29:27 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2013-05-15 08:29:27 +0000
commite4d6a0a80573196dfd09b1201d79c9b77536c745 (patch)
treee7cc60514c99640b6483947ee3bfb09d9b2d58bb /sys/dev
parent2af0efdd18ad07b832c93f5c98d654ace8e0524e (diff)
Introduce a global interrupt-aware mutex protecting data
structures (including sound-card registers) from concurent access by syscall and interrupt code-paths. Since critical sections remain the same, calls to splraise/spllower can be safely replaced by calls to mtx_enter/mtx_leave with two exceptions: (1) mutexes are not reentrant (the inner splraise is thus removed), and (2) we're not allowed to sleep with a mutex (either msleep is used or the mutex is released before sleeping). ok and help from kettenis, a lot of work from armani
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/audio.c206
-rw-r--r--sys/dev/audio_if.h6
-rw-r--r--sys/dev/bluetooth/btsco.c18
-rw-r--r--sys/dev/ic/am7930.c7
-rw-r--r--sys/dev/ic/arcofi.c34
-rw-r--r--sys/dev/isa/ad1848.c39
-rw-r--r--sys/dev/isa/ess.c60
-rw-r--r--sys/dev/isa/gus.c61
-rw-r--r--sys/dev/isa/ics2101.c7
-rw-r--r--sys/dev/isa/mpu401.c23
-rw-r--r--sys/dev/isa/sbdsp.c42
-rw-r--r--sys/dev/isa/wss.c12
-rw-r--r--sys/dev/midi.c124
-rw-r--r--sys/dev/pci/auacer.c10
-rw-r--r--sys/dev/pci/auglx.c15
-rw-r--r--sys/dev/pci/auich.c19
-rw-r--r--sys/dev/pci/auixp.c18
-rw-r--r--sys/dev/pci/autri.c23
-rw-r--r--sys/dev/pci/auvia.c13
-rw-r--r--sys/dev/pci/azalia.c37
-rw-r--r--sys/dev/pci/cmpci.c26
-rw-r--r--sys/dev/pci/cs4280.c15
-rw-r--r--sys/dev/pci/cs4281.c12
-rw-r--r--sys/dev/pci/eap.c31
-rw-r--r--sys/dev/pci/emuxki.c90
-rw-r--r--sys/dev/pci/envy.c46
-rw-r--r--sys/dev/pci/esa.c22
-rw-r--r--sys/dev/pci/eso.c102
-rw-r--r--sys/dev/pci/fms.c19
-rw-r--r--sys/dev/pci/maestro.c56
-rw-r--r--sys/dev/pci/neo.c19
-rw-r--r--sys/dev/pci/sv.c22
-rw-r--r--sys/dev/pci/yds.c21
-rw-r--r--sys/dev/sbus/cs4231.c19
-rw-r--r--sys/dev/tc/bba.c18
-rw-r--r--sys/dev/usb/uaudio.c13
-rw-r--r--sys/dev/usb/umidi.c9
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);
}
}