diff options
-rw-r--r-- | drivers/usb/host/ehci-q.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 14 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 1 |
3 files changed, 12 insertions, 4 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index a46d6a1388c..5d6bc624c96 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -826,6 +826,7 @@ qh_make ( is_input, 0, hb_mult(maxp) * max_packet(maxp))); qh->start = NO_FRAME; + qh->stamp = ehci->periodic_stamp; if (urb->dev->speed == USB_SPEED_HIGH) { qh->c_usecs = 0; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 1543c838b3d..a7408d88fda 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -2287,6 +2287,7 @@ scan_periodic (struct ehci_hcd *ehci) } clock &= mod - 1; clock_frame = clock >> 3; + ++ehci->periodic_stamp; for (;;) { union ehci_shadow q, *q_p; @@ -2315,10 +2316,14 @@ restart: temp.qh = qh_get (q.qh); type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next); q = q.qh->qh_next; - modified = qh_completions (ehci, temp.qh); - if (unlikely(list_empty(&temp.qh->qtd_list) || - temp.qh->needs_rescan)) - intr_deschedule (ehci, temp.qh); + if (temp.qh->stamp != ehci->periodic_stamp) { + modified = qh_completions(ehci, temp.qh); + if (!modified) + temp.qh->stamp = ehci->periodic_stamp; + if (unlikely(list_empty(&temp.qh->qtd_list) || + temp.qh->needs_rescan)) + intr_deschedule(ehci, temp.qh); + } qh_put (temp.qh); break; case Q_TYPE_FSTN: @@ -2460,6 +2465,7 @@ restart: if (ehci->clock_frame != clock_frame) { free_cached_lists(ehci); ehci->clock_frame = clock_frame; + ++ehci->periodic_stamp; } } else { now_uframe++; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 829213423de..f68e419cae8 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -118,6 +118,7 @@ struct ehci_hcd { /* one per controller */ struct timer_list watchdog; unsigned long actions; unsigned stamp; + unsigned periodic_stamp; unsigned random_frame; unsigned long next_statechange; ktime_t last_periodic_enable; |