diff options
-rw-r--r-- | sys/dev/sound/pcm/mixer.c | 2 | ||||
-rw-r--r-- | sys/dev/sound/pcm/sndstat.c | 25 | ||||
-rw-r--r-- | sys/dev/sound/pcm/sound.c | 15 |
3 files changed, 30 insertions, 12 deletions
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c index 34dbcbd..7c1bd04 100644 --- a/sys/dev/sound/pcm/mixer.c +++ b/sys/dev/sound/pcm/mixer.c @@ -300,7 +300,9 @@ sysctl_hw_snd_hwvol_mixer(SYSCTL_HANDLER_ARGS) m = oidp->oid_arg1; snd_mtxlock(m->lock); strncpy(devname, snd_mixernames[m->hwvol_mixer], sizeof(devname)); + snd_mtxunlock(m->lock); error = sysctl_handle_string(oidp, &devname[0], sizeof(devname), req); + snd_mtxlock(m->lock); if (error == 0 && req->newptr != NULL) { dev = mixer_lookup(devname); if (dev == -1) { diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c index 5ff2080..bd9cb32 100644 --- a/sys/dev/sound/pcm/sndstat.c +++ b/sys/dev/sound/pcm/sndstat.c @@ -112,7 +112,7 @@ static int sndstat_open(dev_t i_dev, int flags, int mode, struct thread *td) { intrmask_t s; - int err; + int error; s = spltty(); mtx_lock(&sndstat_lock); @@ -121,19 +121,24 @@ sndstat_open(dev_t i_dev, int flags, int mode, struct thread *td) splx(s); return EBUSY; } + sndstat_isopen = 1; + mtx_unlock(&sndstat_lock); + splx(s); if (sbuf_new(&sndstat_sbuf, NULL, 4096, 0) == NULL) { + error = ENXIO; + goto out; + } + sndstat_bufptr = 0; + error = (sndstat_prepare(&sndstat_sbuf) > 0) ? 0 : ENOMEM; +out: + if (error) { + s = spltty(); + mtx_lock(&sndstat_lock); + sndstat_isopen = 0; mtx_unlock(&sndstat_lock); splx(s); - return ENXIO; } - sndstat_bufptr = 0; - err = (sndstat_prepare(&sndstat_sbuf) > 0)? 0 : ENOMEM; - if (!err) - sndstat_isopen = 1; - - mtx_unlock(&sndstat_lock); - splx(s); - return err; + return (error); } static int diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index 3f346f3..8fe48a2 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -798,7 +798,7 @@ sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS) struct snddev_info *d; struct snddev_channel *sce; struct pcm_channel *c; - int err, oldcnt, newcnt, cnt; + int err, newcnt, cnt; d = oidp->oid_arg1; @@ -809,10 +809,21 @@ sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS) if ((c->direction == PCMDIR_PLAY) && (c->flags & CHN_F_VIRTUAL)) cnt++; } - oldcnt = cnt; newcnt = cnt; + pcm_unlock(d); err = sysctl_handle_int(oidp, &newcnt, sizeof(newcnt), req); + pcm_lock(d); + /* + * Since we dropped the pcm_lock, reload cnt now as it may + * have changed. + */ + cnt = 0; + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + if ((c->direction == PCMDIR_PLAY) && (c->flags & CHN_F_VIRTUAL)) + cnt++; + } if (err == 0 && req->newptr != NULL) { if (newcnt < 0 || newcnt > SND_MAXVCHANS) { pcm_unlock(d); |