[PATCH 5/5] usb: xhci: wait a real interval for interrupt endpoint transfers
Stephano Cetola <[email protected]>
| Newsgroups | org.infradead.lists.barebox |
|---|---|
| Message-ID | <[email protected]> |
_xhci_submit_int_msg() ignored its interval parameter and always waited 0ms for the transfer to complete. With a 0ms wait, xhci_wait_for_event() does essentially a single instant check of the event ring and gives up if nothing is pending yet, then abort_td() cancels the just-queued transfer. The xHC polls the device autonomously at the endpoint's bInterval once a TRB is queued and the doorbell is rung, entirely in hardware, independent of how long the driver waits. A 0ms wait cancels that transfer before the hardware's own polling cycle ever gets a chance to complete, even when the device has real data ready to send. Every call would time out regardless of actual device state. Because abort_td()'s own cleanup commands wait on a real timeout, five seconds, not the caller's zero, the aborted transfer is often still racing the hardware's actual response when the driver moves on. Some polls still pick up real data by accident. The result reads as intermittent. A keypress sometimes registers and sometimes doesn't, rather than a clean, consistent failure. Signed-off-by: Stephano Cetola <[email protected]> --- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 27d4353597..661dc0dde0 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1110,7 +1110,7 @@ static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, * (at most) one TD. A TD (comprised of sg list entries) can * take several service intervals to transmit. */ - return xhci_bulk_tx(udev, pipe, length, buffer, 0); + return xhci_bulk_tx(udev, pipe, length, buffer, interval); } /** -- 2.55.0