Skip to content

Commit

Permalink
ALSA: usb-audio: Fix UAC2 get_ctl request with a RANGE attribute
Browse files Browse the repository at this point in the history
The layout of the UAC2 Control request and response varies depending on
the request type. With the current implementation, only the Layout 2
Parameter Block (with the 2-byte sized RANGE attribute) is handled
properly. For the Control requests with the 1-byte sized RANGE attribute
(Bass Control, Mid Control, Tremble Control), the response is parsed
incorrectly.

This commit:
* fixes the wLength field value in the request
* fixes parsing the range values from the response

Fixes: 23caaf1 ("ALSA: usb-mixer: Add support for Audio Class v2.0")
Signed-off-by: Kirill Marinushkin <k.marinushkin@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Kirill Marinushkin authored and Takashi Iwai committed Feb 12, 2018
1 parent 2bda714 commit 447cae5
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions sound/usb/mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,17 +347,20 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
int validx, int *value_ret)
{
struct snd_usb_audio *chip = cval->head.mixer->chip;
unsigned char buf[4 + 3 * sizeof(__u32)]; /* enough space for one range */
/* enough space for one range */
unsigned char buf[sizeof(__u16) + 3 * sizeof(__u32)];
unsigned char *val;
int idx = 0, ret, size;
int idx = 0, ret, val_size, size;
__u8 bRequest;

val_size = uac2_ctl_value_size(cval->val_type);

if (request == UAC_GET_CUR) {
bRequest = UAC2_CS_CUR;
size = uac2_ctl_value_size(cval->val_type);
size = val_size;
} else {
bRequest = UAC2_CS_RANGE;
size = sizeof(buf);
size = sizeof(__u16) + 3 * val_size;
}

memset(buf, 0, sizeof(buf));
Expand Down Expand Up @@ -390,16 +393,17 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
val = buf + sizeof(__u16);
break;
case UAC_GET_MAX:
val = buf + sizeof(__u16) * 2;
val = buf + sizeof(__u16) + val_size;
break;
case UAC_GET_RES:
val = buf + sizeof(__u16) * 3;
val = buf + sizeof(__u16) + val_size * 2;
break;
default:
return -EINVAL;
}

*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(val, sizeof(__u16)));
*value_ret = convert_signed_value(cval,
snd_usb_combine_bytes(val, val_size));

return 0;
}
Expand Down

0 comments on commit 447cae5

Please sign in to comment.