aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorNikolay Yakimov <root@livid.pp.ru>2019-01-15 11:13:54 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-02-08 04:22:39 -0500
commit25b0161450363ed7fe9fe618cda202e15817311a (patch)
tree4864a2179683dadaebc03860c0922684456086ce /drivers/usb/core
parent4fdc1790e6a9ef22399c6bc6e63b80f4609f3b7e (diff)
USB: Fix configuration selection issues introduced in v4.20.0
Commit f13912d3f014a introduced changes to the usb_choose_configuration function to better support USB Audio UAC3-compatible devices. However, there are a few problems with this patch. First of all, it adds new "if" clauses in the middle of an existing "if"/"else if" tree, which obviously breaks pre-existing logic. Secondly, since it continues iterating over configurations in one of the branches, other code in the loop can choose an unintended configuration. Finally, if an audio device's first configuration is UAC3-compatible, and there are multiple UAC3 configurations, the second one would be chosen, due to the first configuration never being checked for UAC3-compatibility. Commit ff2a8c532c14 tries to fix the second issue, but it goes about it in a somewhat unnecessarily convoluted way, in my opinion, and does nothing to fix the first or the last one. This patch tries to rectify problems described by essentially rewriting code introduced in f13912d3f014a. Notice the code was moved to *before* the "if"/"else if" tree. Signed-off-by: Nikolay Yakimov <root@livid.pp.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/generic.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index f713cecc1f41..1ac9c1e5f773 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -118,6 +118,31 @@ int usb_choose_configuration(struct usb_device *udev)
118 continue; 118 continue;
119 } 119 }
120 120
121 /*
122 * Select first configuration as default for audio so that
123 * devices that don't comply with UAC3 protocol are supported.
124 * But, still iterate through other configurations and
125 * select UAC3 compliant config if present.
126 */
127 if (desc && is_audio(desc)) {
128 /* Always prefer the first found UAC3 config */
129 if (is_uac3_config(desc)) {
130 best = c;
131 break;
132 }
133
134 /* If there is no UAC3 config, prefer the first config */
135 else if (i == 0)
136 best = c;
137
138 /* Unconditional continue, because the rest of the code
139 * in the loop is irrelevant for audio devices, and
140 * because it can reassign best, which for audio devices
141 * we don't want.
142 */
143 continue;
144 }
145
121 /* When the first config's first interface is one of Microsoft's 146 /* When the first config's first interface is one of Microsoft's
122 * pet nonstandard Ethernet-over-USB protocols, ignore it unless 147 * pet nonstandard Ethernet-over-USB protocols, ignore it unless
123 * this kernel has enabled the necessary host side driver. 148 * this kernel has enabled the necessary host side driver.
@@ -132,25 +157,6 @@ int usb_choose_configuration(struct usb_device *udev)
132#endif 157#endif
133 } 158 }
134 159
135 /*
136 * Select first configuration as default for audio so that
137 * devices that don't comply with UAC3 protocol are supported.
138 * But, still iterate through other configurations and
139 * select UAC3 compliant config if present.
140 */
141 if (i == 0 && num_configs > 1 && desc && is_audio(desc)) {
142 best = c;
143 continue;
144 }
145
146 if (i > 0 && desc && is_audio(desc)) {
147 if (is_uac3_config(desc)) {
148 best = c;
149 break;
150 }
151 continue;
152 }
153
154 /* From the remaining configs, choose the first one whose 160 /* From the remaining configs, choose the first one whose
155 * first interface is for a non-vendor-specific class. 161 * first interface is for a non-vendor-specific class.
156 * Reason: Linux is more likely to have a class driver 162 * Reason: Linux is more likely to have a class driver