On Mon, Aug 31, 2020 at 02:46:49PM +0300, Mathias Nyman wrote:
Userspace drivers that use a SetConfiguration() request to "lightweight" reset a already configured usb device might cause data toggles to get out of sync between the device and host, and the device becomes unusable.
The xHCI host requires endpoints to be dropped and added back to reset the toggle. USB core avoids these otherwise extra steps if the current active configuration is the same as the new requested configuration.
You should mention usb_reset_configuration() here. After all, that's where most of the changes in this patch occur.
A SetConfiguration() request will reset the device side data toggles. Make sure usb core drops and adds back the endpoints in this case.
To avoid code duplication split the current usb_disable_device() function and reuse the endpoint specific part.
Cc: stable stable@vger.kernel.org Tested-by: Martin Thierer mthierer@gmail.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com
@@ -1589,8 +1579,12 @@ int usb_reset_configuration(struct usb_device *dev) USB_REQ_SET_CONFIGURATION, 0, config->desc.bConfigurationValue, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
- if (retval < 0)
goto reset_old_alts;
- if (retval < 0) {
retval = usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
usb_enable_lpm(dev);
mutex_unlock(hcd->bandwidth_mutex);
return retval;
That's not right; we want to return the original error code. Not 0, which usb_hcd_alloc_bandwidth() will probably give us. Just remove the "retval =" from the call above.
Alan Stern