summaryrefslogtreecommitdiff
path: root/sys/dev/pci/maestro.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/maestro.c')
-rw-r--r--sys/dev/pci/maestro.c56
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;
}