ChangeSet 1.1931, 2004/04/22 13:43:11-07:00, [EMAIL PROTECTED]

[PATCH] USB: ehci handles pci misbehavior better

Cope better when PCI misbehaves badly and registers misbehave:

    - terminate some loops before they get to infinity
       * capability scan
       * port reset
    - after init failure, memory may already be cleaned up

Some systems have been reporting such problems after ACPI resume.


 drivers/usb/host/ehci-hcd.c |   17 ++++++++++++++---
 drivers/usb/host/ehci-hub.c |   16 ++++++++++------
 2 files changed, 24 insertions(+), 9 deletions(-)


diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c       Thu Apr 22 14:41:25 2004
+++ b/drivers/usb/host/ehci-hcd.c       Thu Apr 22 14:41:25 2004
@@ -330,6 +330,7 @@
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        u32                     temp;
+       unsigned                count = 256/4;
 
        spin_lock_init (&ehci->lock);
 
@@ -345,16 +346,21 @@
                temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
        else
                temp = 0;
-       while (temp) {
+       while (temp && count--) {
                u32             cap;
 
-               pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller), temp, 
&cap);
+               pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller),
+                               temp, &cap);
                ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp);
                switch (cap & 0xff) {
                case 1:                 /* BIOS/SMM/... handoff */
                        if (bios_handoff (ehci, temp, cap) != 0)
                                return -EOPNOTSUPP;
                        break;
+               case 0x0a:              /* appendix C */
+                       ehci_dbg (ehci, "debug registers, BAR %d offset %d\n",
+                               (cap >> 29) & 0x07, (cap >> 16) & 0x0fff);
+                       break;
                case 0:                 /* illegal reserved capability */
                        ehci_warn (ehci, "illegal capability!\n");
                        cap = 0;
@@ -364,6 +370,10 @@
                }
                temp = (cap >> 8) & 0xff;
        }
+       if (!count) {
+               ehci_err (ehci, "bogus capabilities ... PCI problems!\n");
+               return -EIO;
+       }
 #endif
 
        /* cache this readonly data; minimize PCI reads */
@@ -577,7 +587,8 @@
 
        /* root hub is shut down separately (first, when possible) */
        spin_lock_irq (&ehci->lock);
-       ehci_work (ehci, NULL);
+       if (ehci->async)
+               ehci_work (ehci, NULL);
        spin_unlock_irq (&ehci->lock);
        ehci_mem_cleanup (ehci);
 
diff -Nru a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
--- a/drivers/usb/host/ehci-hub.c       Thu Apr 22 14:41:25 2004
+++ b/drivers/usb/host/ehci-hub.c       Thu Apr 22 14:41:25 2004
@@ -252,14 +252,18 @@
                        /* force reset to complete */
                        writel (temp & ~PORT_RESET,
                                        &ehci->regs->port_status [wIndex]);
-                       do {
-                               temp = readl (
-                                       &ehci->regs->port_status [wIndex]);
-                               udelay (10);
-                       } while (temp & PORT_RESET);
+                       retval = handshake (
+                                       &ehci->regs->port_status [wIndex],
+                                       PORT_RESET, 0, 500);
+                       if (retval != 0) {
+                               ehci_err (ehci, "port %d reset error %d\n",
+                                       wIndex + 1, retval);
+                               goto error;
+                       }
 
                        /* see what we found out */
-                       temp = check_reset_complete (ehci, wIndex, temp);
+                       temp = check_reset_complete (ehci, wIndex,
+                               readl (&ehci->regs->port_status [wIndex]));
                }
 
                // don't show wPortStatus if it's owned by a companion hc



-------------------------------------------------------
This SF.net email is sponsored by: The Robotic Monkeys at ThinkGeek
For a limited time only, get FREE Ground shipping on all orders of $35
or more. Hurry up and shop folks, this offer expires April 30th!
http://www.thinkgeek.com/freeshipping/?cpg297
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to