aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/oxu210hp-hcd.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/oxu210hp-hcd.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/oxu210hp-hcd.c')
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 4a771f6cc822..5fbe997dc6df 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -1884,6 +1884,7 @@ static int enable_periodic(struct oxu_hcd *oxu)
1884 status = handshake(oxu, &oxu->regs->status, STS_PSS, 0, 9 * 125); 1884 status = handshake(oxu, &oxu->regs->status, STS_PSS, 0, 9 * 125);
1885 if (status != 0) { 1885 if (status != 0) {
1886 oxu_to_hcd(oxu)->state = HC_STATE_HALT; 1886 oxu_to_hcd(oxu)->state = HC_STATE_HALT;
1887 usb_hc_died(oxu_to_hcd(oxu));
1887 return status; 1888 return status;
1888 } 1889 }
1889 1890
@@ -1909,6 +1910,7 @@ static int disable_periodic(struct oxu_hcd *oxu)
1909 status = handshake(oxu, &oxu->regs->status, STS_PSS, STS_PSS, 9 * 125); 1910 status = handshake(oxu, &oxu->regs->status, STS_PSS, STS_PSS, 9 * 125);
1910 if (status != 0) { 1911 if (status != 0) {
1911 oxu_to_hcd(oxu)->state = HC_STATE_HALT; 1912 oxu_to_hcd(oxu)->state = HC_STATE_HALT;
1913 usb_hc_died(oxu_to_hcd(oxu));
1912 return status; 1914 return status;
1913 } 1915 }
1914 1916
@@ -2449,8 +2451,9 @@ static irqreturn_t oxu210_hcd_irq(struct usb_hcd *hcd)
2449 goto dead; 2451 goto dead;
2450 } 2452 }
2451 2453
2454 /* Shared IRQ? */
2452 status &= INTR_MASK; 2455 status &= INTR_MASK;
2453 if (!status) { /* irq sharing? */ 2456 if (!status || unlikely(hcd->state == HC_STATE_HALT)) {
2454 spin_unlock(&oxu->lock); 2457 spin_unlock(&oxu->lock);
2455 return IRQ_NONE; 2458 return IRQ_NONE;
2456 } 2459 }
@@ -2516,6 +2519,7 @@ static irqreturn_t oxu210_hcd_irq(struct usb_hcd *hcd)
2516dead: 2519dead:
2517 ehci_reset(oxu); 2520 ehci_reset(oxu);
2518 writel(0, &oxu->regs->configured_flag); 2521 writel(0, &oxu->regs->configured_flag);
2522 usb_hc_died(hcd);
2519 /* generic layer kills/unlinks all urbs, then 2523 /* generic layer kills/unlinks all urbs, then
2520 * uses oxu_stop to clean up the rest 2524 * uses oxu_stop to clean up the rest
2521 */ 2525 */