diff options
| author | ad <ad@NetBSD.org> | 2007-02-09 21:55:00 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2007-02-09 21:55:00 +0000 |
| commit | b07ec3fc388a5aeae51e8871aa89eefea3ce1e53 (patch) | |
| tree | c93d3b23a29f98ac0e26c9d43afb509219d0ea42 /sys/dev/audio.c | |
| parent | 5c1aad3ad0b9d2403784bd52128e8e8399e22254 (diff) | |
Merge newlock2 to head.
Diffstat (limited to 'sys/dev/audio.c')
| -rw-r--r-- | sys/dev/audio.c | 74 |
1 files changed, 59 insertions, 15 deletions
diff --git a/sys/dev/audio.c b/sys/dev/audio.c index 2ea82d47203..ebc4605c931 100644 --- a/sys/dev/audio.c +++ b/sys/dev/audio.c @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.215 2006/11/16 01:32:44 christos Exp $ */ +/* $NetBSD: audio.c,v 1.216 2007/02/09 21:55:26 ad Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.215 2006/11/16 01:32:44 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.216 2007/02/09 21:55:26 ad Exp $"); #include "audio.h" #if NAUDIO > 0 @@ -174,6 +174,9 @@ int audioactivate(struct device *, enum devact); void audio_powerhook(int, void *); +static void audio_softintr_rd(void *); +static void audio_softintr_wr(void *); + struct portname { const char *name; int mask; @@ -333,6 +336,11 @@ audioattach(struct device *parent, struct device *self, void *aux) return; } + sc->sc_sih_rd = softintr_establish(IPL_SOFTSERIAL, + audio_softintr_rd, sc); + sc->sc_sih_wr = softintr_establish(IPL_SOFTSERIAL, + audio_softintr_wr, sc); + iclass = mclass = oclass = rclass = -1; sc->sc_inports.index = -1; sc->sc_inports.master = -1; @@ -522,6 +530,14 @@ audiodetach(struct device *self, int flags) powerhook_disestablish(sc->sc_powerhook); sc->sc_powerhook = NULL; } + if (sc->sc_sih_rd) { + softintr_disestablish(sc->sc_sih_rd); + sc->sc_sih_rd = NULL; + } + if (sc->sc_sih_wr) { + softintr_disestablish(sc->sc_sih_wr); + sc->sc_sih_wr = NULL; + } return 0; } @@ -2492,6 +2508,40 @@ audio_pint_silence(struct audio_softc *sc, struct audio_ringbuffer *cb, } } +static void +audio_softintr_rd(void *cookie) +{ + struct audio_softc *sc = cookie; + struct proc *p; + + selnotify(&sc->sc_rsel, 0); + if (sc->sc_async_audio != NULL) { + DPRINTFN(3, ("audio_softintr_rd: sending SIGIO %p\n", + sc->sc_async_audio)); + mutex_enter(&proclist_mutex); + if ((p = sc->sc_async_audio) != NULL) + psignal(p, SIGIO); + mutex_exit(&proclist_mutex); + } +} + +static void +audio_softintr_wr(void *cookie) +{ + struct audio_softc *sc = cookie; + struct proc *p; + + selnotify(&sc->sc_wsel, 0); + if (sc->sc_async_audio != NULL) { + DPRINTFN(3, ("audio_softintr_wr: sending SIGIO %p\n", + sc->sc_async_audio)); + mutex_enter(&proclist_mutex); + if ((p = sc->sc_async_audio) != NULL) + psignal(p, SIGIO); + mutex_exit(&proclist_mutex); + } +} + /* * Called from HW driver module on completion of DMA output. * Start output of new block, wrap in ring buffer if needed. @@ -2623,21 +2673,14 @@ audio_pint(void *v) if ((sc->sc_mode & AUMODE_PLAY) && !cb->pause) { if (audio_stream_get_used(sc->sc_pustream) <= cb->usedlow) { audio_wakeup(&sc->sc_wchan); - selnotify(&sc->sc_wsel, 0); - if (sc->sc_async_audio) { - DPRINTFN(3, ("audio_pint: sending SIGIO %p\n", - sc->sc_async_audio)); - psignal(sc->sc_async_audio, SIGIO); - } + softintr_schedule(sc->sc_sih_wr); } } /* Possible to return one or more "phantom blocks" now. */ if (!sc->sc_full_duplex && sc->sc_rchan) { audio_wakeup(&sc->sc_rchan); - selnotify(&sc->sc_rsel, 0); - if (sc->sc_async_audio) - psignal(sc->sc_async_audio, SIGIO); + softintr_schedule(sc->sc_sih_rd); } } @@ -2744,9 +2787,7 @@ audio_rint(void *v) } audio_wakeup(&sc->sc_rchan); - selnotify(&sc->sc_rsel, 0); - if (sc->sc_async_audio) - psignal(sc->sc_async_audio, SIGIO); + softintr_schedule(sc->sc_sih_rd); } int @@ -3625,8 +3666,11 @@ mixer_signal(struct audio_softc *sc) { struct mixer_asyncs *m; - for (m = sc->sc_async_mixer; m; m = m->next) + for (m = sc->sc_async_mixer; m; m = m->next) { + mutex_enter(&proclist_mutex); psignal(m->proc, SIGIO); + mutex_exit(&proclist_mutex); + } } /* |
