Commit e8bdb6bb authored by Daniel Mack's avatar Daniel Mack Committed by Takashi Iwai

ALSA: usb-audio: fix UAC2 control value queries

For RANGE requests, we should only query as much bytes as we're in fact
interested in.

For CUR requests, we shouldn't confuse the firmware with an overlong
request but just ask for 2 bytes.

This might need fixing in the future as it's not entirely clear when to
dispatch 1-byte, 2-byte and 4-byte request blocks. For now, we assume
everything is coded in 16bit - this works for all firmware
implementations I've seen.
Signed-off-by: default avatarDaniel Mack <daniel@caiaq.de>
Reported-by: default avatarAlex Lee <alexlee188@gmail.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 67c10366
...@@ -297,20 +297,27 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v ...@@ -297,20 +297,27 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
{ {
unsigned char buf[14]; /* enough space for one range of 4 bytes */ unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
unsigned char *val; unsigned char *val;
int ret; int ret, size;
__u8 bRequest; __u8 bRequest;
bRequest = (request == UAC_GET_CUR) ? if (request == UAC_GET_CUR) {
UAC2_CS_CUR : UAC2_CS_RANGE; bRequest = UAC2_CS_CUR;
size = sizeof(__u16);
} else {
bRequest = UAC2_CS_RANGE;
size = sizeof(buf);
}
memset(buf, 0, sizeof(buf));
ret = snd_usb_ctl_msg(cval->mixer->chip->dev, ret = snd_usb_ctl_msg(cval->mixer->chip->dev,
usb_rcvctrlpipe(cval->mixer->chip->dev, 0), usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
bRequest, bRequest,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
validx, cval->mixer->ctrlif | (cval->id << 8), validx, cval->mixer->ctrlif | (cval->id << 8),
buf, sizeof(buf), 1000); buf, size, 1000);
if (ret < 0) { if (ret < 0) {
snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
...@@ -318,6 +325,8 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v ...@@ -318,6 +325,8 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
return ret; return ret;
} }
/* FIXME: how should we handle multiple triplets here? */
switch (request) { switch (request) {
case UAC_GET_CUR: case UAC_GET_CUR:
val = buf; val = buf;
......
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