]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
xhci: cleanup and refactor process_ctrl_td()
authorMathias Nyman <mathias.nyman@linux.intel.com>
Fri, 11 Nov 2016 13:13:16 +0000 (15:13 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Nov 2016 09:18:21 +0000 (10:18 +0100)
Refactor pricess_ctrl_tx() to make it more readable
No functional changes

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-ring.c

index ae3a02e83e30b334043e1df4c523b7336d19b074..65b11a3ba47621867e8dded2f412d4e7609b6ef0 100644 (file)
@@ -1932,6 +1932,8 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
        int ep_index;
        struct xhci_ep_ctx *ep_ctx;
        u32 trb_comp_code;
+       u32 remaining, requested;
+       bool on_data_stage;
 
        slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
        xdev = xhci->devs[slot_id];
@@ -1939,89 +1941,74 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
        ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer));
        ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
        trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
+       requested = td->urb->transfer_buffer_length;
+       remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+
+       /* not setup (dequeue), or status stage means we are at data stage */
+       on_data_stage = (event_trb != ep_ring->dequeue &&
+                        event_trb != td->last_trb);
 
        switch (trb_comp_code) {
        case COMP_SUCCESS:
-               if (event_trb == ep_ring->dequeue) {
-                       xhci_warn(xhci, "WARN: Success on ctrl setup TRB "
-                                       "without IOC set??\n");
-                       *status = -ESHUTDOWN;
-               } else if (event_trb != td->last_trb) {
-                       xhci_warn(xhci, "WARN: Success on ctrl data TRB "
-                                       "without IOC set??\n");
+               if (event_trb != td->last_trb) {
+                       xhci_warn(xhci, "WARN: Success on ctrl %s TRB without IOC set?\n",
+                                 on_data_stage ? "data" : "setup");
                        *status = -ESHUTDOWN;
-               } else {
-                       *status = 0;
+                       break;
                }
+               *status = 0;
                break;
        case COMP_SHORT_TX:
-                       *status = 0;
+               *status = 0;
                break;
        case COMP_STOP_SHORT:
-               if (event_trb == ep_ring->dequeue || event_trb == td->last_trb)
-                       xhci_warn(xhci, "WARN: Stopped Short Packet on ctrl setup or status TRB\n");
+               if (on_data_stage)
+                       td->urb->actual_length = remaining;
                else
-                       td->urb->actual_length =
-                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
-
-               return finish_td(xhci, td, event_trb, event, ep, status, false);
+                       xhci_warn(xhci, "WARN: Stopped Short Packet on ctrl setup or status TRB\n");
+               goto finish_td;
        case COMP_STOP:
-               /* Did we stop at data stage? */
-               if (event_trb != ep_ring->dequeue && event_trb != td->last_trb)
-                       td->urb->actual_length =
-                               td->urb->transfer_buffer_length -
-                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
-               /* fall through */
+               if (on_data_stage)
+                       td->urb->actual_length = requested - remaining;
+               goto finish_td;
        case COMP_STOP_INVAL:
-               return finish_td(xhci, td, event_trb, event, ep, status, false);
+               goto finish_td;
        default:
                if (!xhci_requires_manual_halt_cleanup(xhci,
-                                       ep_ctx, trb_comp_code))
+                                                      ep_ctx, trb_comp_code))
                        break;
-               xhci_dbg(xhci, "TRB error code %u, "
-                               "halted endpoint index = %u\n",
-                               trb_comp_code, ep_index);
+               xhci_dbg(xhci, "TRB error %u, halted endpoint index = %u\n",
+                        trb_comp_code, ep_index);
                /* else fall through */
        case COMP_STALL:
                /* Did we transfer part of the data (middle) phase? */
-               if (event_trb != ep_ring->dequeue &&
-                               event_trb != td->last_trb)
-                       td->urb->actual_length =
-                               td->urb->transfer_buffer_length -
-                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+               if (on_data_stage)
+                       td->urb->actual_length = requested - remaining;
                else if (!td->urb_length_set)
                        td->urb->actual_length = 0;
-
-               return finish_td(xhci, td, event_trb, event, ep, status, false);
+               goto finish_td;
        }
+
+       /* stopped at setup stage, no data transferred */
+       if (event_trb == ep_ring->dequeue)
+               goto finish_td;
+
        /*
-        * Did we transfer any data, despite the errors that might have
-        * happened?  I.e. did we get past the setup stage?
+        * if on data stage then update the actual_length of the URB and flag it
+        * as set, so it won't be overwritten in the event for the last TRB.
         */
-       if (event_trb != ep_ring->dequeue) {
-               /* The event was for the status stage */
-               if (event_trb == td->last_trb) {
-                       if (!td->urb_length_set) {
-                               td->urb->actual_length =
-                                       td->urb->transfer_buffer_length;
-                       }
-               } else {
-                       /*
-                        * Maybe the event was for the data stage? If so, update
-                        * already the actual_length of the URB and flag it as
-                        * set, so that it is not overwritten in the event for
-                        * the last TRB.
-                        */
-                       td->urb_length_set = true;
-                       td->urb->actual_length =
-                               td->urb->transfer_buffer_length -
-                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
-                       xhci_dbg(xhci, "Waiting for status "
-                                       "stage event\n");
-                       return 0;
-               }
+       if (on_data_stage) {
+               td->urb_length_set = true;
+               td->urb->actual_length = requested - remaining;
+               xhci_dbg(xhci, "Waiting for status stage event\n");
+               return 0;
        }
 
+       /* at status stage */
+       if (!td->urb_length_set)
+               td->urb->actual_length = requested;
+
+finish_td:
        return finish_td(xhci, td, event_trb, event, ep, status, false);
 }