diff options
Diffstat (limited to 'sound/usb/format.c')
| -rw-r--r-- | sound/usb/format.c | 20 | 
1 files changed, 20 insertions, 0 deletions
diff --git a/sound/usb/format.c b/sound/usb/format.c index ab5fed9f55b6..3b45d0ee7693 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -470,9 +470,11 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip,  					   int clock)  {  	struct usb_device *dev = chip->dev; +	struct usb_host_interface *alts;  	unsigned int *table;  	unsigned int nr_rates;  	int i, err; +	u32 bmControls;  	/* performing the rate verification may lead to unexpected USB bus  	 * 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,  	if (!(chip->quirk_flags & QUIRK_FLAG_VALIDATE_RATES))  		return 0; /* don't perform the validation as default */ +	alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting); +	if (!alts) +		return 0; + +	if (fp->protocol == UAC_VERSION_3) { +		struct uac3_as_header_descriptor *as = snd_usb_find_csint_desc( +				alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); +		bmControls = le32_to_cpu(as->bmControls); +	} else { +		struct uac2_as_header_descriptor *as = snd_usb_find_csint_desc( +				alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); +		bmControls = as->bmControls; +	} + +	if (!uac_v2v3_control_is_readable(bmControls, +				UAC2_AS_VAL_ALT_SETTINGS)) +		return 0; +  	table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL);  	if (!table)  		return -ENOMEM;  | 
