mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
UPSTREAM: xhci: handle stop endpoint command completion with endpoint in running state.
Handle race where a stop endpoint command fails with "context state error"
as hardware hasn't actually started the ring yet after a previous urb
cancellation completed and restarted the endpoint.
Flushing the doorbell write that restart the endpoint reduced these cases,
but didn't completely resolve them.
Check if the ring is running in the stop endpoint completion handler, and
issue a new stop endpoint command in this case.
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20210129130044.206855-24-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 1174d44906
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-linus)
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: Ie8db9628fd6ccaa07886ec33a89a1ad5872054e1
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
905cf93f89
commit
d4e086141f
@@ -983,6 +983,7 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
|
||||
struct xhci_ep_ctx *ep_ctx;
|
||||
struct xhci_td *td = NULL;
|
||||
enum xhci_ep_reset_type reset_type;
|
||||
struct xhci_command *command;
|
||||
|
||||
if (unlikely(TRB_TO_SUSPEND_PORT(le32_to_cpu(trb->generic.field[3])))) {
|
||||
if (!xhci->devs[slot_id])
|
||||
@@ -1029,6 +1030,18 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
|
||||
/* reset ep, reset handler cleans up cancelled tds */
|
||||
xhci_handle_halted_endpoint(xhci, ep, 0, td, reset_type);
|
||||
xhci_stop_watchdog_timer_in_irq(xhci, ep);
|
||||
return;
|
||||
case EP_STATE_RUNNING:
|
||||
/* Race, HW handled stop ep cmd before ep was running */
|
||||
command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
|
||||
if (!command)
|
||||
xhci_stop_watchdog_timer_in_irq(xhci, ep);
|
||||
|
||||
mod_timer(&ep->stop_cmd_timer,
|
||||
jiffies + XHCI_STOP_EP_CMD_TIMEOUT * HZ);
|
||||
xhci_queue_stop_endpoint(xhci, command, slot_id, ep_index, 0);
|
||||
xhci_ring_cmd_db(xhci);
|
||||
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user