Skip to content

Commit ee27770

Browse files
puleglotgregkh
authored andcommitted
ALSA: usb-audio: Check presence of valid altsetting control
[ Upstream commit 346f59d ] Many devices with a single alternate setting do not have a Valid Alternate Setting Control and validation performed by validate_sample_rate_table_v2v3() doesn't work on them and is not really needed. So check the presense of control before sending altsetting validation requests. MOTU Microbook IIc is suffering the most without this check. It takes up to 40 seconds to bootup due to how slow it switches sampling rates: [ 2659.164824] usb 3-2: New USB device found, idVendor=07fd, idProduct=0004, bcdDevice= 0.60 [ 2659.164827] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 2659.164829] usb 3-2: Product: MicroBook IIc [ 2659.164830] usb 3-2: Manufacturer: MOTU [ 2659.166204] usb 3-2: Found last interface = 3 [ 2679.322298] usb 3-2: No valid sample rate available for 1:1, assuming a firmware bug [ 2679.322306] usb 3-2: 1:1: add audio endpoint 0x3 [ 2679.322321] usb 3-2: Creating new data endpoint #3 [ 2679.322552] usb 3-2: 1:1 Set sample rate 96000, clock 1 [ 2684.362250] usb 3-2: 2:1: cannot get freq (v2/v3): err -110 [ 2694.444700] usb 3-2: No valid sample rate available for 2:1, assuming a firmware bug [ 2694.444707] usb 3-2: 2:1: add audio endpoint 0x84 [ 2694.444721] usb 3-2: Creating new data endpoint #84 [ 2699.482103] usb 3-2: 2:1 Set sample rate 96000, clock 1 Signed-off-by: Alexander Tsoy <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 21857ee commit ee27770

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

sound/usb/format.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,9 +470,11 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip,
470470
int clock)
471471
{
472472
struct usb_device *dev = chip->dev;
473+
struct usb_host_interface *alts;
473474
unsigned int *table;
474475
unsigned int nr_rates;
475476
int i, err;
477+
u32 bmControls;
476478

477479
/* performing the rate verification may lead to unexpected USB bus
478480
* behavior afterwards by some unknown reason. Do this only for the
@@ -481,6 +483,24 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip,
481483
if (!(chip->quirk_flags & QUIRK_FLAG_VALIDATE_RATES))
482484
return 0; /* don't perform the validation as default */
483485

486+
alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting);
487+
if (!alts)
488+
return 0;
489+
490+
if (fp->protocol == UAC_VERSION_3) {
491+
struct uac3_as_header_descriptor *as = snd_usb_find_csint_desc(
492+
alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
493+
bmControls = le32_to_cpu(as->bmControls);
494+
} else {
495+
struct uac2_as_header_descriptor *as = snd_usb_find_csint_desc(
496+
alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
497+
bmControls = as->bmControls;
498+
}
499+
500+
if (!uac_v2v3_control_is_readable(bmControls,
501+
UAC2_AS_VAL_ALT_SETTINGS))
502+
return 0;
503+
484504
table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL);
485505
if (!table)
486506
return -ENOMEM;

0 commit comments

Comments
 (0)