[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180129053755.20136-1-k.marinushkin@gmail.com>
Date: Mon, 29 Jan 2018 06:37:55 +0100
From: Kirill Marinushkin <k.marinushkin@...il.com>
To: perex@...ex.cz, tiwai@...e.com
Cc: Kirill Marinushkin <k.marinushkin@...il.com>,
Jaejoong Kim <climbbb.kim@...il.com>,
Bhumika Goyal <bhumirks@...il.com>,
Stephen Barber <smbarber@...omium.org>,
Julian Scheel <julian@...st.de>, alsa-devel@...a-project.org,
linux-kernel@...r.kernel.org
Subject: [PATCH] ALSA: usb-audio: Fix UAC2 get_ctl request with a RANGE attribute
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: 23caaf19b11e ("ALSA: usb-mixer: Add support for Audio Class v2.0")
Signed-off-by: Kirill Marinushkin <k.marinushkin@...il.com>
Cc: Jaroslav Kysela <perex@...ex.cz>
Cc: Takashi Iwai <tiwai@...e.com>
Cc: Jaejoong Kim <climbbb.kim@...il.com>
Cc: Bhumika Goyal <bhumirks@...il.com>
Cc: Stephen Barber <smbarber@...omium.org>
Cc: Julian Scheel <julian@...st.de>
Cc: alsa-devel@...a-project.org
Cc: linux-kernel@...r.kernel.org
---
sound/usb/mixer.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 2b4ceda36291..20b28a5a1456 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -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));
@@ -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;
}
--
2.13.6
Powered by blists - more mailing lists