aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-sched.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2011-05-17 17:27:12 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-19 19:34:04 -0400
commit69fff59de4d844f8b4c2454c3c23d32b69dcbfd7 (patch)
tree3d88efbce85e3a8c25651d07f9c9ddafbda86ae5 /drivers/usb/host/ehci-sched.c
parentd23894402b33338c51f1863d7f866fdc6f073a02 (diff)
USB: remove remaining usages of hcd->state from usbcore and fix regression
This patch (as1467) removes the last usages of hcd->state from usbcore. We no longer check to see if an interrupt handler finds that a controller has died; instead we rely on host controller drivers to make an explicit call to usb_hc_died(). This fixes a regression introduced by commit 9b37596a2e860404503a3f2a6513db60c296bfdc (USB: move usbcore away from hcd->state). It used to be that when a controller shared an IRQ with another device and an interrupt arrived while hcd->state was set to HC_STATE_HALT, the interrupt handler would be skipped. The commit removed that test; as a result the current code doesn't skip calling the handler and ends up believing the controller has died, even though it's only temporarily stopped. The solution is to ignore HC_STATE_HALT following the handler's return. As a consequence of this change, several of the host controller drivers need to be modified. They can no longer implicitly rely on usbcore realizing that a controller has died because of hcd->state. The patch adds calls to usb_hc_died() in the appropriate places. The patch also changes a few of the interrupt handlers. They don't expect to be called when hcd->state is equal to HC_STATE_HALT, even if the controller is still alive. Early returns were added to avoid any confusion. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: Manuel Lauss <manuel.lauss@googlemail.com> CC: Rodolfo Giometti <giometti@linux.it> CC: Olav Kongas <ok@artecdesign.ee> CC: <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r--drivers/usb/host/ehci-sched.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index a7408d88fda0..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);