Re: [PATCH] usb: xhci: Make usb_host_endpoint.hcpriv survive endpoint_disable()
From: Mathias Nyman
Date: Wed Apr 01 2026 - 15:27:41 EST
On 4/1/26 17:52, Michal Pecio wrote:
On Wed, 1 Apr 2026 17:34:37 +0300, Mathias Nyman wrote:
On 3/31/26 02:06, Michal Pecio wrote:
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.
Were you able to trigger a usb_clear_halt() called with ep->hcpriv == NULL,
causing a toggle/seq mismatch?
The ep->hcpriv should be set back correctly in usb_set_interface():
usb_set_interface()
usb_hcd_alloc_bandwidth()
hcd->driver->add_endpoint()
xhci_add_endpoint()
ep->hcpriv = udev;
right, and later:
usb_disable_interface(dev, iface, true)
usb_disable_endpoint(dev, ..., true)
usb_hcd_disable_endpoint(dev, ep)
hcd->driver->endpoint_disable(hcd, ep)
usb_enable_interface(dev, iface, true)
usb_enable_endpoint(dev, ..., true)
usb_hcd_reset_endpoint(dev, ep)
hcd->driver->endpoint_reset(hcd, ep)
True, thanks, usb_set_interface() calls usb_disable_interface() twice.
First time just to flush pending URBs, second time with reset_hardware
flag set.
Adding patch to queue
-Mathias