ChangeSet 1.1276.1.54, 2003/08/27 17:32:14-07:00, [EMAIL PROTECTED]
[PATCH] USB: ohci -- reset, fault recovery
This fixes two small and unrelated bugs in the current OHCI code:
- Certain initialization sequences had problems with IRQs.
Fixed last month in EHCI, but this ohci patch didn't seem
needed back then. OK, so now I saw the same bug in OHCI.
(I could believe UHCI needs it too, sigh.)
- When restarting endpoint i/o after a queue fault, the HC
needs to be told the control (or bulk) list filled (CLF/BLF).
Likely this wasn't common (usbtest test10 subcase7 fault
recovery reproduced it nicely).
Please merge. Lack of the first one might make trouble for
some people.
drivers/usb/host/ohci-pci.c | 16 ++++++++++------
drivers/usb/host/ohci-q.c | 16 ++++++++++++++--
2 files changed, 24 insertions(+), 8 deletions(-)
diff -Nru a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
--- a/drivers/usb/host/ohci-pci.c Tue Sep 2 12:43:11 2003
+++ b/drivers/usb/host/ohci-pci.c Tue Sep 2 12:43:11 2003
@@ -30,6 +30,15 @@
/*-------------------------------------------------------------------------*/
+static int
+ohci_pci_reset (struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+
+ ohci->regs = hcd->regs;
+ return hc_reset (ohci);
+}
+
static int __devinit
ohci_pci_start (struct usb_hcd *hcd)
{
@@ -89,12 +98,6 @@
ohci_stop (hcd);
return ret;
}
- ohci->regs = hcd->regs;
-
- if (hc_reset (ohci) < 0) {
- ohci_stop (hcd);
- return -ENODEV;
- }
if (hc_start (ohci) < 0) {
ohci_err (ohci, "can't start\n");
@@ -315,6 +318,7 @@
/*
* basic lifecycle operations
*/
+ .reset = ohci_pci_reset,
.start = ohci_pci_start,
#ifdef CONFIG_PM
.suspend = ohci_pci_suspend,
diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c Tue Sep 2 12:43:11 2003
+++ b/drivers/usb/host/ohci-q.c Tue Sep 2 12:43:11 2003
@@ -1013,10 +1013,22 @@
if (list_empty (&ed->td_list))
ed_deschedule (ohci, ed);
/* ... reenabling halted EDs only after fault cleanup */
- else if (!(ed->hwINFO & ED_DEQUEUE)) {
+ else if ((ed->hwINFO & (ED_SKIP | ED_DEQUEUE)) == ED_SKIP) {
td = list_entry (ed->td_list.next, struct td, td_list);
- if (!(td->hwINFO & TD_DONE))
+ if (!(td->hwINFO & TD_DONE)) {
ed->hwINFO &= ~ED_SKIP;
+ /* ... hc may need waking-up */
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ writel (OHCI_CLF,
+ &ohci->regs->cmdstatus);
+ break;
+ case PIPE_BULK:
+ writel (OHCI_BLF,
+ &ohci->regs->cmdstatus);
+ break;
+ }
+ }
}
td = td_next;
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel