diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2013-05-15 08:29:27 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2013-05-15 08:29:27 +0000 |
commit | e4d6a0a80573196dfd09b1201d79c9b77536c745 (patch) | |
tree | e7cc60514c99640b6483947ee3bfb09d9b2d58bb /sys/arch | |
parent | 2af0efdd18ad07b832c93f5c98d654ace8e0524e (diff) |
Introduce a global interrupt-aware mutex protecting data
structures (including sound-card registers) from concurent
access by syscall and interrupt code-paths. Since critical
sections remain the same, calls to splraise/spllower can be
safely replaced by calls to mtx_enter/mtx_leave with two
exceptions: (1) mutexes are not reentrant (the inner splraise
is thus removed), and (2) we're not allowed to sleep with a
mutex (either msleep is used or the mutex is released before
sleeping).
ok and help from kettenis, a lot of work from armani
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/hppa/gsc/harmony.c | 14 | ||||
-rw-r--r-- | sys/arch/macppc/dev/awacs.c | 24 | ||||
-rw-r--r-- | sys/arch/macppc/dev/i2s.c | 18 | ||||
-rw-r--r-- | sys/arch/sgi/dev/mavb.c | 15 | ||||
-rw-r--r-- | sys/arch/sparc/dev/audioamd.c | 12 | ||||
-rw-r--r-- | sys/arch/sparc/dev/cs4231.c | 21 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/ce4231.c | 15 | ||||
-rw-r--r-- | sys/arch/vax/vsa/vsaudio.c | 18 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_audio.c | 10 |
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) |