aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorMatt Evans <matt@ozlabs.org>2011-03-28 22:41:02 -0400
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2011-05-02 19:42:50 -0400
commit9dee9a213cb90fdc13118ab221f65c9fa6944f7a (patch)
tree4f47812a37cef571cf6870f717b7ac68788040b1 /drivers/usb/host
parent7ed603ecf8b68ab81f4c83097d3063d43ec73bb8 (diff)
xhci: Remove recursive call to xhci_handle_event
Make the caller loop while there are events to handle, instead. Signed-off-by: Matt Evans <matt@ozlabs.org> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci-ring.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index e0f05f5abe10..73f8db0ecc4b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2171,8 +2171,10 @@ cleanup:
2171/* 2171/*
2172 * This function handles all OS-owned events on the event ring. It may drop 2172 * This function handles all OS-owned events on the event ring. It may drop
2173 * xhci->lock between event processing (e.g. to pass up port status changes). 2173 * xhci->lock between event processing (e.g. to pass up port status changes).
2174 * Returns >0 for "possibly more events to process" (caller should call again),
2175 * otherwise 0 if done. In future, <0 returns should indicate error code.
2174 */ 2176 */
2175static void xhci_handle_event(struct xhci_hcd *xhci) 2177static int xhci_handle_event(struct xhci_hcd *xhci)
2176{ 2178{
2177 union xhci_trb *event; 2179 union xhci_trb *event;
2178 int update_ptrs = 1; 2180 int update_ptrs = 1;
@@ -2181,7 +2183,7 @@ static void xhci_handle_event(struct xhci_hcd *xhci)
2181 xhci_dbg(xhci, "In %s\n", __func__); 2183 xhci_dbg(xhci, "In %s\n", __func__);
2182 if (!xhci->event_ring || !xhci->event_ring->dequeue) { 2184 if (!xhci->event_ring || !xhci->event_ring->dequeue) {
2183 xhci->error_bitmask |= 1 << 1; 2185 xhci->error_bitmask |= 1 << 1;
2184 return; 2186 return 0;
2185 } 2187 }
2186 2188
2187 event = xhci->event_ring->dequeue; 2189 event = xhci->event_ring->dequeue;
@@ -2189,7 +2191,7 @@ static void xhci_handle_event(struct xhci_hcd *xhci)
2189 if ((le32_to_cpu(event->event_cmd.flags) & TRB_CYCLE) != 2191 if ((le32_to_cpu(event->event_cmd.flags) & TRB_CYCLE) !=
2190 xhci->event_ring->cycle_state) { 2192 xhci->event_ring->cycle_state) {
2191 xhci->error_bitmask |= 1 << 2; 2193 xhci->error_bitmask |= 1 << 2;
2192 return; 2194 return 0;
2193 } 2195 }
2194 xhci_dbg(xhci, "%s - OS owns TRB\n", __func__); 2196 xhci_dbg(xhci, "%s - OS owns TRB\n", __func__);
2195 2197
@@ -2233,15 +2235,17 @@ static void xhci_handle_event(struct xhci_hcd *xhci)
2233 if (xhci->xhc_state & XHCI_STATE_DYING) { 2235 if (xhci->xhc_state & XHCI_STATE_DYING) {
2234 xhci_dbg(xhci, "xHCI host dying, returning from " 2236 xhci_dbg(xhci, "xHCI host dying, returning from "
2235 "event handler.\n"); 2237 "event handler.\n");
2236 return; 2238 return 0;
2237 } 2239 }
2238 2240
2239 if (update_ptrs) 2241 if (update_ptrs)
2240 /* Update SW event ring dequeue pointer */ 2242 /* Update SW event ring dequeue pointer */
2241 inc_deq(xhci, xhci->event_ring, true); 2243 inc_deq(xhci, xhci->event_ring, true);
2242 2244
2243 /* Are there more items on the event ring? */ 2245 /* Are there more items on the event ring? Caller will call us again to
2244 xhci_handle_event(xhci); 2246 * check.
2247 */
2248 return 1;
2245} 2249}
2246 2250
2247/* 2251/*
@@ -2323,7 +2327,7 @@ hw_died:
2323 /* FIXME this should be a delayed service routine 2327 /* FIXME this should be a delayed service routine
2324 * that clears the EHB. 2328 * that clears the EHB.
2325 */ 2329 */
2326 xhci_handle_event(xhci); 2330 while (xhci_handle_event(xhci) > 0) {}
2327 2331
2328 temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); 2332 temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
2329 /* If necessary, update the HW's version of the event ring deq ptr. */ 2333 /* If necessary, update the HW's version of the event ring deq ptr. */