Skip to content

Commit

Permalink
ALSA: usb-audio: Yet more regression for for the delayed card registr…
Browse files Browse the repository at this point in the history
…ation

Although we tried to fix the regression for the recent changes with
the delayed card registration, it doesn't seem covering the all
cases; e.g. on Roland EDIROL M-100FX, where the generic quirk for
Roland devices is applied, it misses the card registration because the
detection of the last interface (apparently for MIDI) fails.

This patch is an attempt to recover from those failures by calling the
card register also at the error path for the secondary interfaces.
The card register condition is also extended to match with the old
check in the previous patch, too (i.e. the simple check of the
interface number) for catching the probe with errors.

Fixes: 39efc9c ("ALSA: usb-audio: Fix last interface check for registration")
Cc: <stable@vger.kernel.org>
Link: https://bugzilla.suse.com/show_bug.cgi?id=1205111
Link: https://lore.kernel.org/r/20221108065824.14418-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Nov 8, 2022
1 parent 0c423e2 commit 971cb60
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions sound/usb/card.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,18 @@ get_alias_quirk(struct usb_device *dev, unsigned int id)
return NULL;
}

/* register card if we reach to the last interface or to the specified
* one given via option
*/
static int try_to_register_card(struct snd_usb_audio *chip, int ifnum)
{
if (check_delayed_register_option(chip) == ifnum ||
chip->last_iface == ifnum ||
usb_interface_claimed(usb_ifnum_to_if(chip->dev, chip->last_iface)))
return snd_card_register(chip->card);
return 0;
}

/*
* probe the active usb device
*
Expand Down Expand Up @@ -880,15 +892,9 @@ static int usb_audio_probe(struct usb_interface *intf,
chip->need_delayed_register = false; /* clear again */
}

/* register card if we reach to the last interface or to the specified
* one given via option
*/
if (check_delayed_register_option(chip) == ifnum ||
usb_interface_claimed(usb_ifnum_to_if(dev, chip->last_iface))) {
err = snd_card_register(chip->card);
if (err < 0)
goto __error;
}
err = try_to_register_card(chip, ifnum);
if (err < 0)
goto __error_no_register;

if (chip->quirk_flags & QUIRK_FLAG_SHARE_MEDIA_DEVICE) {
/* don't want to fail when snd_media_device_create() fails */
Expand All @@ -907,6 +913,11 @@ static int usb_audio_probe(struct usb_interface *intf,
return 0;

__error:
/* in the case of error in secondary interface, still try to register */
if (chip)
try_to_register_card(chip, ifnum);

__error_no_register:
if (chip) {
/* chip->active is inside the chip->card object,
* decrement before memory is possibly returned.
Expand Down

0 comments on commit 971cb60

Please sign in to comment.