|
@@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd)
|
|
static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|
static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|
{
|
|
{
|
|
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
|
|
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
|
|
- u32 status, pcd_status = 0, cmd;
|
|
|
|
|
|
+ u32 status, masked_status, pcd_status = 0, cmd;
|
|
int bh;
|
|
int bh;
|
|
|
|
|
|
spin_lock (&ehci->lock);
|
|
spin_lock (&ehci->lock);
|
|
@@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|
goto dead;
|
|
goto dead;
|
|
}
|
|
}
|
|
|
|
|
|
- status &= INTR_MASK;
|
|
|
|
- if (!status) { /* irq sharing? */
|
|
|
|
|
|
+ masked_status = status & INTR_MASK;
|
|
|
|
+ if (!masked_status) { /* irq sharing? */
|
|
spin_unlock(&ehci->lock);
|
|
spin_unlock(&ehci->lock);
|
|
return IRQ_NONE;
|
|
return IRQ_NONE;
|
|
}
|
|
}
|
|
|
|
|
|
/* clear (just) interrupts */
|
|
/* clear (just) interrupts */
|
|
- ehci_writel(ehci, status, &ehci->regs->status);
|
|
|
|
|
|
+ ehci_writel(ehci, masked_status, &ehci->regs->status);
|
|
cmd = ehci_readl(ehci, &ehci->regs->command);
|
|
cmd = ehci_readl(ehci, &ehci->regs->command);
|
|
bh = 0;
|
|
bh = 0;
|
|
|
|
|
|
@@ -734,18 +734,17 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|
|
|
|
|
/* PCI errors [4.15.2.4] */
|
|
/* PCI errors [4.15.2.4] */
|
|
if (unlikely ((status & STS_FATAL) != 0)) {
|
|
if (unlikely ((status & STS_FATAL) != 0)) {
|
|
|
|
+ ehci_err(ehci, "fatal error\n");
|
|
dbg_cmd(ehci, "fatal", cmd);
|
|
dbg_cmd(ehci, "fatal", cmd);
|
|
dbg_status(ehci, "fatal", status);
|
|
dbg_status(ehci, "fatal", status);
|
|
- if (status & STS_HALT) {
|
|
|
|
- ehci_err (ehci, "fatal error\n");
|
|
|
|
|
|
+ ehci_halt(ehci);
|
|
dead:
|
|
dead:
|
|
- ehci_reset (ehci);
|
|
|
|
- ehci_writel(ehci, 0, &ehci->regs->configured_flag);
|
|
|
|
- /* generic layer kills/unlinks all urbs, then
|
|
|
|
- * uses ehci_stop to clean up the rest
|
|
|
|
- */
|
|
|
|
- bh = 1;
|
|
|
|
- }
|
|
|
|
|
|
+ ehci_reset(ehci);
|
|
|
|
+ ehci_writel(ehci, 0, &ehci->regs->configured_flag);
|
|
|
|
+ /* generic layer kills/unlinks all urbs, then
|
|
|
|
+ * uses ehci_stop to clean up the rest
|
|
|
|
+ */
|
|
|
|
+ bh = 1;
|
|
}
|
|
}
|
|
|
|
|
|
if (bh)
|
|
if (bh)
|