summaryrefslogtreecommitdiff
path: root/sys/arch
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/arch
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/arch')
-rw-r--r--sys/arch/hppa/gsc/harmony.c14
-rw-r--r--sys/arch/macppc/dev/awacs.c24
-rw-r--r--sys/arch/macppc/dev/i2s.c18
-rw-r--r--sys/arch/sgi/dev/mavb.c15
-rw-r--r--sys/arch/sparc/dev/audioamd.c12
-rw-r--r--sys/arch/sparc/dev/cs4231.c21
-rw-r--r--sys/arch/sparc64/dev/ce4231.c15
-rw-r--r--sys/arch/vax/vsa/vsaudio.c18
-rw-r--r--sys/arch/zaurus/dev/zaurus_audio.c10
9 files changed, 109 insertions, 38 deletions
diff --git a/sys/arch/hppa/gsc/harmony.c b/sys/arch/hppa/gsc/harmony.c
index a9b6bf36fd7..30991f0a9ad 100644
--- a/sys/arch/hppa/gsc/harmony.c
+++ b/sys/arch/hppa/gsc/harmony.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: harmony.c,v 1.27 2010/07/15 03:43:11 jakemsr Exp $ */
+/* $OpenBSD: harmony.c,v 1.28 2013/05/15 08:29:23 ratchov Exp $ */
/*
* Copyright (c) 2003 Jason L. Wright (jason@thought.net)
@@ -308,6 +308,7 @@ harmony_intr(vsc)
u_int32_t dstatus;
int r = 0;
+ mtx_enter(&audio_lock);
ADD_CLKALLICA(sc);
harmony_intr_disable(sc);
@@ -360,7 +361,7 @@ harmony_intr(vsc)
sc->sc_ov = 0;
harmony_intr_enable(sc);
-
+ mtx_leave(&audio_lock);
return (r);
}
@@ -394,6 +395,7 @@ harmony_close(void *vsc)
{
struct harmony_softc *sc = vsc;
+ /* XXX: not useful, halt_*() already called */
harmony_halt_input(sc);
harmony_halt_output(sc);
harmony_intr_disable(sc);
@@ -655,6 +657,7 @@ harmony_halt_output(void *vsc)
{
struct harmony_softc *sc = vsc;
+ /* XXX: disable interrupts */
sc->sc_playing = 0;
return (0);
}
@@ -664,6 +667,7 @@ harmony_halt_input(void *vsc)
{
struct harmony_softc *sc = vsc;
+ /* XXX: disable interrupts */
sc->sc_capturing = 0;
return (0);
}
@@ -1071,6 +1075,7 @@ harmony_trigger_output(void *vsc, void *start, void *end, int blksize,
nextaddr - d->d_map->dm_segs[0].ds_addr,
c->c_blksz, BUS_DMASYNC_PREWRITE);
+ mtx_enter(&audio_lock);
WRITE_REG(sc, HARMONY_PNXTADD, nextaddr);
c->c_theaddr = nextaddr;
SYNC_REG(sc, HARMONY_PNXTADD, BUS_SPACE_BARRIER_WRITE);
@@ -1078,7 +1083,7 @@ harmony_trigger_output(void *vsc, void *start, void *end, int blksize,
harmony_start_cp(sc);
harmony_intr_enable(sc);
-
+ mtx_leave(&audio_lock);
return (0);
}
@@ -1143,10 +1148,11 @@ harmony_trigger_input(void *vsc, void *start, void *end, int blksize,
c->c_segsz = (caddr_t)end - (caddr_t)start;
c->c_cnt = 0;
c->c_lastaddr = d->d_map->dm_segs[0].ds_addr;
-
+ mtx_enter(&audio_lock);
sc->sc_capturing = 1;
harmony_start_cp(sc);
harmony_intr_enable(sc);
+ mtx_leave(&audio_lock);
return (0);
}
diff --git a/sys/arch/macppc/dev/awacs.c b/sys/arch/macppc/dev/awacs.c
index 071e40035dc..cb8e625033c 100644
--- a/sys/arch/macppc/dev/awacs.c
+++ b/sys/arch/macppc/dev/awacs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: awacs.c,v 1.27 2011/09/04 18:48:10 miod Exp $ */
+/* $OpenBSD: awacs.c,v 1.28 2013/05/15 08:29:23 ratchov Exp $ */
/* $NetBSD: awacs.c,v 1.4 2001/02/26 21:07:51 wiz Exp $ */
/*-
@@ -387,8 +387,9 @@ awacs_intr(void *v)
{
int reason;
struct awacs_softc *sc = v;
- reason = awacs_read_reg(sc, AWACS_SOUND_CTRL);
+ mtx_enter(&audio_lock);
+ reason = awacs_read_reg(sc, AWACS_SOUND_CTRL);
if (reason & AWACS_CTL_CNTRLERR) {
/* change outputs ?? */
}
@@ -413,6 +414,7 @@ awacs_intr(void *v)
}
awacs_write_reg(sc, AWACS_SOUND_CTRL, reason); /* clear interrupt */
+ mtx_leave(&audio_lock);
return 1;
}
@@ -425,8 +427,8 @@ awacs_tx_intr(void *v)
/* if not set we are not running */
if (!cmd)
- return (0);
-
+ return (0);
+ mtx_enter(&audio_lock);
c = in16rb(&cmd->d_command);
status = in16rb(&cmd->d_status);
@@ -441,7 +443,7 @@ awacs_tx_intr(void *v)
if (sc->sc_ointr)
(*sc->sc_ointr)(sc->sc_oarg);
}
-
+ mtx_leave(&audio_lock);
return (1);
}
int
@@ -455,6 +457,7 @@ awacs_rx_intr(void *v)
if (!cmd)
return (0);
+ mtx_enter(&audio_lock);
c = in16rb(&cmd->d_command);
status = in16rb(&cmd->d_status);
@@ -469,7 +472,7 @@ awacs_rx_intr(void *v)
if (sc->sc_iintr)
(*sc->sc_iintr)(sc->sc_iarg);
}
-
+ mtx_leave(&audio_lock);
return (1);
}
@@ -487,6 +490,7 @@ awacs_close(void *h)
{
struct awacs_softc *sc = h;
+ /* XXX: halt_xxx() already called by upper layer */
awacs_halt_output(sc);
awacs_halt_input(sc);
@@ -679,10 +683,12 @@ awacs_halt_output(void *h)
{
struct awacs_softc *sc = h;
+ mtx_enter(&audio_lock);
dbdma_stop(sc->sc_odma);
dbdma_reset(sc->sc_odma);
dbdma_stop(sc->sc_odma);
sc->sc_odmap = NULL;
+ mtx_leave(&audio_lock);
return 0;
}
@@ -691,8 +697,10 @@ awacs_halt_input(void *h)
{
struct awacs_softc *sc = h;
+ mtx_enter(&audio_lock);
dbdma_stop(sc->sc_idma);
dbdma_reset(sc->sc_idma);
+ mtx_leave(&audio_lock);
return 0;
}
@@ -1041,6 +1049,7 @@ awacs_trigger_output(void *h, void *start, void *end, int bsize,
sc->sc_oarg = arg;
sc->sc_odmap = sc->sc_odmacmd;
+ mtx_enter(&audio_lock);
spa = p->segs[0].ds_addr;
c = DBDMA_CMD_OUT_MORE;
for (pa = spa, epa = spa + (end - start);
@@ -1059,6 +1068,7 @@ awacs_trigger_output(void *h, void *start, void *end, int bsize,
dbdma_start(sc->sc_odma, sc->sc_odbdma);
+ mtx_leave(&audio_lock);
return 0;
}
@@ -1082,6 +1092,7 @@ awacs_trigger_input(void *h, void *start, void *end, int bsize,
sc->sc_iarg = arg;
sc->sc_idmap = sc->sc_idmacmd;
+ mtx_enter(&audio_lock);
spa = p->segs[0].ds_addr;
c = DBDMA_CMD_IN_MORE;
for (pa = spa, epa = spa + (end - start);
@@ -1100,6 +1111,7 @@ awacs_trigger_input(void *h, void *start, void *end, int bsize,
dbdma_start(sc->sc_idma, sc->sc_idbdma);
+ mtx_leave(&audio_lock);
return 0;
}
diff --git a/sys/arch/macppc/dev/i2s.c b/sys/arch/macppc/dev/i2s.c
index a5f18639fae..5f21a986a1c 100644
--- a/sys/arch/macppc/dev/i2s.c
+++ b/sys/arch/macppc/dev/i2s.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i2s.c,v 1.22 2011/06/07 16:29:51 mpi Exp $ */
+/* $OpenBSD: i2s.c,v 1.23 2013/05/15 08:29:23 ratchov Exp $ */
/* $NetBSD: i2s.c,v 1.1 2003/12/27 02:19:34 grant Exp $ */
/*-
@@ -132,9 +132,13 @@ i2s_intr(v)
struct dbdma_command *cmd = sc->sc_odmap;
u_int16_t c, status;
+ mtx_enter(&audio_lock);
+
/* if not set we are not running */
- if (!cmd)
+ if (!cmd) {
+ mtx_leave(&audio_lock);
return (0);
+ }
DPRINTF(("i2s_intr: cmd %x\n", cmd));
c = in16rb(&cmd->d_command);
@@ -151,7 +155,7 @@ i2s_intr(v)
if (sc->sc_ointr)
(*sc->sc_ointr)(sc->sc_oarg);
}
-
+ mtx_leave(&audio_lock);
return 1;
}
@@ -163,9 +167,13 @@ i2s_iintr(v)
struct dbdma_command *cmd = sc->sc_idmap;
u_int16_t c, status;
+ mtx_enter(&audio_lock);
+
/* if not set we are not running */
- if (!cmd)
+ if (!cmd) {
+ mtx_leave(&audio_lock);
return (0);
+ }
DPRINTF(("i2s_intr: cmd %x\n", cmd));
c = in16rb(&cmd->d_command);
@@ -182,7 +190,7 @@ i2s_iintr(v)
if (sc->sc_iintr)
(*sc->sc_iintr)(sc->sc_iarg);
}
-
+ mtx_leave(&audio_lock);
return 1;
}
diff --git a/sys/arch/sgi/dev/mavb.c b/sys/arch/sgi/dev/mavb.c
index bcbf54e6af2..4304652fbaf 100644
--- a/sys/arch/sgi/dev/mavb.c
+++ b/sys/arch/sgi/dev/mavb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mavb.c,v 1.14 2012/10/03 22:46:09 miod Exp $ */
+/* $OpenBSD: mavb.c,v 1.15 2013/05/15 08:29:23 ratchov Exp $ */
/*
* Copyright (c) 2005 Mark Kettenis
@@ -598,8 +598,9 @@ mavb_halt_output(void *hdl)
struct mavb_softc *sc = (struct mavb_softc *)hdl;
DPRINTF(1, ("%s: mavb_halt_output called\n", sc->sc_dev.dv_xname));
-
+ mtx_enter(&audio_lock);
bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
+ mtx_leave(&audio_lock);
return (0);
}
@@ -609,8 +610,9 @@ mavb_halt_input(void *hdl)
struct mavb_softc *sc = (struct mavb_softc *)hdl;
DPRINTF(1, ("%s: mavb_halt_input called\n", sc->sc_dev.dv_xname));
-
+ mtx_enter(&audio_lock);
bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL1_CONTROL, 0);
+ mtx_leave(&audio_lock);
return (0);
}
@@ -1129,6 +1131,7 @@ mavb_trigger_output(void *hdl, void *start, void *end, int blksize,
"blksize=%d intr=%p(%p)\n", sc->sc_dev.dv_xname,
start, end, blksize, intr, intrarg));
+ mtx_enter(&audio_lock);
sc->play.blksize = blksize;
sc->play.intr = intr;
sc->play.intrarg = intrarg;
@@ -1155,6 +1158,7 @@ mavb_trigger_output(void *hdl, void *start, void *end, int blksize,
*/
bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
MAVB_CHANNEL_DMA_ENABLE | MAVB_CHANNEL_INT_25);
+ mtx_leave(&audio_lock);
return (0);
}
@@ -1168,6 +1172,7 @@ mavb_trigger_input(void *hdl, void *start, void *end, int blksize,
"blksize=%d intr=%p(%p)\n", sc->sc_dev.dv_xname,
start, end, blksize, intr, intrarg));
+ mtx_enter(&audio_lock);
sc->rec.blksize = blksize;
sc->rec.intr = intr;
sc->rec.intrarg = intrarg;
@@ -1182,6 +1187,7 @@ mavb_trigger_input(void *hdl, void *start, void *end, int blksize,
bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL1_CONTROL,
MAVB_CHANNEL_DMA_ENABLE | MAVB_CHANNEL_INT_50);
+ mtx_leave(&audio_lock);
return (0);
}
@@ -1240,6 +1246,7 @@ mavb_intr(void *arg)
struct mavb_softc *sc = arg;
u_int64_t intstat, intmask;
+ mtx_enter(&audio_lock);
intstat = bus_space_read_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_STAT);
DPRINTF(MAVB_DEBUG_INTR, ("%s: mavb_intr: intstat = 0x%lx\n",
sc->sc_dev.dv_xname, intstat));
@@ -1260,7 +1267,7 @@ mavb_intr(void *arg)
if (intstat & MACE_ISA_INT_AUDIO_DMA2)
mavb_dma_output(sc);
-
+ mtx_leave(&audio_lock);
return 1;
}
diff --git a/sys/arch/sparc/dev/audioamd.c b/sys/arch/sparc/dev/audioamd.c
index 90915cc19f9..68cde256e0e 100644
--- a/sys/arch/sparc/dev/audioamd.c
+++ b/sys/arch/sparc/dev/audioamd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: audioamd.c,v 1.1 2011/09/03 20:04:02 miod Exp $ */
+/* $OpenBSD: audioamd.c,v 1.2 2013/05/15 08:29:23 ratchov Exp $ */
/* $NetBSD: audioamd.c,v 1.26 2011/06/04 01:27:57 tsutsui Exp $ */
/*
@@ -249,6 +249,9 @@ audioamd_onclose(struct am7930_softc *sc)
am7930_halt_output(sc);
}
+/*
+ * called in interrupt code-path, don't lock
+ */
int
audioamd_start_output(void *addr, void *p, int cc,
void (*intr)(void *), void *arg)
@@ -270,6 +273,9 @@ audioamd_start_output(void *addr, void *p, int cc,
return 0;
}
+/*
+ * called in interrupt code-path, don't lock
+ */
int
audioamd_start_input(void *addr, void *p, int cc,
void (*intr)(void *), void *arg)
@@ -347,12 +353,12 @@ am7930swintr(void *v)
au = &sc->sc_au;
dor = dow = 0;
- s = splaudio();
+ mtx_enter(&audio_lock);
if (au->au_rdata > au->au_rend && sc->sc_rintr != NULL)
dor = 1;
if (au->au_pdata > au->au_pend && sc->sc_pintr != NULL)
dow = 1;
- splx(s);
+ mtx_leave(&audio_lock);
if (dor != 0)
(*sc->sc_rintr)(sc->sc_rarg);
diff --git a/sys/arch/sparc/dev/cs4231.c b/sys/arch/sparc/dev/cs4231.c
index 830871b3820..94221574679 100644
--- a/sys/arch/sparc/dev/cs4231.c
+++ b/sys/arch/sparc/dev/cs4231.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cs4231.c,v 1.29 2010/07/15 03:43:11 jakemsr Exp $ */
+/* $OpenBSD: cs4231.c,v 1.30 2013/05/15 08:29:23 ratchov Exp $ */
/*
* Copyright (c) 1999 Jason L. Wright (jason@thought.net)
@@ -285,6 +285,7 @@ cs4231_intr(v)
u_int8_t reg, status;
int r = 0;
+ mtx_enter(&audio_lock);
csr = regs->dma_csr;
regs->dma_csr = csr;
@@ -372,7 +373,7 @@ cs4231_intr(v)
/* capture empty */
r = 1;
}
-
+ mtx_leave(&audio_lock);
return (r);
}
@@ -573,6 +574,7 @@ cs4231_close(addr)
struct cs4231_softc *sc = addr;
struct cs4231_regs *regs = sc->sc_regs;
+ /* XXX: already called by upper layer */
cs4231_halt_input(sc);
cs4231_halt_output(sc);
regs->iar = SP_PIN_CONTROL;
@@ -825,7 +827,7 @@ cs4231_halt_output(addr)
struct cs4231_regs *regs = sc->sc_regs;
u_int8_t r;
- /* XXX Kills some capture bits */
+ mtx_enter(&audio_lock);
regs->dma_csr &= ~(APC_CSR_EI | APC_CSR_GIE | APC_CSR_PIE |
APC_CSR_EIE | APC_CSR_PDMA_GO | APC_CSR_PMIE);
regs->iar = SP_INTERFACE_CONFIG;
@@ -833,6 +835,7 @@ cs4231_halt_output(addr)
regs->iar = SP_INTERFACE_CONFIG;
regs->idr = r;
sc->sc_playback.cs_locked = 0;
+ mtx_leave(&audio_lock);
return (0);
}
@@ -843,11 +846,12 @@ cs4231_halt_input(addr)
struct cs4231_softc *sc = (struct cs4231_softc *)addr;
struct cs4231_regs *regs = sc->sc_regs;
- /* XXX Kills some playback bits */
+ mtx_enter(&audio_lock);
regs->dma_csr = APC_CSR_CAPTURE_PAUSE;
regs->iar = SP_INTERFACE_CONFIG;
regs->idr &= ~CAPTURE_ENABLE;
sc->sc_capture.cs_locked = 0;
+ mtx_leave(&audio_lock);
return (0);
}
@@ -1513,8 +1517,10 @@ cs4231_trigger_output(addr, start, end, blksize, intr, arg, param)
u_int8_t reg;
u_int32_t n, csr;
+ mtx_enter(&audio_lock);
if (chan->cs_locked != 0) {
printf("cs4231_trigger_output: already running\n");
+ mtx_leave(&audio_lock);
return (EINVAL);
}
@@ -1527,6 +1533,7 @@ cs4231_trigger_output(addr, start, end, blksize, intr, arg, param)
p = p->next;
if (p == NULL) {
printf("cs4231_trigger_output: bad addr: %p\n", start);
+ mtx_leave(&audio_lock);
return (EINVAL);
}
@@ -1563,6 +1570,7 @@ cs4231_trigger_output(addr, start, end, blksize, intr, arg, param)
regs->iar = SP_INTERFACE_CONFIG;
regs->idr = reg;
}
+ mtx_leave(&audio_lock);
return (0);
}
@@ -1580,9 +1588,11 @@ cs4231_trigger_input(addr, start, end, blksize, intr, arg, param)
u_int32_t csr;
u_long n;
+ mtx_enter(&audio_lock);
if (chan->cs_locked != 0) {
printf("%s: trigger_input: already running\n",
sc->sc_dev.dv_xname);
+ mtx_leave(&audio_lock);
return (EINVAL);
}
chan->cs_locked = 1;
@@ -1594,6 +1604,7 @@ cs4231_trigger_input(addr, start, end, blksize, intr, arg, param)
if (p == NULL) {
printf("%s: trigger_input: bad addr: %p\n",
sc->sc_dev.dv_xname, start);
+ mtx_leave(&audio_lock);
return (EINVAL);
}
@@ -1644,6 +1655,6 @@ cs4231_trigger_input(addr, start, end, blksize, intr, arg, param)
sc->sc_regs->dma_cnva = nextaddr;
sc->sc_regs->dma_cnc = togo;
}
-
+ mtx_leave(&audio_lock);
return (0);
}
diff --git a/sys/arch/sparc64/dev/ce4231.c b/sys/arch/sparc64/dev/ce4231.c
index de987e3d28a..f5db2c691e0 100644
--- a/sys/arch/sparc64/dev/ce4231.c
+++ b/sys/arch/sparc64/dev/ce4231.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ce4231.c,v 1.28 2010/07/26 23:17:19 jakemsr Exp $ */
+/* $OpenBSD: ce4231.c,v 1.29 2013/05/15 08:29:23 ratchov Exp $ */
/*
* Copyright (c) 1999 Jason L. Wright (jason@thought.net)
@@ -644,7 +644,7 @@ ce4231_commit_settings(addr)
void *addr;
{
struct ce4231_softc *sc = (struct ce4231_softc *)addr;
- int s, tries;
+ int tries;
u_int8_t r, fs;
if (sc->sc_need_commit == 0)
@@ -659,7 +659,8 @@ ce4231_commit_settings(addr)
return (0);
}
- s = splaudio();
+ /* XXX: this code is called before DMA (this intrs) is stopped */
+ mtx_enter(&audio_lock);
r = ce4231_read(sc, SP_INTERFACE_CONFIG) | AUTO_CAL_ENABLE;
CS_WRITE(sc, AD1848_IADDR, MODE_CHANGE_ENABLE);
@@ -702,7 +703,7 @@ ce4231_commit_settings(addr)
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);
@@ -1242,6 +1243,7 @@ ce4231_pintr(v)
struct cs_chdma *chdma = &sc->sc_pchdma;
int r = 0;
+ mtx_enter(&audio_lock);
csr = P_READ(sc, EBDMA_DCSR);
reg = ce4231_read(sc, CS_IRQ_STATUS);
@@ -1279,7 +1281,7 @@ ce4231_pintr(v)
(*sc->sc_pintr)(sc->sc_parg);
r = 1;
}
-
+ mtx_leave(&audio_lock);
return (r);
}
@@ -1294,6 +1296,7 @@ ce4231_cintr(v)
struct cs_chdma *chdma = &sc->sc_rchdma;
int r = 0;
+ mtx_enter(&audio_lock);
csr = C_READ(sc, EBDMA_DCSR);
reg = ce4231_read(sc, CS_IRQ_STATUS);
@@ -1331,7 +1334,7 @@ ce4231_cintr(v)
(*sc->sc_rintr)(sc->sc_rarg);
r = 1;
}
-
+ mtx_leave(&audio_lock);
return (r);
}
diff --git a/sys/arch/vax/vsa/vsaudio.c b/sys/arch/vax/vsa/vsaudio.c
index 46ce4f1ce8e..8bf31770194 100644
--- a/sys/arch/vax/vsa/vsaudio.c
+++ b/sys/arch/vax/vsa/vsaudio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vsaudio.c,v 1.2 2011/09/11 19:29:01 miod Exp $ */
+/* $OpenBSD: vsaudio.c,v 1.3 2013/05/15 08:29:24 ratchov Exp $ */
/*
* Copyright (c) 2011 Miodrag Vallat.
@@ -283,6 +283,9 @@ vsaudio_onclose(struct am7930_softc *sc)
am7930_halt_output(sc);
}
+/*
+ * this is called by interrupt code-path, don't lock
+ */
int
vsaudio_start_output(void *addr, void *p, int cc,
void (*intr)(void *), void *arg)
@@ -304,6 +307,9 @@ vsaudio_start_output(void *addr, void *p, int cc,
return 0;
}
+/*
+ * this is called by interrupt code-path, don't lock
+ */
int
vsaudio_start_input(void *addr, void *p, int cc,
void (*intr)(void *), void *arg)
@@ -336,12 +342,15 @@ vsaudio_hwintr(void *v)
uint8_t *d, *e;
int k;
+ mtx_enter(&audio_lock);
/* clear interrupt */
k = vsaudio_codec_dread(sc, AM7930_DREG_IR);
#if 0 /* interrupt is not shared, this shouldn't happen */
if ((k & (AM7930_IR_DTTHRSH | AM7930_IR_DRTHRSH | AM7930_IR_DSRI |
- AM7930_IR_DERI | AM7930_IR_BBUFF)) == 0)
+ AM7930_IR_DERI | AM7930_IR_BBUFF)) == 0) {
+ mtx_leave(&audio_lock);
return 0;
+ }
#endif
/* receive incoming data */
@@ -367,6 +376,7 @@ vsaudio_hwintr(void *v)
softintr_schedule(sc->sc_swintr);
}
}
+ mtx_leave(&audio_lock);
}
void
@@ -378,12 +388,12 @@ vsaudio_swintr(void *v)
DPRINTFN(1, ("audiointr: sc=%p\n", sc));
dor = dow = 0;
- s = splaudio();
+ mtx_enter(&audio_lock);
if (sc->sc_rdata > sc->sc_rend && sc->sc_rintr != NULL)
dor = 1;
if (sc->sc_pdata > sc->sc_pend && sc->sc_pintr != NULL)
dow = 1;
- splx(s);
+ mtx_leave(&audio_lock);
if (dor != 0)
(*sc->sc_rintr)(sc->sc_rarg);
diff --git a/sys/arch/zaurus/dev/zaurus_audio.c b/sys/arch/zaurus/dev/zaurus_audio.c
index 90ce080bb3f..f640f0ad778 100644
--- a/sys/arch/zaurus/dev/zaurus_audio.c
+++ b/sys/arch/zaurus/dev/zaurus_audio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: zaurus_audio.c,v 1.15 2012/03/01 08:17:26 ratchov Exp $ */
+/* $OpenBSD: zaurus_audio.c,v 1.16 2013/05/15 08:29:24 ratchov Exp $ */
/*
* Copyright (c) 2005 Christopher Pascoe <pascoe@openbsd.org>
@@ -766,8 +766,10 @@ zaudio_halt_output(void *hdl)
/* XXX forcibly stop output DMA? */
+ mtx_enter(&audio_lock);
zaudio_standby(sc);
sc->sc_playing = 0;
+ mtx_leave(&audio_lock);
return 0;
}
@@ -977,6 +979,9 @@ zaudio_get_props(void *hdl)
return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
}
+/*
+ * called by interrupt code-path, don't lock
+ */
int
zaudio_start_output(void *hdl, void *block, int bsize, void (*intr)(void *),
void *intrarg)
@@ -999,6 +1004,9 @@ zaudio_start_output(void *hdl, void *block, int bsize, void (*intr)(void *),
return err;
}
+/*
+ * called by interrupt code-path, don't lock
+ */
int
zaudio_start_input(void *hdl, void *block, int bsize, void (*intr)(void *),
void *intrarg)