OSDN Git Service

xhci: Refactor command watchdog and fix split string.
authorSarah Sharp <sarah.a.sharp@linux.intel.com>
Fri, 21 Feb 2014 17:27:30 +0000 (09:27 -0800)
committerSarah Sharp <sarah.a.sharp@linux.intel.com>
Tue, 4 Mar 2014 23:38:27 +0000 (15:38 -0800)
In preparation for fixing this function for streams endpoints, refactor
code in the command watchdog timeout function into two new functions.
One kills all URBs on a ring (either stream or endpoint), the other
kills all URBs associated with an endpoint.  Fix a split string while
we're at it.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
drivers/usb/host/xhci-ring.c

index b3d27e6..58cbc06 100644 (file)
@@ -900,6 +900,43 @@ remove_finished_td:
        /* Return to the event handler with xhci->lock re-acquired */
 }
 
+static void xhci_kill_ring_urbs(struct xhci_hcd *xhci, struct xhci_ring *ring)
+{
+       struct xhci_td *cur_td;
+
+       while (!list_empty(&ring->td_list)) {
+               cur_td = list_first_entry(&ring->td_list,
+                               struct xhci_td, td_list);
+               list_del_init(&cur_td->td_list);
+               if (!list_empty(&cur_td->cancelled_td_list))
+                       list_del_init(&cur_td->cancelled_td_list);
+               xhci_giveback_urb_in_irq(xhci, cur_td, -ESHUTDOWN);
+       }
+}
+
+static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci,
+               int slot_id, int ep_index)
+{
+       struct xhci_td *cur_td;
+       struct xhci_virt_ep *ep;
+       struct xhci_ring *ring;
+
+       ep = &xhci->devs[slot_id]->eps[ep_index];
+       ring = ep->ring;
+       if (!ring)
+               return;
+       xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
+                       "Killing URBs for slot ID %u, ep index %u",
+                       slot_id, ep_index);
+       xhci_kill_ring_urbs(xhci, ring);
+       while (!list_empty(&ep->cancelled_td_list)) {
+               cur_td = list_first_entry(&ep->cancelled_td_list,
+                               struct xhci_td, cancelled_td_list);
+               list_del_init(&cur_td->cancelled_td_list);
+               xhci_giveback_urb_in_irq(xhci, cur_td, -ESHUTDOWN);
+       }
+}
+
 /* Watchdog timer function for when a stop endpoint command fails to complete.
  * In this case, we assume the host controller is broken or dying or dead.  The
  * host may still be completing some other events, so we have to be careful to
@@ -923,9 +960,6 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
 {
        struct xhci_hcd *xhci;
        struct xhci_virt_ep *ep;
-       struct xhci_virt_ep *temp_ep;
-       struct xhci_ring *ring;
-       struct xhci_td *cur_td;
        int ret, i, j;
        unsigned long flags;
 
@@ -982,34 +1016,8 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
        for (i = 0; i < MAX_HC_SLOTS; i++) {
                if (!xhci->devs[i])
                        continue;
-               for (j = 0; j < 31; j++) {
-                       temp_ep = &xhci->devs[i]->eps[j];
-                       ring = temp_ep->ring;
-                       if (!ring)
-                               continue;
-                       xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
-                                       "Killing URBs for slot ID %u, "
-                                       "ep index %u", i, j);
-                       while (!list_empty(&ring->td_list)) {
-                               cur_td = list_first_entry(&ring->td_list,
-                                               struct xhci_td,
-                                               td_list);
-                               list_del_init(&cur_td->td_list);
-                               if (!list_empty(&cur_td->cancelled_td_list))
-                                       list_del_init(&cur_td->cancelled_td_list);
-                               xhci_giveback_urb_in_irq(xhci, cur_td,
-                                               -ESHUTDOWN);
-                       }
-                       while (!list_empty(&temp_ep->cancelled_td_list)) {
-                               cur_td = list_first_entry(
-                                               &temp_ep->cancelled_td_list,
-                                               struct xhci_td,
-                                               cancelled_td_list);
-                               list_del_init(&cur_td->cancelled_td_list);
-                               xhci_giveback_urb_in_irq(xhci, cur_td,
-                                               -ESHUTDOWN);
-                       }
-               }
+               for (j = 0; j < 31; j++)
+                       xhci_kill_endpoint_urbs(xhci, i, j);
        }
        spin_unlock_irqrestore(&xhci->lock, flags);
        xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,