diff options
author | Niklas Neronin <niklas.neronin@linux.intel.com> | 2024-06-26 15:48:25 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-06-27 17:08:05 +0300 |
commit | 2acd0c22232d7681bc5ae993ca586affed083506 (patch) | |
tree | 8ab8eb8f39b952f305a7ea3c78ec97f9454a5cea /drivers/usb/host | |
parent | bbdd82c752d6e5fc8465092467e13d1c2961c1dd (diff) | |
download | linux-2acd0c22232d7681bc5ae993ca586affed083506.tar.xz |
usb: xhci: move untargeted transfer event handling to a separate function
Move handling transfer events without a target transfer TRB into
handle_transferless_tx_event(), this type of event does not utilize the
rest of handle_tx_event() and as a result it's better to separate it
into a dedicated function.
Additionally, this change reduces handle_tx_event()'s size and makes it
more readable.
[Mathias: Simplify code to return helper function value directly. This
removes the second xhci_err() message for untargeted and unexpected
event completion types]
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20240626124835.1023046-12-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 56 |
1 files changed, 29 insertions, 27 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 8502776d84d6..7f40be2a3885 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2562,6 +2562,33 @@ finish_td: return finish_td(xhci, ep, ep_ring, td, trb_comp_code); } +/* Transfer events which don't point to a transfer TRB, see xhci 4.17.4 */ +static int handle_transferless_tx_event(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, + u32 trb_comp_code) +{ + switch (trb_comp_code) { + case COMP_STALL_ERROR: + case COMP_USB_TRANSACTION_ERROR: + case COMP_INVALID_STREAM_TYPE_ERROR: + case COMP_INVALID_STREAM_ID_ERROR: + xhci_dbg(xhci, "Stream transaction error ep %u no id\n", ep->ep_index); + if (ep->err_count++ > MAX_SOFT_RETRY) + xhci_handle_halted_endpoint(xhci, ep, NULL, EP_HARD_RESET); + else + xhci_handle_halted_endpoint(xhci, ep, NULL, EP_SOFT_RESET); + break; + case COMP_RING_UNDERRUN: + case COMP_RING_OVERRUN: + case COMP_STOPPED_LENGTH_INVALID: + break; + default: + xhci_err(xhci, "ERROR Transfer event for unknown stream ring slot %u ep %u\n", + ep->vdev->slot_id, ep->ep_index); + return -ENODEV; + } + return 0; +} + /* * If this function returns an error condition, it means it got a Transfer * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address. @@ -2605,33 +2632,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, goto err_out; } - /* Some transfer events don't always point to a trb, see xhci 4.17.4 */ - if (!ep_ring) { - switch (trb_comp_code) { - case COMP_STALL_ERROR: - case COMP_USB_TRANSACTION_ERROR: - case COMP_INVALID_STREAM_TYPE_ERROR: - case COMP_INVALID_STREAM_ID_ERROR: - xhci_dbg(xhci, "Stream transaction error ep %u no id\n", - ep_index); - if (ep->err_count++ > MAX_SOFT_RETRY) - xhci_handle_halted_endpoint(xhci, ep, NULL, - EP_HARD_RESET); - else - xhci_handle_halted_endpoint(xhci, ep, NULL, - EP_SOFT_RESET); - break; - case COMP_RING_UNDERRUN: - case COMP_RING_OVERRUN: - case COMP_STOPPED_LENGTH_INVALID: - break; - default: - xhci_err(xhci, "ERROR Transfer event for unknown stream ring slot %u ep %u\n", - slot_id, ep_index); - goto err_out; - } - return 0; - } + if (!ep_ring) + return handle_transferless_tx_event(xhci, ep, trb_comp_code); /* Count current td numbers if ep->skip is set */ if (ep->skip) |