diff options
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 1543c838b3d1..6c9fbe352f73 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -471,8 +471,10 @@ static int enable_periodic (struct ehci_hcd *ehci) | |||
471 | */ | 471 | */ |
472 | status = handshake_on_error_set_halt(ehci, &ehci->regs->status, | 472 | status = handshake_on_error_set_halt(ehci, &ehci->regs->status, |
473 | STS_PSS, 0, 9 * 125); | 473 | STS_PSS, 0, 9 * 125); |
474 | if (status) | 474 | if (status) { |
475 | usb_hc_died(ehci_to_hcd(ehci)); | ||
475 | return status; | 476 | return status; |
477 | } | ||
476 | 478 | ||
477 | cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; | 479 | cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; |
478 | ehci_writel(ehci, cmd, &ehci->regs->command); | 480 | ehci_writel(ehci, cmd, &ehci->regs->command); |
@@ -510,8 +512,10 @@ static int disable_periodic (struct ehci_hcd *ehci) | |||
510 | */ | 512 | */ |
511 | status = handshake_on_error_set_halt(ehci, &ehci->regs->status, | 513 | status = handshake_on_error_set_halt(ehci, &ehci->regs->status, |
512 | STS_PSS, STS_PSS, 9 * 125); | 514 | STS_PSS, STS_PSS, 9 * 125); |
513 | if (status) | 515 | if (status) { |
516 | usb_hc_died(ehci_to_hcd(ehci)); | ||
514 | return status; | 517 | return status; |
518 | } | ||
515 | 519 | ||
516 | cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE; | 520 | cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE; |
517 | ehci_writel(ehci, cmd, &ehci->regs->command); | 521 | ehci_writel(ehci, cmd, &ehci->regs->command); |
@@ -2287,6 +2291,7 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2287 | } | 2291 | } |
2288 | clock &= mod - 1; | 2292 | clock &= mod - 1; |
2289 | clock_frame = clock >> 3; | 2293 | clock_frame = clock >> 3; |
2294 | ++ehci->periodic_stamp; | ||
2290 | 2295 | ||
2291 | for (;;) { | 2296 | for (;;) { |
2292 | union ehci_shadow q, *q_p; | 2297 | union ehci_shadow q, *q_p; |
@@ -2315,10 +2320,14 @@ restart: | |||
2315 | temp.qh = qh_get (q.qh); | 2320 | temp.qh = qh_get (q.qh); |
2316 | type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next); | 2321 | type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next); |
2317 | q = q.qh->qh_next; | 2322 | q = q.qh->qh_next; |
2318 | modified = qh_completions (ehci, temp.qh); | 2323 | if (temp.qh->stamp != ehci->periodic_stamp) { |
2319 | if (unlikely(list_empty(&temp.qh->qtd_list) || | 2324 | modified = qh_completions(ehci, temp.qh); |
2320 | temp.qh->needs_rescan)) | 2325 | if (!modified) |
2321 | intr_deschedule (ehci, temp.qh); | 2326 | temp.qh->stamp = ehci->periodic_stamp; |
2327 | if (unlikely(list_empty(&temp.qh->qtd_list) || | ||
2328 | temp.qh->needs_rescan)) | ||
2329 | intr_deschedule(ehci, temp.qh); | ||
2330 | } | ||
2322 | qh_put (temp.qh); | 2331 | qh_put (temp.qh); |
2323 | break; | 2332 | break; |
2324 | case Q_TYPE_FSTN: | 2333 | case Q_TYPE_FSTN: |
@@ -2460,6 +2469,7 @@ restart: | |||
2460 | if (ehci->clock_frame != clock_frame) { | 2469 | if (ehci->clock_frame != clock_frame) { |
2461 | free_cached_lists(ehci); | 2470 | free_cached_lists(ehci); |
2462 | ehci->clock_frame = clock_frame; | 2471 | ehci->clock_frame = clock_frame; |
2472 | ++ehci->periodic_stamp; | ||
2463 | } | 2473 | } |
2464 | } else { | 2474 | } else { |
2465 | now_uframe++; | 2475 | now_uframe++; |