All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] ALSA: usb-audio: Option for delayed registration
@ 2020-03-25 10:33 Takashi Iwai
  2020-03-25 10:33 ` [PATCH 1/4] ALSA: usb-audio: Rewrite registration quirk handling Takashi Iwai
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Takashi Iwai @ 2020-03-25 10:33 UTC (permalink / raw)
  To: alsa-devel

Hi,

USB-audio driver probes per USB insterface, and this used to be the
cause of the missing device enumeration on user-space because the
driver registers the device per interface probe.  The recently added
quirk allows the delayed registration to sync with the last known
stream, but we must have far more such devices.

This patch set adds a new option to let user specify the delayed
registration device setup and also inform such devices at probe time.


Takashi

===

Takashi Iwai (4):
  ALSA: usb-audio: Rewrite registration quirk handling
  ALSA: usb-audio: Add delayed_register option
  ALSA: usb-audio: Inform devices that need delayed registration
  ALSA: usb-audio: Update the documentation for the new delayed_register
    option

 Documentation/sound/alsa-configuration.rst | 13 ++++++++++
 sound/usb/card.c                           | 28 ++++++++++++++++++++-
 sound/usb/quirks.c                         | 40 ++++++++++++++++++++++--------
 sound/usb/quirks.h                         |  3 +--
 sound/usb/stream.c                         |  3 +++
 sound/usb/usbaudio.h                       |  1 +
 6 files changed, 75 insertions(+), 13 deletions(-)

-- 
2.16.4


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

* [PATCH 1/4] ALSA: usb-audio: Rewrite registration quirk handling
  2020-03-25 10:33 [PATCH 0/4] ALSA: usb-audio: Option for delayed registration Takashi Iwai
@ 2020-03-25 10:33 ` Takashi Iwai
  2020-03-25 10:33 ` [PATCH 2/4] ALSA: usb-audio: Add delayed_register option Takashi Iwai
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2020-03-25 10:33 UTC (permalink / raw)
  To: alsa-devel

A slight refactoring of the registration quirk code.  Now it uses the
table lookup for easy additions in future.  Also the return type was
changed to bool, and got a few more comments.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/card.c   |  2 +-
 sound/usb/quirks.c | 40 ++++++++++++++++++++++++++++++----------
 sound/usb/quirks.h |  3 +--
 3 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index 16bbe2a50fb7..55d563a8154d 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -665,7 +665,7 @@ static int usb_audio_probe(struct usb_interface *intf,
 	/* 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
 	 */
-	if (snd_usb_registration_quirk(chip, ifnum) == 0) {
+	if (!snd_usb_registration_quirk(chip, ifnum)) {
 		err = snd_card_register(chip->card);
 		if (err < 0)
 			goto __error;
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index d605aff801b8..86f192a3043d 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1809,16 +1809,36 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
 	}
 }
 
-int snd_usb_registration_quirk(struct snd_usb_audio *chip,
-			       int iface)
+/*
+ * registration quirk:
+ * the registration is skipped if a device matches with the given ID,
+ * unless the interface reaches to the defined one.  This is for delaying
+ * the registration until the last known interface, so that the card and
+ * devices appear at the same time.
+ */
+
+struct registration_quirk {
+	unsigned int usb_id;	/* composed via USB_ID() */
+	unsigned int interface;	/* the interface to trigger register */
+};
+
+#define REG_QUIRK_ENTRY(vendor, product, iface) \
+	{ .usb_id = USB_ID(vendor, product), .interface = (iface) }
+
+static const struct registration_quirk registration_quirks[] = {
+	REG_QUIRK_ENTRY(0x0951, 0x16d8, 2),	/* Kingston HyperX AMP */
+	{ 0 }					/* terminator */
+};
+
+/* return true if skipping registration */
+bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface)
 {
-	switch (chip->usb_id) {
-	case USB_ID(0x0951, 0x16d8): /* Kingston HyperX AMP */
-		/* Register only when we reach interface 2 so that streams can
-		 * merge correctly into PCMs from interface 0
-		 */
-		return (iface != 2);
-	}
+	const struct registration_quirk *q;
+
+	for (q = registration_quirks; q->usb_id; q++)
+		if (chip->usb_id == q->usb_id)
+			return iface != q->interface;
+
 	/* Register as normal */
-	return 0;
+	return false;
 }
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
index 3afc01eabc7e..c76cf24a640a 100644
--- a/sound/usb/quirks.h
+++ b/sound/usb/quirks.h
@@ -51,7 +51,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
 					  struct audioformat *fp,
 					  int stream);
 
-int snd_usb_registration_quirk(struct snd_usb_audio *chip,
-			       int iface);
+bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface);
 
 #endif /* __USBAUDIO_QUIRKS_H */
-- 
2.16.4


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

* [PATCH 2/4] ALSA: usb-audio: Add delayed_register option
  2020-03-25 10:33 [PATCH 0/4] ALSA: usb-audio: Option for delayed registration Takashi Iwai
  2020-03-25 10:33 ` [PATCH 1/4] ALSA: usb-audio: Rewrite registration quirk handling Takashi Iwai
@ 2020-03-25 10:33 ` Takashi Iwai
  2020-03-25 10:33 ` [PATCH 3/4] ALSA: usb-audio: Inform devices that need delayed registration Takashi Iwai
  2020-03-25 10:33 ` [PATCH 4/4] ALSA: usb-audio: Update the documentation for the new delayed_register option Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2020-03-25 10:33 UTC (permalink / raw)
  To: alsa-devel

Add a new option for specifying the quirk for delayed registration of
the certain device.  A list of devices can be passed in a form
	ID:IFACE,ID:IFACE,ID:IFACE,....
where ID is the 32bit hex number combo of vendor and device IDs and
IFACE is the interface number to trigger the register.

When a matching device is probed, the card registration is delayed
until the given interface is probed.  It's needed for syncing the
registration until the last interface when multiple interfaces are
provided for the same card.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/card.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index 55d563a8154d..951134238669 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -72,6 +72,7 @@ static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
 static bool ignore_ctl_error;
 static bool autoclock = true;
 static char *quirk_alias[SNDRV_CARDS];
+static char *delayed_register[SNDRV_CARDS];
 
 bool snd_usb_use_vmalloc = true;
 bool snd_usb_skip_validation;
@@ -95,6 +96,8 @@ module_param(autoclock, bool, 0444);
 MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes).");
 module_param_array(quirk_alias, charp, NULL, 0444);
 MODULE_PARM_DESC(quirk_alias, "Quirk aliases, e.g. 0123abcd:5678beef.");
+module_param_array(delayed_register, charp, NULL, 0444);
+MODULE_PARM_DESC(delayed_register, "Quirk for delayed registration, given by id:iface, e.g. 0123abcd:4.");
 module_param_named(use_vmalloc, snd_usb_use_vmalloc, bool, 0444);
 MODULE_PARM_DESC(use_vmalloc, "Use vmalloc for PCM intermediate buffers (default: yes).");
 module_param_named(skip_validation, snd_usb_skip_validation, bool, 0444);
@@ -525,6 +528,21 @@ static bool get_alias_id(struct usb_device *dev, unsigned int *id)
 	return false;
 }
 
+static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface)
+{
+	int i;
+	unsigned int id, inum;
+
+	for (i = 0; i < ARRAY_SIZE(delayed_register); i++) {
+		if (delayed_register[i] &&
+		    sscanf(delayed_register[i], "%x:%x", &id, &inum) == 2 &&
+		    id == chip->usb_id)
+			return inum != iface;
+	}
+
+	return false;
+}
+
 static const struct usb_device_id usb_audio_ids[]; /* defined below */
 
 /* look for the corresponding quirk */
@@ -665,7 +683,8 @@ static int usb_audio_probe(struct usb_interface *intf,
 	/* 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
 	 */
-	if (!snd_usb_registration_quirk(chip, ifnum)) {
+	if (!snd_usb_registration_quirk(chip, ifnum) &&
+	    !check_delayed_register_option(chip, ifnum)) {
 		err = snd_card_register(chip->card);
 		if (err < 0)
 			goto __error;
-- 
2.16.4


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

* [PATCH 3/4] ALSA: usb-audio: Inform devices that need delayed registration
  2020-03-25 10:33 [PATCH 0/4] ALSA: usb-audio: Option for delayed registration Takashi Iwai
  2020-03-25 10:33 ` [PATCH 1/4] ALSA: usb-audio: Rewrite registration quirk handling Takashi Iwai
  2020-03-25 10:33 ` [PATCH 2/4] ALSA: usb-audio: Add delayed_register option Takashi Iwai
@ 2020-03-25 10:33 ` Takashi Iwai
  2020-03-25 10:33 ` [PATCH 4/4] ALSA: usb-audio: Update the documentation for the new delayed_register option Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2020-03-25 10:33 UTC (permalink / raw)
  To: alsa-devel

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.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/card.c     | 7 +++++++
 sound/usb/stream.c   | 3 +++
 sound/usb/usbaudio.h | 1 +
 3 files changed, 11 insertions(+)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index 951134238669..fd6fd1726ea0 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -680,6 +680,13 @@ static int usb_audio_probe(struct usb_interface *intf,
 			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
 	 */
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index afd5aa574611..15296f2c902c 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -502,6 +502,9 @@ static int __snd_usb_add_audio_stream(struct snd_usb_audio *chip,
 		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;
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 6fe3ab582ec6..1c892c7f14d7 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -34,6 +34,7 @@ struct snd_usb_audio {
 	unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
 	unsigned int tx_length_quirk:1; /* Put length specifier in transfers */
 	unsigned int setup_fmt_after_resume_quirk:1; /* setup the format to interface after resume */
+	unsigned int need_delayed_register:1; /* warn for delayed registration */
 	int num_interfaces;
 	int num_suspended_intf;
 	int sample_rate_read_error;
-- 
2.16.4


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

* [PATCH 4/4] ALSA: usb-audio: Update the documentation for the new delayed_register option
  2020-03-25 10:33 [PATCH 0/4] ALSA: usb-audio: Option for delayed registration Takashi Iwai
                   ` (2 preceding siblings ...)
  2020-03-25 10:33 ` [PATCH 3/4] ALSA: usb-audio: Inform devices that need delayed registration Takashi Iwai
@ 2020-03-25 10:33 ` Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2020-03-25 10:33 UTC (permalink / raw)
  To: alsa-devel

Just adding a brief explanation to alsa-configuration.rst.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 Documentation/sound/alsa-configuration.rst | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/Documentation/sound/alsa-configuration.rst b/Documentation/sound/alsa-configuration.rst
index 392875a1b94e..72f97d4b01a7 100644
--- a/Documentation/sound/alsa-configuration.rst
+++ b/Documentation/sound/alsa-configuration.rst
@@ -2234,6 +2234,19 @@ use_vmalloc
     buffers.  If mmap is used on such architectures, turn off this
     option, so that the DMA-coherent buffers are allocated and used
     instead.
+delayed_register
+    The option is needed for devices that have multiple streams
+    defined in multiple USB interfaces.  The driver may invoke
+    registrations multiple times (once per interface) and this may
+    lead to the insufficient device enumeration.
+    This option receives an array of strings, and you can pass
+    ID:INTERFACE like ``0123abcd:4`` for performing the delayed
+    registration to the given device.  In this example, when a USB
+    device 0123:abcd is probed, the driver waits the registration
+    until the USB interface 4 gets probed.
+    The driver prints a message like "Found post-registration device
+    assignment: 1234abcd:04" for such a device, so that user can
+    notice the need.
 
 This module supports multiple devices, autoprobe and hotplugging.
 
-- 
2.16.4


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

end of thread, other threads:[~2020-03-25 10:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-25 10:33 [PATCH 0/4] ALSA: usb-audio: Option for delayed registration Takashi Iwai
2020-03-25 10:33 ` [PATCH 1/4] ALSA: usb-audio: Rewrite registration quirk handling Takashi Iwai
2020-03-25 10:33 ` [PATCH 2/4] ALSA: usb-audio: Add delayed_register option Takashi Iwai
2020-03-25 10:33 ` [PATCH 3/4] ALSA: usb-audio: Inform devices that need delayed registration Takashi Iwai
2020-03-25 10:33 ` [PATCH 4/4] ALSA: usb-audio: Update the documentation for the new delayed_register option Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.