Skip to content

Commit 8dae4ba

Browse files
author
Desnes Nunes
committed
usb: Flush altsetting 0 endpoints before reinitializating them after reset.
JIRA: https://issues.redhat.com/browse/RHEL-116016 commit 89bb3dc Author: Mathias Nyman <mathias.nyman@linux.intel.com> Date: Wed, 14 May 2025 16:25:20 +0300 usb core avoids sending a Set-Interface altsetting 0 request after device reset, and instead relies on calling usb_disable_interface() and usb_enable_interface() to flush and reset host-side of those endpoints. xHCI hosts allocate and set up endpoint ring buffers and host_ep->hcpriv during usb_hcd_alloc_bandwidth() callback, which in this case is called before flushing the endpoint in usb_disable_interface(). Call usb_disable_interface() before usb_hcd_alloc_bandwidth() to ensure URBs are flushed before new ring buffers for the endpoints are allocated. Otherwise host driver will attempt to find and remove old stale URBs from a freshly allocated new ringbuffer. Cc: stable <stable@kernel.org> Fixes: 4fe0387 ("USB: don't send Set-Interface after reset") Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20250514132520.225345-1-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Desnes Nunes <desnesn@redhat.com>
1 parent 1e575db commit 8dae4ba

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

drivers/usb/core/hub.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6172,6 +6172,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
61726172
struct usb_hub *parent_hub;
61736173
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
61746174
struct usb_device_descriptor descriptor;
6175+
struct usb_interface *intf;
61756176
struct usb_host_bos *bos;
61766177
int i, j, ret = 0;
61776178
int port1 = udev->portnum;
@@ -6229,6 +6230,18 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
62296230
if (!udev->actconfig)
62306231
goto done;
62316232

6233+
/*
6234+
* Some devices can't handle setting default altsetting 0 with a
6235+
* Set-Interface request. Disable host-side endpoints of those
6236+
* interfaces here. Enable and reset them back after host has set
6237+
* its internal endpoint structures during usb_hcd_alloc_bandwith()
6238+
*/
6239+
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
6240+
intf = udev->actconfig->interface[i];
6241+
if (intf->cur_altsetting->desc.bAlternateSetting == 0)
6242+
usb_disable_interface(udev, intf, true);
6243+
}
6244+
62326245
mutex_lock(hcd->bandwidth_mutex);
62336246
ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL);
62346247
if (ret < 0) {
@@ -6260,12 +6273,11 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
62606273
*/
62616274
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
62626275
struct usb_host_config *config = udev->actconfig;
6263-
struct usb_interface *intf = config->interface[i];
62646276
struct usb_interface_descriptor *desc;
62656277

6278+
intf = config->interface[i];
62666279
desc = &intf->cur_altsetting->desc;
62676280
if (desc->bAlternateSetting == 0) {
6268-
usb_disable_interface(udev, intf, true);
62696281
usb_enable_interface(udev, intf, true);
62706282
ret = 0;
62716283
} else {

0 commit comments

Comments
 (0)