Linux Sound subsystem development
 help / color / mirror / Atom feed
* [PATCH] ALSA: usb-audio: Release components on probe errors
@ 2026-06-18 17:00 Cen Zhang
  2026-06-29 10:28 ` Takashi Iwai
  0 siblings, 1 reply; 2+ messages in thread
From: Cen Zhang @ 2026-06-18 17:00 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai
  Cc: linux-sound, linux-kernel, baijiaju1990, zzzccc427

usb_audio_probe() can create USB-audio component resources before the
first interface is recorded in chip->num_interfaces.  If a later probe
step fails, the error path drops chip->active and frees the card directly
when no interfaces have been registered.

Normal disconnect first releases USB-audio components in a fixed order
before the card is freed.  The first-interface probe error path skipped
that sequence, so partially initialized PCM, endpoint, MIDI, media, or
mixer resources could be left for the card private_free path without their
disconnect handling having run.

Move the existing normal-disconnect component release sequence into a
helper and call it from the zero-interface probe error path before
snd_card_free().  Keep the normal disconnect ordering unchanged: PCM
streams, endpoint resources, MIDI 1.0 resources, MIDI 2.0 resources, media
device cleanup, then mixer resources.

Assisted-by: Codex:gpt-5.5
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
 sound/usb/card.c | 70 ++++++++++++++++++++++++++----------------------
 1 file changed, 38 insertions(+), 32 deletions(-)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index 6a3b576fb067..b36f513dccb9 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -905,6 +905,40 @@ static int try_to_register_card(struct snd_usb_audio *chip, int ifnum)
 	return 0;
 }
 
+static void usb_audio_disconnect_components(struct snd_usb_audio *chip)
+{
+	struct snd_usb_stream *as;
+	struct snd_usb_endpoint *ep;
+	struct usb_mixer_interface *mixer;
+	struct list_head *p;
+
+	/* release the pcm resources */
+	list_for_each_entry(as, &chip->pcm_list, list) {
+		snd_usb_stream_disconnect(as);
+	}
+	/* release the endpoint resources */
+	list_for_each_entry(ep, &chip->ep_list, list) {
+		snd_usb_endpoint_release(ep);
+	}
+	/* release the midi resources */
+	list_for_each(p, &chip->midi_list) {
+		snd_usbmidi_disconnect(p);
+	}
+	snd_usb_midi_v2_disconnect_all(chip);
+	/*
+	 * Nice to check quirk && quirk->shares_media_device and
+	 * then call the snd_media_device_delete(). Don't have
+	 * access to the quirk here. snd_media_device_delete()
+	 * accesses mixer_list
+	 */
+	snd_media_device_delete(chip);
+
+	/* release mixer resources */
+	list_for_each_entry(mixer, &chip->mixer_list, list) {
+		snd_usb_mixer_disconnect(mixer);
+	}
+}
+
 /*
  * probe the active usb device
  *
@@ -1077,8 +1111,10 @@ static int usb_audio_probe(struct usb_interface *intf,
 		 * decrement before memory is possibly returned.
 		 */
 		atomic_dec(&chip->active);
-		if (!chip->num_interfaces)
+		if (!chip->num_interfaces) {
+			usb_audio_disconnect_components(chip);
 			snd_card_free(chip->card);
+		}
 	}
 	return err;
 }
@@ -1091,48 +1127,18 @@ static bool __usb_audio_disconnect(struct usb_interface *intf,
 				   struct snd_usb_audio *chip,
 				   struct snd_card *card)
 {
-	struct list_head *p;
-
 	guard(mutex)(&register_mutex);
 
 	if (platform_ops && platform_ops->disconnect_cb)
 		platform_ops->disconnect_cb(chip);
 
 	if (atomic_inc_return(&chip->shutdown) == 1) {
-		struct snd_usb_stream *as;
-		struct snd_usb_endpoint *ep;
-		struct usb_mixer_interface *mixer;
-
 		/* wait until all pending tasks done;
 		 * they are protected by snd_usb_lock_shutdown()
 		 */
 		snd_refcount_sync(&chip->usage_count);
 		snd_card_disconnect(card);
-		/* release the pcm resources */
-		list_for_each_entry(as, &chip->pcm_list, list) {
-			snd_usb_stream_disconnect(as);
-		}
-		/* release the endpoint resources */
-		list_for_each_entry(ep, &chip->ep_list, list) {
-			snd_usb_endpoint_release(ep);
-		}
-		/* release the midi resources */
-		list_for_each(p, &chip->midi_list) {
-			snd_usbmidi_disconnect(p);
-		}
-		snd_usb_midi_v2_disconnect_all(chip);
-		/*
-		 * Nice to check quirk && quirk->shares_media_device and
-		 * then call the snd_media_device_delete(). Don't have
-		 * access to the quirk here. snd_media_device_delete()
-		 * accesses mixer_list
-		 */
-		snd_media_device_delete(chip);
-
-		/* release mixer resources */
-		list_for_each_entry(mixer, &chip->mixer_list, list) {
-			snd_usb_mixer_disconnect(mixer);
-		}
+		usb_audio_disconnect_components(chip);
 	}
 
 	if (chip->quirk_flags & QUIRK_FLAG_DISABLE_AUTOSUSPEND)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] ALSA: usb-audio: Release components on probe errors
  2026-06-18 17:00 [PATCH] ALSA: usb-audio: Release components on probe errors Cen Zhang
@ 2026-06-29 10:28 ` Takashi Iwai
  0 siblings, 0 replies; 2+ messages in thread
From: Takashi Iwai @ 2026-06-29 10:28 UTC (permalink / raw)
  To: Cen Zhang
  Cc: Jaroslav Kysela, Takashi Iwai, linux-sound, linux-kernel,
	baijiaju1990

On Thu, 18 Jun 2026 19:00:26 +0200,
Cen Zhang wrote:
> 
> usb_audio_probe() can create USB-audio component resources before the
> first interface is recorded in chip->num_interfaces.  If a later probe
> step fails, the error path drops chip->active and frees the card directly
> when no interfaces have been registered.
> 
> Normal disconnect first releases USB-audio components in a fixed order
> before the card is freed.  The first-interface probe error path skipped
> that sequence, so partially initialized PCM, endpoint, MIDI, media, or
> mixer resources could be left for the card private_free path without their
> disconnect handling having run.
> 
> Move the existing normal-disconnect component release sequence into a
> helper and call it from the zero-interface probe error path before
> snd_card_free().  Keep the normal disconnect ordering unchanged: PCM
> streams, endpoint resources, MIDI 1.0 resources, MIDI 2.0 resources, media
> device cleanup, then mixer resources.
> 
> Assisted-by: Codex:gpt-5.5
> Signed-off-by: Cen Zhang <zzzccc427@gmail.com>

Applied to for-next branch now.  Thanks.


Takashi

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-06-29 10:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-18 17:00 [PATCH] ALSA: usb-audio: Release components on probe errors Cen Zhang
2026-06-29 10:28 ` Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox