소스 검색

xhci: Refactor command watchdog and fix split string.

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>
Sarah Sharp 11 년 전
부모
커밋
50e8725e7c
1개의 변경된 파일39개의 추가작업 그리고 31개의 파일을 삭제
  1. 39 31
      drivers/usb/host/xhci-ring.c

+ 39 - 31
drivers/usb/host/xhci-ring.c

@@ -900,6 +900,43 @@ remove_finished_td:
 	/* Return to the event handler with xhci->lock re-acquired */
 	/* 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.
 /* 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
  * 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
  * 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_hcd *xhci;
 	struct xhci_virt_ep *ep;
 	struct xhci_virt_ep *ep;
-	struct xhci_virt_ep *temp_ep;
-	struct xhci_ring *ring;
-	struct xhci_td *cur_td;
 	int ret, i, j;
 	int ret, i, j;
 	unsigned long flags;
 	unsigned long flags;
 
 
@@ -982,34 +1016,8 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
 	for (i = 0; i < MAX_HC_SLOTS; i++) {
 	for (i = 0; i < MAX_HC_SLOTS; i++) {
 		if (!xhci->devs[i])
 		if (!xhci->devs[i])
 			continue;
 			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);
 	spin_unlock_irqrestore(&xhci->lock, flags);
 	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
 	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,