git: 365067e98e4e - main - Revert "sound: Implement asynchronous device detach"

From: Christos Margiolis <christos_at_FreeBSD.org>
Date: Fri, 05 Apr 2024 10:38:25 UTC
The branch main has been updated by christos:

URL: https://cgit.FreeBSD.org/src/commit/?id=365067e98e4e9deba18070f5ebd4e9eee7149b6d

commit 365067e98e4e9deba18070f5ebd4e9eee7149b6d
Author:     Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2024-04-05 10:27:47 +0000
Commit:     Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2024-04-05 10:33:23 +0000

    Revert "sound: Implement asynchronous device detach"
    
    This reverts commit 9eff58c6d52b66eb8abe7f724dabcd804a566df4.
    
    We are reverting dc831e93bad6 ("sound: Get rid of snd_clone and use
    DEVFS_CDEVPRIV(9)"), so revert this commit as well since it depends
    dc831e93bad6.
---
 share/man/man4/snd_uaudio.4 | 11 ++++++++++-
 sys/dev/sound/pcm/dsp.c     |  2 +-
 sys/dev/sound/pcm/mixer.c   | 11 +++++++++++
 sys/dev/sound/pcm/sound.c   | 24 ++++++++++++++----------
 sys/dev/sound/usb/uaudio.c  | 13 ++++++++++---
 5 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/share/man/man4/snd_uaudio.4 b/share/man/man4/snd_uaudio.4
index 6e2509b8f2ac..b6a6c06a2312 100644
--- a/share/man/man4/snd_uaudio.4
+++ b/share/man/man4/snd_uaudio.4
@@ -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.
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index 754f09c7199e..b9693908da43 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -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);
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
index cc8cf5b1ceea..ee1ed11a8ed0 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -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);
 
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index 1517126210c4..53cde49c4905 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -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);
diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index 2351c2522021..5d7396c527e0 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -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