Revert "sound: Implement asynchronous device detach"

This reverts commit 9eff58c6d5.

We are reverting dc831e93ba ("sound: Get rid of snd_clone and use
DEVFS_CDEVPRIV(9)"), so revert this commit as well since it depends
dc831e93ba.
This commit is contained in:
Christos Margiolis 2024-04-05 12:27:47 +02:00
parent 5ffb19ac36
commit 365067e98e
5 changed files with 46 additions and 15 deletions

View file

@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd March 26, 2024
.Dd January 29, 2024
.Dt SND_UAUDIO 4
.Os
.Sh NAME
@ -156,6 +156,15 @@ and modified for
by
.An Hiten Pandya Aq Mt hmp@FreeBSD.org .
.Sh BUGS
The PCM framework in
.Fx
only supports synchronous device detach.
That means all mixer and DSP character devices belonging to a given
USB audio device must be closed when receiving an error on a DSP read,
a DSP write or a DSP IOCTL request.
Else the USB audio driver will wait for this to happen, preventing
enumeration of new devices on the parenting USB controller.
.Pp
Some USB audio devices might refuse to work properly unless the sample
rate is configured the same for both recording and playback, even if
only simplex is used.

View file

@ -295,7 +295,7 @@ dsp_close(void *data)
d = priv->sc;
/* At this point pcm_unregister() will destroy all channels anyway. */
if (PCM_DETACHING(d))
if (!PCM_REGISTERED(d))
goto skip;
PCM_GIANT_ENTER(d);

View file

@ -817,6 +817,17 @@ mixer_uninit(device_t dev)
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);
pdev->si_drv1 = NULL;
destroy_dev(pdev);

View file

@ -1001,22 +1001,26 @@ pcm_unregister(device_t dev)
CHN_FOREACH(ch, d, channels.pcm) {
CHN_LOCK(ch);
if (ch->flags & CHN_F_SLEEPING) {
/*
* We are detaching, so do not wait for the timeout in
* chn_read()/chn_write(). Wake up the thread and kill
* the channel immediately.
*/
CHN_BROADCAST(&ch->intr_cv);
ch->flags |= CHN_F_DEAD;
if (ch->refcount > 0) {
device_printf(dev,
"unregister: channel %s busy (pid %d)\n",
ch->name, ch->pid);
CHN_UNLOCK(ch);
PCM_RELEASE_QUICK(d);
return (EBUSY);
}
chn_abort(ch);
CHN_UNLOCK(ch);
}
dsp_destroy_dev(dev);
(void)mixer_uninit(dev);
if (mixer_uninit(dev) == EBUSY) {
device_printf(dev, "unregister: mixer busy\n");
PCM_LOCK(d);
PCM_RELEASE(d);
PCM_UNLOCK(d);
return (EBUSY);
}
/* remove /dev/sndstat entry first */
sndstat_unregister(dev);

View file

@ -1255,13 +1255,20 @@ uaudio_detach_sub(device_t dev)
unsigned i = uaudio_get_child_index_by_dev(sc, dev);
int error = 0;
repeat:
if (sc->sc_child[i].pcm_registered) {
error = pcm_unregister(dev);
} else if (sc->sc_child[i].mixer_init) {
error = mixer_uninit(dev);
} else {
if (sc->sc_child[i].mixer_init)
error = mixer_uninit(dev);
}
return (error);
if (error) {
device_printf(dev, "Waiting for sound application to exit!\n");
usb_pause_mtx(NULL, 2 * hz);
goto repeat; /* try again */
}
return (0); /* success */
}
static int