| From 43ec1ac1fe7aaca3d3bfcf5d9c0a49eea70dd93d Mon Sep 17 00:00:00 2001 |
| From: Takashi Iwai <tiwai@suse.de> |
| Date: Tue, 11 Feb 2020 17:05:21 +0100 |
| Subject: [PATCH] ALSA: usb-audio: Fix UAC2/3 effect unit parsing |
| |
| commit d75a170fd848f037a1e28893ad10be7a4c51f8a6 upstream. |
| |
| We've got a regression report about M-Audio Fast Track C400 device, |
| and the git bisection resulted in the commit e0ccdef92653 ("ALSA: |
| usb-audio: Clean up check_input_term()"). This commit was about the |
| rewrite of the input terminal parser, and it's not too obvious from |
| the change what really broke. The answer is: it's the interpretation |
| of UAC2/3 effect units. |
| |
| In the original code, UAC2 effect unit is as if through UAC1 |
| processing unit because both UAC1 PU and UAC2/3 EU share the same |
| number (0x07). The old code went through a complex switch-case |
| fallthrough, finally bailing out in the middle: |
| |
| if (protocol == UAC_VERSION_2 && |
| hdr[2] == UAC2_EFFECT_UNIT) { |
| /* UAC2/UAC1 unit IDs overlap here in an |
| * uncompatible way. Ignore this unit for now. |
| */ |
| return 0; |
| } |
| |
| ... and this special handling was missing in the new code; the new |
| code treats UAC2/3 effect unit as if it were equivalent with the |
| processing unit. |
| |
| Actually, the old code was too confusing. The effect unit has an |
| incompatible unit description with the processing unit, so we |
| shouldn't have dealt with EU in the same way. |
| |
| This patch addresses the regression by changing the effect unit |
| handling to the own parser function. The own parser function makes |
| the clear distinct with PU, so it improves the readability, too. |
| |
| The EU parser just sets the type and the id like the old kernels. |
| Once when the proper effect unit support is added, we can revisit this |
| parser function, but for now, let's keep this simple setup as is. |
| |
| Fixes: e0ccdef92653 ("ALSA: usb-audio: Clean up check_input_term()") |
| Cc: <stable@vger.kernel.org> |
| BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=206147 |
| Link: https://lore.kernel.org/r/20200211160521.31990-1-tiwai@suse.de |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
| index bd1cffb2ab50..edae32da5b40 100644 |
| --- a/sound/usb/mixer.c |
| +++ b/sound/usb/mixer.c |
| @@ -897,6 +897,15 @@ static int parse_term_proc_unit(struct mixer_build *state, |
| return 0; |
| } |
| |
| +static int parse_term_effect_unit(struct mixer_build *state, |
| + struct usb_audio_term *term, |
| + void *p1, int id) |
| +{ |
| + term->type = UAC3_EFFECT_UNIT << 16; /* virtual type */ |
| + term->id = id; |
| + return 0; |
| +} |
| + |
| static int parse_term_uac2_clock_source(struct mixer_build *state, |
| struct usb_audio_term *term, |
| void *p1, int id) |
| @@ -981,8 +990,7 @@ static int __check_input_term(struct mixer_build *state, int id, |
| UAC3_PROCESSING_UNIT); |
| case PTYPE(UAC_VERSION_2, UAC2_EFFECT_UNIT): |
| case PTYPE(UAC_VERSION_3, UAC3_EFFECT_UNIT): |
| - return parse_term_proc_unit(state, term, p1, id, |
| - UAC3_EFFECT_UNIT); |
| + return parse_term_effect_unit(state, term, p1, id); |
| case PTYPE(UAC_VERSION_1, UAC1_EXTENSION_UNIT): |
| case PTYPE(UAC_VERSION_2, UAC2_EXTENSION_UNIT_V2): |
| case PTYPE(UAC_VERSION_3, UAC3_EXTENSION_UNIT): |
| -- |
| 2.7.4 |
| |