Skip to content

Commit 21b224d

Browse files
matnymangregkh
authored andcommitted
xhci: rework xhci internal endpoint halt state detection.
When xhci_requires_manual_halt_cleanup() was written it wasn't clear that the xhci internal endpoint halt state always needs to be cleared with a reset endpoint command. Functional stall cases additionally halt the device side endpoint which requires class driver to clear the device side halt with a CLEAR_FEATURE(ENDPOINT_HALT) request as well. Clean up, rename, and make sure the new function always return true when internal endpoint state is halted, including stall cases. Based on related cleanup suggestion code by Niklas Neronin cc: Niklas Neronin <[email protected]> Signed-off-by: Mathias Nyman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent bde66d2 commit 21b224d

File tree

1 file changed

+29
-27
lines changed

1 file changed

+29
-27
lines changed

drivers/usb/host/xhci-ring.c

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2130,28 +2130,34 @@ static void xhci_clear_hub_tt_buffer(struct xhci_hcd *xhci, struct xhci_td *td,
21302130
}
21312131
}
21322132

2133-
/* Check if an error has halted the endpoint ring. The class driver will
2134-
* cleanup the halt for a non-default control endpoint if we indicate a stall.
2135-
* However, a babble and other errors also halt the endpoint ring, and the class
2136-
* driver won't clear the halt in that case, so we need to issue a Set Transfer
2137-
* Ring Dequeue Pointer command manually.
2133+
/*
2134+
* Check if xhci internal endpoint state has gone to a "halt" state due to an
2135+
* error or stall, including default control pipe protocol stall.
2136+
* The internal halt needs to be cleared with a reset endpoint command.
2137+
*
2138+
* External device side is also halted in functional stall cases. Class driver
2139+
* will clear the device halt with a CLEAR_FEATURE(ENDPOINT_HALT) request later.
21382140
*/
2139-
static int xhci_requires_manual_halt_cleanup(struct xhci_ep_ctx *ep_ctx, unsigned int trb_comp_code)
2141+
static bool xhci_halted_host_endpoint(struct xhci_ep_ctx *ep_ctx, unsigned int comp_code)
21402142
{
2141-
/* TRB completion codes that may require a manual halt cleanup */
2142-
if (trb_comp_code == COMP_USB_TRANSACTION_ERROR ||
2143-
trb_comp_code == COMP_BABBLE_DETECTED_ERROR ||
2144-
trb_comp_code == COMP_SPLIT_TRANSACTION_ERROR)
2145-
/* The 0.95 spec says a babbling control endpoint
2146-
* is not halted. The 0.96 spec says it is. Some HW
2147-
* claims to be 0.95 compliant, but it halts the control
2148-
* endpoint anyway. Check if a babble halted the
2149-
* endpoint.
2143+
/* Stall halts both internal and device side endpoint */
2144+
if (comp_code == COMP_STALL_ERROR)
2145+
return true;
2146+
2147+
/* TRB completion codes that may require internal halt cleanup */
2148+
if (comp_code == COMP_USB_TRANSACTION_ERROR ||
2149+
comp_code == COMP_BABBLE_DETECTED_ERROR ||
2150+
comp_code == COMP_SPLIT_TRANSACTION_ERROR)
2151+
/*
2152+
* The 0.95 spec says a babbling control endpoint is not halted.
2153+
* The 0.96 spec says it is. Some HW claims to be 0.95
2154+
* compliant, but it halts the control endpoint anyway.
2155+
* Check endpoint context if endpoint is halted.
21502156
*/
21512157
if (GET_EP_CTX_STATE(ep_ctx) == EP_STATE_HALTED)
2152-
return 1;
2158+
return true;
21532159

2154-
return 0;
2160+
return false;
21552161
}
21562162

21572163
int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code)
@@ -2321,7 +2327,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
23212327
case COMP_STOPPED_LENGTH_INVALID:
23222328
goto finish_td;
23232329
default:
2324-
if (!xhci_requires_manual_halt_cleanup(ep_ctx, trb_comp_code))
2330+
if (!xhci_halted_host_endpoint(ep_ctx, trb_comp_code))
23252331
break;
23262332
xhci_dbg(xhci, "TRB error %u, halted endpoint index = %u\n",
23272333
trb_comp_code, ep->ep_index);
@@ -2791,11 +2797,9 @@ static int handle_tx_event(struct xhci_hcd *xhci,
27912797
xhci_dbg(xhci, "td_list is empty while skip flag set. Clear skip flag for slot %u ep %u.\n",
27922798
slot_id, ep_index);
27932799
}
2794-
if (trb_comp_code == COMP_STALL_ERROR ||
2795-
xhci_requires_manual_halt_cleanup(ep_ctx, trb_comp_code)) {
2796-
xhci_handle_halted_endpoint(xhci, ep, NULL,
2797-
EP_HARD_RESET);
2798-
}
2800+
if (xhci_halted_host_endpoint(ep_ctx, trb_comp_code))
2801+
xhci_handle_halted_endpoint(xhci, ep, NULL, EP_HARD_RESET);
2802+
27992803
return 0;
28002804
}
28012805

@@ -2911,10 +2915,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
29112915
*/
29122916

29132917
if (trb_is_noop(ep_trb)) {
2914-
if (trb_comp_code == COMP_STALL_ERROR ||
2915-
xhci_requires_manual_halt_cleanup(ep_ctx, trb_comp_code))
2916-
xhci_handle_halted_endpoint(xhci, ep, td,
2917-
EP_HARD_RESET);
2918+
if (xhci_halted_host_endpoint(ep_ctx, trb_comp_code))
2919+
xhci_handle_halted_endpoint(xhci, ep, td, EP_HARD_RESET);
29182920
} else {
29192921
td->status = status;
29202922

0 commit comments

Comments
 (0)