|
@@ -1116,8 +1116,7 @@ static void scan_async (struct ehci_hcd *ehci)
|
|
|
struct ehci_qh *qh;
|
|
|
enum ehci_timer_action action = TIMER_IO_WATCHDOG;
|
|
|
|
|
|
- if (!++(ehci->stamp))
|
|
|
- ehci->stamp++;
|
|
|
+ ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index);
|
|
|
timer_action_done (ehci, TIMER_ASYNC_SHRINK);
|
|
|
rescan:
|
|
|
qh = ehci->async->qh_next.qh;
|
|
@@ -1148,12 +1147,14 @@ rescan:
|
|
|
* doesn't stay idle for long.
|
|
|
* (plus, avoids some kind of re-activation race.)
|
|
|
*/
|
|
|
- if (list_empty (&qh->qtd_list)) {
|
|
|
- if (qh->stamp == ehci->stamp)
|
|
|
+ if (list_empty(&qh->qtd_list) &&
|
|
|
+ qh->qh_state == QH_STATE_LINKED) {
|
|
|
+ if (!ehci->reclaim &&
|
|
|
+ ((ehci->stamp - qh->stamp) & 8191) >=
|
|
|
+ EHCI_SHRINK_UFRAMES)
|
|
|
+ start_unlink_async(ehci, qh);
|
|
|
+ else
|
|
|
action = TIMER_ASYNC_SHRINK;
|
|
|
- else if (!ehci->reclaim
|
|
|
- && qh->qh_state == QH_STATE_LINKED)
|
|
|
- start_unlink_async (ehci, qh);
|
|
|
}
|
|
|
|
|
|
qh = qh->qh_next.qh;
|