summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ehci-q.c1
-rw-r--r--drivers/usb/host/ehci-sched.c14
-rw-r--r--drivers/usb/host/ehci.h1
3 files changed, 12 insertions, 4 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index a46d6a1388c9..5d6bc624c961 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 1543c838b3d1..a7408d88fda0 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 829213423dea..f68e419cae87 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;