[PATCH 1/2] ALSA: core: Add snd_device_get_state() helper
A new small helper to get the current state of the device registration for the given object. It'll be used for USB-audio driver to check the delayed device registrations.
Signed-off-by: Takashi Iwai tiwai@suse.de --- include/sound/core.h | 1 + sound/core/device.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+)
diff --git a/include/sound/core.h b/include/sound/core.h index ac8b692b69b4..381a010a1bd4 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -266,6 +266,7 @@ void snd_device_disconnect(struct snd_card *card, void *device_data); void snd_device_disconnect_all(struct snd_card *card); void snd_device_free(struct snd_card *card, void *device_data); void snd_device_free_all(struct snd_card *card); +int snd_device_get_state(struct snd_card *card, void *device_data);
/* isadma.c */
diff --git a/sound/core/device.c b/sound/core/device.c index cdc5af526739..bf0b04a7ee79 100644 --- a/sound/core/device.c +++ b/sound/core/device.c @@ -237,3 +237,24 @@ void snd_device_free_all(struct snd_card *card) list_for_each_entry_safe_reverse(dev, next, &card->devices, list) __snd_device_free(dev); } + +/** + * snd_device_get_state - Get the current state of the given device + * @card: the card instance + * @device_data: the data pointer to release + * + * Returns the current state of the given device object. For the valid + * device, either @SNDRV_DEV_BUILD, @SNDRV_DEV_REGISTERED or + * @SNDRV_DEV_DISCONNECTED is returned. + * Or for a non-existing device, -1 is returned as an error. + */ +int snd_device_get_state(struct snd_card *card, void *device_data) +{ + struct snd_device *dev; + + dev = look_for_dev(card, device_data); + if (dev) + return dev->state; + return -1; +} +EXPORT_SYMBOL_GPL(snd_device_get_state);
USB-audio driver registers the card and its devices at each probe of USB interface, while trying to append a USB substream into the empty PCM stream slot. This works for most cases where the all PCM streams are declared in the single interface description. However, when the device provides multiple individual interfaces, this may up with pushing a new stream into the existing snd_pcm object that has been already registered. From the driver perspective, it's OK, but it doesn't work for PulseAudio and others because they manage in the card registration level, hence they'll miss this new device creation.
This patch tries to warn such a too-late-appended stream, and also tries to put rather into a new snd_pcm object.
If we get a report from a user about this, we may add it to an entry for snd_usb_registration_quirk().
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/usb/stream.c | 9 +++++++++ sound/usb/usbaudio.h | 1 + 2 files changed, 10 insertions(+)
diff --git a/sound/usb/stream.c b/sound/usb/stream.c index afd5aa574611..6c758af069e6 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -502,6 +502,15 @@ 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) { + if (!chip->pcm_devs_warned) { + usb_audio_warn(chip, "PCM stream already registered\n"); + usb_audio_warn(chip, "Please report to upstream for assigning the delayed card registration\n"); + chip->pcm_devs_warned = true; + } + continue; + } 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..b2b693eeca91 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 pcm_devs_warned:1; /* warned for delayed PCM registrations */ int num_interfaces; int num_suspended_intf; int sample_rate_read_error;
On Mon, 23 Mar 2020 18:06:43 +0100, Takashi Iwai wrote:
USB-audio driver registers the card and its devices at each probe of USB interface, while trying to append a USB substream into the empty PCM stream slot. This works for most cases where the all PCM streams are declared in the single interface description. However, when the device provides multiple individual interfaces, this may up with pushing a new stream into the existing snd_pcm object that has been already registered. From the driver perspective, it's OK, but it doesn't work for PulseAudio and others because they manage in the card registration level, hence they'll miss this new device creation.
This patch tries to warn such a too-late-appended stream, and also tries to put rather into a new snd_pcm object.
If we get a report from a user about this, we may add it to an entry for snd_usb_registration_quirk().
Signed-off-by: Takashi Iwai tiwai@suse.de
Let's scratch this. It's better to be put together with a generic module option that allows specifying the delayed registration for the given device, and show the warning at the time of snd_card_register() call instead.
Will respin the improved version later.
Takashi
participants (1)
-
Takashi Iwai