ALSA: usb-audio: increase control transfer timeout

There are certain devices that are reportedly so slow that they need
more than 100 ms to handle control transfers.  Therefore, increase the
timeout in mixer(_quirks).c to 1000 ms.

The timeout parameter of snd_usb_ctl_msg() is now constant, so we can
drop it.

Reported-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Clemens Ladisch 2011-09-26 21:15:27 +02:00 коммит произвёл Takashi Iwai
Родитель 6b69a0e520
Коммит 17d900c4a1
8 изменённых файлов: 25 добавлений и 25 удалений

Просмотреть файл

@ -91,7 +91,7 @@ static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_i
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
UAC2_CX_CLOCK_SELECTOR << 8, UAC2_CX_CLOCK_SELECTOR << 8,
snd_usb_ctrl_intf(chip) | (selector_id << 8), snd_usb_ctrl_intf(chip) | (selector_id << 8),
&buf, sizeof(buf), 1000); &buf, sizeof(buf));
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -118,7 +118,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
UAC2_CS_CONTROL_CLOCK_VALID << 8, UAC2_CS_CONTROL_CLOCK_VALID << 8,
snd_usb_ctrl_intf(chip) | (source_id << 8), snd_usb_ctrl_intf(chip) | (source_id << 8),
&data, sizeof(data), 1000); &data, sizeof(data));
if (err < 0) { if (err < 0) {
snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n",
@ -222,7 +222,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
data, sizeof(data), 1000)) < 0) { data, sizeof(data))) < 0) {
snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
dev->devnum, iface, fmt->altsetting, rate, ep); dev->devnum, iface, fmt->altsetting, rate, ep);
return err; return err;
@ -231,7 +231,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
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,
UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
data, sizeof(data), 1000)) < 0) { data, sizeof(data))) < 0) {
snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
dev->devnum, iface, fmt->altsetting, ep); dev->devnum, iface, fmt->altsetting, ep);
return 0; /* some devices don't support reading */ return 0; /* some devices don't support reading */
@ -273,7 +273,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
UAC2_CS_CONTROL_SAM_FREQ << 8, UAC2_CS_CONTROL_SAM_FREQ << 8,
snd_usb_ctrl_intf(chip) | (clock << 8), snd_usb_ctrl_intf(chip) | (clock << 8),
data, sizeof(data), 1000)) < 0) { data, sizeof(data))) < 0) {
snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
dev->devnum, iface, fmt->altsetting, rate); dev->devnum, iface, fmt->altsetting, rate);
return err; return err;
@ -283,7 +283,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
UAC2_CS_CONTROL_SAM_FREQ << 8, UAC2_CS_CONTROL_SAM_FREQ << 8,
snd_usb_ctrl_intf(chip) | (clock << 8), snd_usb_ctrl_intf(chip) | (clock << 8),
data, sizeof(data), 1000)) < 0) { data, sizeof(data))) < 0) {
snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
dev->devnum, iface, fmt->altsetting); dev->devnum, iface, fmt->altsetting);
return err; return err;

Просмотреть файл

@ -286,7 +286,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
UAC2_CS_CONTROL_SAM_FREQ << 8, UAC2_CS_CONTROL_SAM_FREQ << 8,
snd_usb_ctrl_intf(chip) | (clock << 8), snd_usb_ctrl_intf(chip) | (clock << 8),
tmp, sizeof(tmp), 1000); tmp, sizeof(tmp));
if (ret < 0) { if (ret < 0) {
snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n", snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n",
@ -307,7 +307,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
UAC2_CS_CONTROL_SAM_FREQ << 8, UAC2_CS_CONTROL_SAM_FREQ << 8,
snd_usb_ctrl_intf(chip) | (clock << 8), snd_usb_ctrl_intf(chip) | (clock << 8),
data, data_size, 1000); data, data_size);
if (ret < 0) { if (ret < 0) {
snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n", snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n",

Просмотреть файл

@ -81,7 +81,7 @@ void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype
*/ */
int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
__u8 requesttype, __u16 value, __u16 index, void *data, __u8 requesttype, __u16 value, __u16 index, void *data,
__u16 size, int timeout) __u16 size)
{ {
int err; int err;
void *buf = NULL; void *buf = NULL;
@ -92,7 +92,7 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
return -ENOMEM; return -ENOMEM;
} }
err = usb_control_msg(dev, pipe, request, requesttype, err = usb_control_msg(dev, pipe, request, requesttype,
value, index, buf, size, timeout); value, index, buf, size, 1000);
if (size > 0) { if (size > 0) {
memcpy(data, buf, size); memcpy(data, buf, size);
kfree(buf); kfree(buf);

Просмотреть файл

@ -8,7 +8,7 @@ void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsub
int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
__u8 request, __u8 requesttype, __u16 value, __u16 index, __u8 request, __u8 requesttype, __u16 value, __u16 index,
void *data, __u16 size, int timeout); void *data, __u16 size);
unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
struct usb_host_interface *alts); struct usb_host_interface *alts);

Просмотреть файл

@ -296,7 +296,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
buf, val_len, 100) >= val_len) { buf, val_len) >= val_len) {
*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
snd_usb_autosuspend(cval->mixer->chip); snd_usb_autosuspend(cval->mixer->chip);
return 0; return 0;
@ -333,7 +333,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
buf, size, 1000); buf, size);
snd_usb_autosuspend(chip); snd_usb_autosuspend(chip);
if (ret < 0) { if (ret < 0) {
@ -445,7 +445,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
usb_sndctrlpipe(chip->dev, 0), request, usb_sndctrlpipe(chip->dev, 0), request,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
buf, val_len, 100) >= 0) { buf, val_len) >= 0) {
snd_usb_autosuspend(chip); snd_usb_autosuspend(chip);
return 0; return 0;
} }

Просмотреть файл

@ -190,18 +190,18 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
err = snd_usb_ctl_msg(mixer->chip->dev, err = snd_usb_ctl_msg(mixer->chip->dev,
usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
!value, 0, NULL, 0, 100); !value, 0, NULL, 0);
/* USB X-Fi S51 Pro */ /* USB X-Fi S51 Pro */
if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
err = snd_usb_ctl_msg(mixer->chip->dev, err = snd_usb_ctl_msg(mixer->chip->dev,
usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
!value, 0, NULL, 0, 100); !value, 0, NULL, 0);
else else
err = snd_usb_ctl_msg(mixer->chip->dev, err = snd_usb_ctl_msg(mixer->chip->dev,
usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
value, index + 2, NULL, 0, 100); value, index + 2, NULL, 0);
if (err < 0) if (err < 0)
return err; return err;
mixer->audigy2nx_leds[index] = value; mixer->audigy2nx_leds[index] = value;
@ -299,7 +299,7 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
usb_rcvctrlpipe(mixer->chip->dev, 0), usb_rcvctrlpipe(mixer->chip->dev, 0),
UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
USB_RECIP_INTERFACE, 0, USB_RECIP_INTERFACE, 0,
jacks[i].unitid << 8, buf, 3, 100); jacks[i].unitid << 8, buf, 3);
if (err == 3 && (buf[0] == 3 || buf[0] == 6)) if (err == 3 && (buf[0] == 3 || buf[0] == 6))
snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
else else
@ -332,7 +332,7 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
err = snd_usb_ctl_msg(mixer->chip->dev, err = snd_usb_ctl_msg(mixer->chip->dev,
usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
50, 0, &new_status, 1, 100); 50, 0, &new_status, 1);
if (err < 0) if (err < 0)
return err; return err;
mixer->xonar_u1_status = new_status; mixer->xonar_u1_status = new_status;

Просмотреть файл

@ -152,7 +152,7 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep,
data, sizeof(data), 1000)) < 0) { data, sizeof(data))) < 0) {
snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
dev->devnum, iface, ep); dev->devnum, iface, ep);
return err; return err;
@ -176,7 +176,7 @@ static int init_pitch_v2(struct snd_usb_audio *chip, int iface,
if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
UAC2_EP_CS_PITCH << 8, 0, UAC2_EP_CS_PITCH << 8, 0,
data, sizeof(data), 1000)) < 0) { data, sizeof(data))) < 0) {
snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n", snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n",
dev->devnum, iface, fmt->altsetting); dev->devnum, iface, fmt->altsetting);
return err; return err;

Просмотреть файл

@ -340,7 +340,7 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac
snd_printdd("sending Extigy boot sequence...\n"); snd_printdd("sending Extigy boot sequence...\n");
/* Send message to force it to reconnect with full interface. */ /* Send message to force it to reconnect with full interface. */
err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0), err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000); 0x10, 0x43, 0x0001, 0x000a, NULL, 0);
if (err < 0) snd_printdd("error sending boot message: %d\n", err); if (err < 0) snd_printdd("error sending boot message: %d\n", err);
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
&dev->descriptor, sizeof(dev->descriptor)); &dev->descriptor, sizeof(dev->descriptor));
@ -361,11 +361,11 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a, snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
0, 0, &buf, 1, 1000); 0, 0, &buf, 1);
if (buf == 0) { if (buf == 0) {
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29, snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1, 2000, NULL, 0, 1000); 1, 2000, NULL, 0);
return -ENODEV; return -ENODEV;
} }
return 0; return 0;
@ -408,7 +408,7 @@ static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 valu
buf[3] = reg; buf[3] = reg;
return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
0, 0, &buf, 4, 1000); 0, 0, &buf, 4);
} }
static int snd_usb_cm106_boot_quirk(struct usb_device *dev) static int snd_usb_cm106_boot_quirk(struct usb_device *dev)