Blob Blame History Raw
From a4aad5636c7298eecfb60fc9d73933336cb0c4d8 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Wed, 25 Mar 2020 11:33:21 +0100
Subject: [PATCH] ALSA: usb-audio: Inform devices that need delayed registration
Git-commit: a4aad5636c7298eecfb60fc9d73933336cb0c4d8
Patch-mainline: v5.7-rc1
References: bsc#1051510

The USB-audio driver may call snd_card_register() multiple times as
its probe function is per USB interface while some USB-audio devices
may provide multiple interfaces to assign different streams although
they belong to the same device.  This works in most cases but the
registration is racy, hence it may miss the device recognition,
e.g. PA doesn't see certain devices when hotplugged.

The recent addition of the delayed registration quirk allows to sync
the registration at the last known interface, and the previous commit
added a new module option to allow the dynamic setup for that
purpose.

Now, this patch tries to find out and notifies for such devices that
require the delayed registration.  It shows a message like:

  Found post-registration device assignment: 1234abcd:02

If you hit this message, you can pass delayed_register module option
Like: 

  snd_usb_audio.delayed_register=1234abcd:02

by just copying the last shown entry.  If this works, it can be added
statically in the quirk list, registration_quirks[] found at the end
of sound/usb/quirks.c.

Link: https://lore.kernel.org/r/20200325103322.2508-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

---
 sound/usb/card.c     |    7 +++++++
 sound/usb/stream.c   |    3 +++
 sound/usb/usbaudio.h |    2 +-
 3 files changed, 11 insertions(+), 1 deletion(-)

--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -693,6 +693,13 @@ static int usb_audio_probe(struct usb_in
 			goto __error;
 	}
 
+	if (chip->need_delayed_register) {
+		dev_info(&dev->dev,
+			 "Found post-registration device assignment: %08x:%02x\n",
+			 chip->usb_id, ifnum);
+		chip->need_delayed_register = false; /* clear again */
+	}
+
 	/* we are allowed to call snd_card_register() many times, but first
 	 * check to see if a device needs to skip it or do anything special
 	 */
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -512,6 +512,9 @@ static int __snd_usb_add_audio_stream(st
 		subs = &as->substream[stream];
 		if (subs->ep_num)
 			continue;
+		if (snd_device_get_state(chip->card, as->pcm) !=
+		    SNDRV_DEV_BUILD)
+			chip->need_delayed_register = true;
 		err = snd_pcm_new_stream(as->pcm, stream, 1);
 		if (err < 0)
 			return err;
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -44,7 +44,7 @@ struct snd_usb_audio {
 	wait_queue_head_t shutdown_wait;
 	unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
 	unsigned int tx_length_quirk:1; /* Put length specifier in transfers */
-	
+	unsigned int need_delayed_register:1; /* warn for delayed registration */
 	int num_interfaces;
 	int num_suspended_intf;
 	int sample_rate_read_error;