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
9b37596a2e
(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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
d23894402b
commit
69fff59de4
@ -986,7 +986,7 @@ static int register_root_hub(struct usb_hcd *hcd)
|
||||
spin_unlock_irq (&hcd_root_hub_lock);
|
||||
|
||||
/* Did the HC die before the root hub was registered? */
|
||||
if (HCD_DEAD(hcd) || hcd->state == HC_STATE_HALT)
|
||||
if (HCD_DEAD(hcd))
|
||||
usb_hc_died (hcd); /* This time clean up */
|
||||
}
|
||||
|
||||
@ -2128,9 +2128,6 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
|
||||
set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
|
||||
if (hcd->shared_hcd)
|
||||
set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags);
|
||||
|
||||
if (unlikely(hcd->state == HC_STATE_HALT))
|
||||
usb_hc_died(hcd);
|
||||
rc = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user