Skip to content

Commit 8429841

Browse files
Michal Peciogregkh
authored andcommitted
usb: xhci: Make usb_host_endpoint.hcpriv survive endpoint_disable()
commit 25e531b upstream. xHCI hardware maintains its endpoint state between add_endpoint() and drop_endpoint() calls followed by successful check_bandwidth(). So does the driver. Core may call endpoint_disable() during xHCI endpoint life, so don't clear host_ep->hcpriv then, because this breaks endpoint_reset(). If a driver calls usb_set_interface(), submits URBs which make host sequence state non-zero and calls usb_clear_halt(), the device clears its sequence state but xhci_endpoint_reset() bails out. The next URB malfunctions: USB2 loses one packet, USB3 gets Transaction Error or may not complete at all on some (buggy?) HCs from ASMedia and AMD. This is triggered by uvcvideo on bulk video devices. The code was copied from ehci_endpoint_disable() but it isn't needed here - hcpriv should only be NULL on emulated root hub endpoints. It might prevent resetting and inadvertently enabling a disabled and dropped endpoint, but core shouldn't try to reset dropped endpoints. Document xhci requirements regarding hcpriv. They are currently met. Fixes: 18b7406 ("xhci: Fix use-after-free regression in xhci clear hub TT implementation") Cc: stable@vger.kernel.org Signed-off-by: Michal Pecio <michal.pecio@gmail.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://patch.msgid.link/20260402131342.2628648-26-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent d1905db commit 8429841

2 files changed

Lines changed: 2 additions & 2 deletions

File tree

drivers/usb/host/xhci.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3102,7 +3102,6 @@ static void xhci_endpoint_disable(struct usb_hcd *hcd,
31023102
xhci_dbg(xhci, "endpoint disable with ep_state 0x%x\n",
31033103
ep->ep_state);
31043104
done:
3105-
host_ep->hcpriv = NULL;
31063105
spin_unlock_irqrestore(&xhci->lock, flags);
31073106
}
31083107

include/linux/usb.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ struct ep_device;
5353
* @ssp_isoc_ep_comp: SuperSpeedPlus isoc companion descriptor for this endpoint
5454
* @urb_list: urbs queued to this endpoint; maintained by usbcore
5555
* @hcpriv: for use by HCD; typically holds hardware dma queue head (QH)
56-
* with one or more transfer descriptors (TDs) per urb
56+
* with one or more transfer descriptors (TDs) per urb; must be preserved
57+
* by core while BW is allocated for the endpoint
5758
* @ep_dev: ep_device for sysfs info
5859
* @extra: descriptors following this endpoint in the configuration
5960
* @extralen: how many bytes of "extra" are valid

0 commit comments

Comments
 (0)