diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2013-03-22 13:30:56 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-25 16:35:05 -0400 |
commit | 79bcf7b02ba3d45bafe81a2753cedb8ef49548e3 (patch) | |
tree | da06b30b0fdd12dfb3286bed6a940bd2e4e0dfe0 | |
parent | c1fdb68e3d73741630ca16695cf9176c233be7ed (diff) |
USB: EHCI: change return value of qh_completions()
This patch (as1658) cleans up the usage of qh_completions() in
ehci-hcd. Currently the function's return value indicates whether any
URBs were given back; the idea was that the caller can scan the QH
over again to handle any URBs that were dequeued by a completion
handler. This is not necessary; when qh_completions() is ready to
give back dequeued URBs, it does its own rescanning.
Therefore the new return value will be a flag indicating whether the
caller needs to unlink the QH. This is more convenient than forcing
the caller to check qh->needs_rescan, and it makes a lot more sense --
why should "needs_rescan" imply that an unlink is needed? The callers
are also changed to remove the unneeded rescans.
Lastly, the check for whether qh->qtd_list is non-empty is removed
from the start of qh_completions(). Two of the callers have to make
this test anyway, so the same test can simply be added to the other
two callers.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/host/ehci-q.c | 22 | ||||
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 12 |
2 files changed, 13 insertions, 21 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index b824cb674898..c95f60d43b1a 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -292,8 +292,8 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh); | |||
292 | 292 | ||
293 | /* | 293 | /* |
294 | * Process and free completed qtds for a qh, returning URBs to drivers. | 294 | * Process and free completed qtds for a qh, returning URBs to drivers. |
295 | * Chases up to qh->hw_current. Returns number of completions called, | 295 | * Chases up to qh->hw_current. Returns nonzero if the caller should |
296 | * indicating how much "real" work we did. | 296 | * unlink qh. |
297 | */ | 297 | */ |
298 | static unsigned | 298 | static unsigned |
299 | qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | 299 | qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) |
@@ -302,13 +302,9 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
302 | struct list_head *entry, *tmp; | 302 | struct list_head *entry, *tmp; |
303 | int last_status; | 303 | int last_status; |
304 | int stopped; | 304 | int stopped; |
305 | unsigned count = 0; | ||
306 | u8 state; | 305 | u8 state; |
307 | struct ehci_qh_hw *hw = qh->hw; | 306 | struct ehci_qh_hw *hw = qh->hw; |
308 | 307 | ||
309 | if (unlikely (list_empty (&qh->qtd_list))) | ||
310 | return count; | ||
311 | |||
312 | /* completions (or tasks on other cpus) must never clobber HALT | 308 | /* completions (or tasks on other cpus) must never clobber HALT |
313 | * till we've gone through and cleaned everything up, even when | 309 | * till we've gone through and cleaned everything up, even when |
314 | * they add urbs to this qh's queue or mark them for unlinking. | 310 | * they add urbs to this qh's queue or mark them for unlinking. |
@@ -345,7 +341,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
345 | if (last) { | 341 | if (last) { |
346 | if (likely (last->urb != urb)) { | 342 | if (likely (last->urb != urb)) { |
347 | ehci_urb_done(ehci, last->urb, last_status); | 343 | ehci_urb_done(ehci, last->urb, last_status); |
348 | count++; | ||
349 | last_status = -EINPROGRESS; | 344 | last_status = -EINPROGRESS; |
350 | } | 345 | } |
351 | ehci_qtd_free (ehci, last); | 346 | ehci_qtd_free (ehci, last); |
@@ -519,7 +514,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
519 | /* last urb's completion might still need calling */ | 514 | /* last urb's completion might still need calling */ |
520 | if (likely (last != NULL)) { | 515 | if (likely (last != NULL)) { |
521 | ehci_urb_done(ehci, last->urb, last_status); | 516 | ehci_urb_done(ehci, last->urb, last_status); |
522 | count++; | ||
523 | ehci_qtd_free (ehci, last); | 517 | ehci_qtd_free (ehci, last); |
524 | } | 518 | } |
525 | 519 | ||
@@ -566,7 +560,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
566 | /* otherwise, unlink already started */ | 560 | /* otherwise, unlink already started */ |
567 | } | 561 | } |
568 | 562 | ||
569 | return count; | 563 | return qh->needs_rescan; |
570 | } | 564 | } |
571 | 565 | ||
572 | /*-------------------------------------------------------------------------*/ | 566 | /*-------------------------------------------------------------------------*/ |
@@ -1254,7 +1248,8 @@ static void end_unlink_async(struct ehci_hcd *ehci) | |||
1254 | qh->qh_state = QH_STATE_IDLE; | 1248 | qh->qh_state = QH_STATE_IDLE; |
1255 | qh->qh_next.qh = NULL; | 1249 | qh->qh_next.qh = NULL; |
1256 | 1250 | ||
1257 | qh_completions(ehci, qh); | 1251 | if (!list_empty(&qh->qtd_list)) |
1252 | qh_completions(ehci, qh); | ||
1258 | if (!list_empty(&qh->qtd_list) && | 1253 | if (!list_empty(&qh->qtd_list) && |
1259 | ehci->rh_state == EHCI_RH_RUNNING) | 1254 | ehci->rh_state == EHCI_RH_RUNNING) |
1260 | qh_link_async(ehci, qh); | 1255 | qh_link_async(ehci, qh); |
@@ -1348,7 +1343,7 @@ static void scan_async (struct ehci_hcd *ehci) | |||
1348 | while (ehci->qh_scan_next) { | 1343 | while (ehci->qh_scan_next) { |
1349 | qh = ehci->qh_scan_next; | 1344 | qh = ehci->qh_scan_next; |
1350 | ehci->qh_scan_next = qh->qh_next.qh; | 1345 | ehci->qh_scan_next = qh->qh_next.qh; |
1351 | rescan: | 1346 | |
1352 | /* clean any finished work for this qh */ | 1347 | /* clean any finished work for this qh */ |
1353 | if (!list_empty(&qh->qtd_list)) { | 1348 | if (!list_empty(&qh->qtd_list)) { |
1354 | int temp; | 1349 | int temp; |
@@ -1361,14 +1356,13 @@ static void scan_async (struct ehci_hcd *ehci) | |||
1361 | * in single_unlink_async(). | 1356 | * in single_unlink_async(). |
1362 | */ | 1357 | */ |
1363 | temp = qh_completions(ehci, qh); | 1358 | temp = qh_completions(ehci, qh); |
1364 | if (qh->needs_rescan) { | 1359 | if (unlikely(temp)) { |
1365 | start_unlink_async(ehci, qh); | 1360 | start_unlink_async(ehci, qh); |
1366 | } else if (list_empty(&qh->qtd_list) | 1361 | } else if (list_empty(&qh->qtd_list) |
1367 | && qh->qh_state == QH_STATE_LINKED) { | 1362 | && qh->qh_state == QH_STATE_LINKED) { |
1368 | qh->unlink_cycle = ehci->async_unlink_cycle; | 1363 | qh->unlink_cycle = ehci->async_unlink_cycle; |
1369 | check_unlinks_later = true; | 1364 | check_unlinks_later = true; |
1370 | } else if (temp != 0) | 1365 | } |
1371 | goto rescan; | ||
1372 | } | 1366 | } |
1373 | } | 1367 | } |
1374 | 1368 | ||
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 66259dc7822e..5c82bbab9a48 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -649,7 +649,8 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
649 | qh->qh_state = QH_STATE_IDLE; | 649 | qh->qh_state = QH_STATE_IDLE; |
650 | hw->hw_next = EHCI_LIST_END(ehci); | 650 | hw->hw_next = EHCI_LIST_END(ehci); |
651 | 651 | ||
652 | qh_completions(ehci, qh); | 652 | if (!list_empty(&qh->qtd_list)) |
653 | qh_completions(ehci, qh); | ||
653 | 654 | ||
654 | /* reschedule QH iff another request is queued */ | 655 | /* reschedule QH iff another request is queued */ |
655 | if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) { | 656 | if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) { |
@@ -914,7 +915,7 @@ static void scan_intr(struct ehci_hcd *ehci) | |||
914 | 915 | ||
915 | list_for_each_entry_safe(qh, ehci->qh_scan_next, &ehci->intr_qh_list, | 916 | list_for_each_entry_safe(qh, ehci->qh_scan_next, &ehci->intr_qh_list, |
916 | intr_node) { | 917 | intr_node) { |
917 | rescan: | 918 | |
918 | /* clean any finished work for this qh */ | 919 | /* clean any finished work for this qh */ |
919 | if (!list_empty(&qh->qtd_list)) { | 920 | if (!list_empty(&qh->qtd_list)) { |
920 | int temp; | 921 | int temp; |
@@ -927,12 +928,9 @@ static void scan_intr(struct ehci_hcd *ehci) | |||
927 | * in qh_unlink_periodic(). | 928 | * in qh_unlink_periodic(). |
928 | */ | 929 | */ |
929 | temp = qh_completions(ehci, qh); | 930 | temp = qh_completions(ehci, qh); |
930 | if (unlikely(qh->needs_rescan || | 931 | if (unlikely(temp || (list_empty(&qh->qtd_list) && |
931 | (list_empty(&qh->qtd_list) && | 932 | qh->qh_state == QH_STATE_LINKED))) |
932 | qh->qh_state == QH_STATE_LINKED))) | ||
933 | start_unlink_intr(ehci, qh); | 933 | start_unlink_intr(ehci, qh); |
934 | else if (temp != 0) | ||
935 | goto rescan; | ||
936 | } | 934 | } |
937 | } | 935 | } |
938 | } | 936 | } |