Skip to content

Commit

Permalink
dev/sound: allow unplug soundcars without apps close devices
Browse files Browse the repository at this point in the history
This patch fix use case: user unplug USB sound card before all apps
close /dev/mixer and /dev/dsp and then USB driver hang/wait until
all apps closed, no old devices can be removed, no new devices can be added.

dmesg show for mixer:
pcm4: unregister: mixer busy
pcm4: Waiting for sound application to exit!
And almost same for dsp, but also prints app pid.

Undone: only mixer unplug fixed.
  • Loading branch information
rozhuk-im committed Dec 20, 2020
1 parent d4f2ccb commit 74d5727
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 27 deletions.
16 changes: 2 additions & 14 deletions sys/dev/sound/pcm/mixer.c
Expand Up @@ -774,25 +774,14 @@ mixer_uninit(device_t dev)

d = device_get_softc(dev);
pdev = mixer_get_devt(dev);
if (d == NULL || pdev == NULL || pdev->si_drv1 == NULL)
if (d == NULL || pdev == NULL || (m = pdev->si_drv1) == NULL)
return EBADF;

m = pdev->si_drv1;
KASSERT(m != NULL, ("NULL snd_mixer"));
KASSERT(m->type == MIXER_TYPE_PRIMARY,
("%s(): illegal mixer type=%d", __func__, m->type));

snd_mtxlock(m->lock);

if (m->busy) {
snd_mtxunlock(m->lock);
return EBUSY;
}

/* destroy dev can sleep --hps */

snd_mtxunlock(m->lock);

d->mixer_dev = NULL;
pdev->si_drv1 = NULL;
destroy_dev(pdev);

Expand All @@ -812,7 +801,6 @@ mixer_uninit(device_t dev)
snd_mtxfree(m->lock);
kobj_delete((kobj_t)m, M_MIXER);

d->mixer_dev = NULL;

--mixer_count;

Expand Down
12 changes: 1 addition & 11 deletions sys/dev/sound/pcm/sound.c
Expand Up @@ -1145,9 +1145,7 @@ pcm_unregister(device_t dev)
{
struct snddev_info *d;
struct pcm_channel *ch;
struct thread *td;

td = curthread;
d = device_get_softc(dev);

if (!PCM_ALIVE(d)) {
Expand Down Expand Up @@ -1194,15 +1192,7 @@ pcm_unregister(device_t dev)
}
}

if (mixer_uninit(dev) == EBUSY) {
device_printf(dev, "unregister: mixer busy\n");
PCM_LOCK(d);
if (d->clones != NULL)
(void)snd_clone_enable(d->clones);
PCM_RELEASE(d);
PCM_UNLOCK(d);
return (EBUSY);
}
mixer_uninit(dev);

/* remove /dev/sndstat entry first */
sndstat_unregister(dev);
Expand Down
6 changes: 4 additions & 2 deletions sys/dev/sound/usb/uaudio.c
Expand Up @@ -1235,8 +1235,10 @@ uaudio_detach_sub(device_t dev)
if (sc->sc_child[i].pcm_registered) {
error = pcm_unregister(dev);
} else {
if (sc->sc_child[i].mixer_init)
error = mixer_uninit(dev);
if (sc->sc_child[i].mixer_init) {
error = 0;
mixer_uninit(dev);
}
}

if (error) {
Expand Down

0 comments on commit 74d5727

Please sign in to comment.