diff options
Diffstat (limited to 'sys/dev/pci/maestro.c')
-rw-r--r-- | sys/dev/pci/maestro.c | 56 |
1 files changed, 41 insertions, 15 deletions
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; } |