Commit 57dd5414 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: usb-audio: Limit retrying sample rate reads

There are many USB audio devices with buggy firmware that don't react
with the sample rate reading properly.  This often results in the
flood of error messages and slowing down the operation.

The sample rate read back is basically only for confirming the sample
rate setup, and it's not critically important.  As a compromise, in
this patch, we stop the sample rate read back once when the device
gives errors more than tolerance (twice, as of now).  This should
improve most of error cases while we still can catch the firmware
bugginess.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent a33d5959
...@@ -309,6 +309,9 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, ...@@ -309,6 +309,9 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
* support reading */ * support reading */
if (snd_usb_get_sample_rate_quirk(chip)) if (snd_usb_get_sample_rate_quirk(chip))
return 0; return 0;
/* the firmware is likely buggy, don't repeat to fail too many times */
if (chip->sample_rate_read_error > 2)
return 0;
if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
...@@ -316,6 +319,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, ...@@ -316,6 +319,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
data, sizeof(data))) < 0) { data, sizeof(data))) < 0) {
dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n", dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n",
iface, fmt->altsetting, ep); iface, fmt->altsetting, ep);
chip->sample_rate_read_error++;
return 0; /* some devices don't support reading */ return 0; /* some devices don't support reading */
} }
......
...@@ -50,6 +50,7 @@ struct snd_usb_audio { ...@@ -50,6 +50,7 @@ struct snd_usb_audio {
int num_interfaces; int num_interfaces;
int num_suspended_intf; int num_suspended_intf;
int sample_rate_read_error;
struct list_head pcm_list; /* list of pcm streams */ struct list_head pcm_list; /* list of pcm streams */
struct list_head ep_list; /* list of audio-related endpoints */ struct list_head ep_list; /* list of audio-related endpoints */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment