[PATCH 2/5] usb: xhci: reset_ep: wait for real completion, not the caller's timeout
Stephano Cetola <[email protected]>
| Newsgroups | org.infradead.lists.barebox |
|---|---|
| Message-ID | <[email protected]> |
reset_ep() recovers a halted endpoint by issuing a Reset Endpoint command followed by a Set TR Dequeue Pointer command, each followed by a wait for the command's completion event. It waited using the caller's timeout_ms. For an interrupt endpoint poll, timeout_ms is 0 (a non-blocking check for pending data). Passed through to reset_ep(), that same 0ms value gives the actual recovery commands almost no time to complete. xhci_wait_for_event() gives up immediately, reset_ep() returns before the halt is ever cleared, and the endpoint stays halted forever no matter how many times the caller retries. Recovering from a halt is a command completion wait, not a data transfer wait, and should not inherit the transfer's timeout. Signed-off-by: Stephano Cetola <[email protected]> --- drivers/usb/host/xhci-ring.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index bd38f0de91..0b11da88a2 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -506,7 +506,7 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected, * Send reset endpoint command for given endpoint. This recovers from a * halted endpoint (e.g. due to a stall error). */ -static void reset_ep(struct usb_device *udev, int ep_index, unsigned int timeout_ms) +static void reset_ep(struct usb_device *udev, int ep_index) { struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); struct xhci_ring *ring = ctrl->devs[udev->slot_id]->eps[ep_index].ring; @@ -517,7 +517,7 @@ static void reset_ep(struct usb_device *udev, int ep_index, unsigned int timeout dev_info(&udev->dev, "Resetting EP %d...\n", ep_index); xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_RESET_EP); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION, timeout_ms); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); if (!event) return; @@ -528,7 +528,7 @@ static void reset_ep(struct usb_device *udev, int ep_index, unsigned int timeout addr = xhci_trb_virt_to_dma(ring->enq_seg, (void *)((uintptr_t)ring->enqueue | ring->cycle_state)); xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION, timeout_ms); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); if (!event) return; @@ -706,7 +706,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, * have dealt with whatever caused the error. */ if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK) == EP_STATE_HALTED) - reset_ep(udev, ep_index, timeout_ms); + reset_ep(udev, ep_index); ring = virt_dev->eps[ep_index].ring; /* @@ -1055,7 +1055,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, dma_unmap_single(ctrl->host.hw_dev, map, length, direction); if (udev->status == USB_ST_STALLED) { - reset_ep(udev, ep_index, timeout_ms); + reset_ep(udev, ep_index); return -EPIPE; } -- 2.55.0