Re: [RFC PATCH 1/2] xhci: prevent automatic endpoint restart after stall or error

Michal Pecio
2026-04-18T09:21:53Z

On Fri, 17 Apr 2026 22:34:58 -0400, Alan Stern wrote:
> Okay, good, we'll require all HCDs to reset control endpoints
> automatically after every error and stall.

Are they not doing it?

Say that something like lsusb encounters protocol stall while another
URB from the class driver is pending, will the other URB time out just
because host endpoint halted on an earlier one?

> > Currently, by the time the URB is given back, its endpoint is
> > already in a "stopped but runnable" state and its sequence state is
> > zeroed. And it may have already been restarted if there are more
> > pending URBs.
>
> Ah, I was going to ask about that. This will be different from the
> way bulk and interrupt endpoints will behave, but I think it is
> acceptable. Control endpoints aren't used for anything that requires
> high throughput; if a driver wants an error to prevent later
> transfers from starting right away then it can simply avoid
> submitting those later transfers until the earlier ones have
> completed.

Or it could unlink if the async giveback race is fixed with a new
callback separate from endpoint_reset(), but IDK if any demand exists.

Same thing with "chain unlinking" - unlink one URB and expect others
not to execute so that unlink completion can unlink them later. Looks
odd, but it's guaranteed by kerneldocs. And currently broken.

> > > Recovery from a transaction error on a bulk or interrupt endpoint
> > > involves sending a Clear-Halt request to the device. But if the
> > > error was caused by some sort of transient interference that
> > > hasn't ended yet, the Clear-Halt might itself fail with the same
> > > error. To handle this, we should retry the Clear-Halt at
> > > increasing time intervals. At what point should the core give up?
> >
> > Good question, I don't know. One thing I noticed is that Windows
> > does tend to lose patience with completely unresponsive devices and
> > kicks them out, but I don't know the exact criteria.
>
> Two reasonable possibilities are 250 ms (because that's about how
> long an intermediate hub might take to notify the core about a
> disconnect) or 5 seconds (the normal timeout for control transfers).
> Of course, 5 seconds is an awfully long time to wait for a mouse or
> keyboard to recover, so maybe something in between would be best.

What happens after giving up? If control requests don't work, most
likely nothing works anyway. Reset may work, or not if it's bad cable.

Retrying too long may cause class drivers to time out on pending URBs,
not sure if it matters. Drivers may have no way to distinguish this
from any other timeout, not sure if this matters either.

> I will set things up so that an extraneous clear-halt (such as one
> submitted by the driver) will prevent the core from doing its own.
> This leaves the possibility of the core clearing the halt and
> restarting the endpoint and then the driver doing it again, while the
> endpoint is running and the queue is nonempty. Hopefully drivers
> avoid doing this.

Yes, that's just dodgy, what would such driver even expect to happen?
An URB may be in progress and then what? On xHCI we would need to throw
out this URB, so it simply isn't supported.

> But if it helps, I could print a warning if usb_clear_halt() is
> called for an endpoint that isn't stopped and has a nonempty queue.

Not sure what core considers a "stopped" endpoint. FYI, xhci-hcd
logs dev_err() when reset is attempted while URBs are running.

> > A related issue is clearing TT buffers. AFAIK this has no retries,
> > it fails silently and leaves the endpoint potentially broken, and
> > it is waited for to complete in case of usb_set_interface().
>
> Is there anything we can do besides calling usb_clear_halt() and
> usb_reset_endpoint()? If not, and data loss is unavoidable, then so
> be it.

If this "clear-halt by usbcore" materializes and survives confrotation
with the real world, it could make sense to look into combining TT
clearing with it. It's a similar thing, but tracked separately now.

One thing that could reduce data loss is never giving up on those
control requests, or resetting/disconnecting the device if giving up.
It's a general problem that control requests can fail and nobody has
much idea what to do then. Some drivers ignore errors. If the device
returns to operation, it may end up running in an unknown state.

This is apparently rare enough that nobody complains, though on
low- and full-speed it's relatively easy to produce artificially with
a particularly defective cable.

Regards,
Michal