dwc_otg: make channel halts with unknown state less damaging
If the IRQ received a channel halt interrupt through the FIQ
with no other bits set, the IRQ would not release the host
channel and never complete the URB.
Add catchall handling to treat as a transaction error and retry.
Source: https://dev.openwrt.org/browser/branches/barrier_breaker/target/linux/brcm2708/patches-3.10/0084-dwc_otg-make-channel-halts-with-unknown-state-less-d.patch?rev=42682
Google-Bug-Id: 23325978
Change-Id: I87e827944ae055260277f749e30d48d1ff4c240f
diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
index 856b150..3837595 100644
--- a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
+++ b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
@@ -1976,14 +1976,24 @@
DWC_READ_REG32(&hcd->
core_if->core_global_regs->
gintsts));
- halt_channel(hcd, hc, qtd,
- DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE);
+ /* Failthrough: use 3-strikes rule */
+ qtd->error_count++;
+ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
+ update_urb_state_xfer_intr(hc, hc_regs,
+ qtd->urb, qtd, DWC_OTG_HC_XFER_XACT_ERR);
+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
}
}
} else {
DWC_PRINTF("NYET/NAK/ACK/other in non-error case, 0x%08x\n",
hcint.d32);
+ /* Failthrough: use 3-strikes rule */
+ qtd->error_count++;
+ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
+ update_urb_state_xfer_intr(hc, hc_regs,
+ qtd->urb, qtd, DWC_OTG_HC_XFER_XACT_ERR);
+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
}
}