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

Michal Pecio
2026-04-22T05:31:02Z

On Tue, 21 Apr 2026 22:11:41 -0400, Alan Stern wrote:
> On Tue, Apr 07, 2026 at 11:24:01PM +0300, Mathias Nyman wrote:
> > On 4/7/26 18:23, Alan Stern wrote:
> > > It's been a while now, and nobody has objected to the proposed
> > > plan for handling this issue, so I'm going to assume that
> > > everyone is on board with the idea.
> >
> > Yes, I support this
> >
> > So basically usb core will call usb_clear_halt() after EPROTO URB
> > completion handler finishes, and xhci-hcd needs to prevent
> > bulk/interrupt endpoint from restarting after returning a EPROTO
> > URB up until usb_reset_endpoint() is called
>
> Can you confirm that it's also possible for xhci-hcd to prevent
> control endpoints from restarting when a transaction error (-EPROTO)
> occurs? Up until usb_reset_endpoint() or a new callback?

Doable. They halt like any other and it's SW's choice how to restart.

BTW, what about EOVERFLOW? It's treated similarly by xhci-hcd.

> I've been thinking about how to implement all this, and some issues
> have to be solved. In particular, suppose we have sent a Clear-Halt
> request for an endpoint that has gotten an error, and either the
> request times out or the device replies with a stall.

(... or the TT replies with STALL due to downstream bus EPROTO).

> My feeling is that either of these events would mean that the device
> is so far out of whack that the only thing to do is try resetting it.
> Any proposals for something a little less drastic?

Let's look at possible causes:

1. disconnected device
Doesn't matter what happens.

2. completely brain dead host controller
Ditto. Just be sure not to lock up so xhci-hcd can be reloaded.

3. temporary EMI or low link quality
This should clear itself after a few retries.

4. broken D+/D- wire in a LS/FS cable
Issues can last arbitrarily long and yet still clear.
Least disruptive solution: wait forever with sporadic retries.
Acceptable alternative: request user attention, i.e. disconnect.

Note: we would disconnect instantly if the opposite wire broke.

5. crashed device firmware
In this case a reset seems more productive than retrying forever.

A compromise betwen 4 and 5 could be to retry for some time, then
reset a few times, then disconnect.

6. device doesn't support clear-halt, stalls or does something odd

Nightmare fuel.

> Also, it seems reasonable to devote only a single thread to endpoint
> error recovery. Another possibility would be to have one thread for
> each device having problems, but I think the likelihood of this
> happening to multiple devices at once is pretty small unless the
> problem affects a hub upstream from all of them -- in which case
> having multiple threads wouldn't really help much. Other opinions?

Well, another option is asynchronous URBs and "callback hell". For
instance, besides hcd methods, all xhci-hcd endpoint management is
asynchronous, tracks current state with bit flags and defers actions
blocked by flags until the flags are cleared. This includes waiting
for Reset Endpoint commands, TT clearing, ongoing unlinks, etc.

One practical complication is that hcd->endpoint_reset() may sleep.
But it will only extremely rarely take 5 seconds and time out.

Regards,
Michal