]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: xhci: move untargeted transfer event handling to a separate function
authorNiklas Neronin <niklas.neronin@linux.intel.com>
Wed, 26 Jun 2024 12:48:25 +0000 (15:48 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jun 2024 14:08:05 +0000 (16:08 +0200)
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>
drivers/usb/host/xhci-ring.c

index 8502776d84d6e0077314ec93b3dc1c1ddd2ca753..7f40be2a3885eb11bd72159a04b2002e6c0ce003 100644 (file)
@@ -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)