ChangeSet 1.1623, 2003/08/01 10:08:08-07:00, [EMAIL PROTECTED]

[PATCH] USB: hcd initialization fix

This cleans up HCD initialization by adding an explicit
reset step, putting the device into a known state before
resources are allocated.  This step is implemented for
EHCI, since some BIOS firmware seems to act quirky there,
but nothing else yet.  (OHCI would be just easy too.)


 drivers/usb/core/hcd-pci.c  |   21 ++++++++++++++-------
 drivers/usb/core/hcd.h      |    1 +
 drivers/usb/host/ehci-hcd.c |   31 ++++++++++++++++++-------------
 3 files changed, 33 insertions(+), 20 deletions(-)


diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
--- a/drivers/usb/core/hcd-pci.c        Fri Aug  1 10:53:34 2003
+++ b/drivers/usb/core/hcd-pci.c        Fri Aug  1 10:53:34 2003
@@ -122,10 +122,9 @@
                base = (void *) resource;
        }
 
-       // driver->start(), later on, will transfer device from
+       // driver->reset(), later on, will transfer device from
        // control by SMM/BIOS to control by Linux (if needed)
 
-       pci_set_master (dev);
        hcd = driver->hcd_alloc ();
        if (hcd == NULL){
                dbg ("hcd alloc fail");
@@ -140,6 +139,9 @@
                        return retval;
                }
        }
+       hcd->regs = base;
+       hcd->region = region;
+
        pci_set_drvdata (dev, hcd);
        hcd->driver = driver;
        hcd->description = driver->description;
@@ -157,22 +159,27 @@
 
        dev_info (hcd->controller, "%s\n", hcd->product_desc);
 
+       /* till now HC has been in an indeterminate state ... */
+       if (driver->reset && (retval = driver->reset (hcd)) < 0) {
+               dev_err (hcd->controller, "can't reset\n");
+               goto clean_3;
+       }
+
+       pci_set_master (dev);
 #ifndef __sparc__
        sprintf (buf, "%d", dev->irq);
 #else
        bufp = __irq_itoa(dev->irq);
 #endif
-       if (request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd)
-                       != 0) {
+       retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ,
+                               hcd->description, hcd);
+       if (retval != 0) {
                dev_err (hcd->controller,
                                "request interrupt %s failed\n", bufp);
-               retval = -EBUSY;
                goto clean_3;
        }
        hcd->irq = dev->irq;
 
-       hcd->regs = base;
-       hcd->region = region;
        dev_info (hcd->controller, "irq %s, %s %p\n", bufp,
                (driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
                base);
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h    Fri Aug  1 10:53:34 2003
+++ b/drivers/usb/core/hcd.h    Fri Aug  1 10:53:34 2003
@@ -173,6 +173,7 @@
 #define        HCD_USB2        0x0020          /* USB 2.0 */
 
        /* called to init HCD and root hub */
+       int     (*reset) (struct usb_hcd *hcd);
        int     (*start) (struct usb_hcd *hcd);
 
        /* called after all devices were suspended */
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c       Fri Aug  1 10:53:34 2003
+++ b/drivers/usb/host/ehci-hcd.c       Fri Aug  1 10:53:34 2003
@@ -318,28 +318,21 @@
 
 /* called by khubd or root hub init threads */
 
-static int ehci_start (struct usb_hcd *hcd)
+static int ehci_hc_reset (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        u32                     temp;
-       struct usb_device       *udev;
-       struct usb_bus          *bus;
-       int                     retval;
-       u32                     hcc_params;
-       u8                      tempbyte;
 
        spin_lock_init (&ehci->lock);
 
        ehci->caps = (struct ehci_caps *) hcd->regs;
        ehci->regs = (struct ehci_regs *) (hcd->regs +
                                readb (&ehci->caps->length));
-       dbg_hcs_params (ehci, "ehci_start");
-       dbg_hcc_params (ehci, "ehci_start");
-
-       hcc_params = readl (&ehci->caps->hcc_params);
+       dbg_hcs_params (ehci, "reset");
+       dbg_hcc_params (ehci, "reset");
 
        /* EHCI 0.96 and later may have "extended capabilities" */
-       temp = HCC_EXT_CAPS (hcc_params);
+       temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
        while (temp) {
                u32             cap;
 
@@ -364,8 +357,18 @@
        ehci->hcs_params = readl (&ehci->caps->hcs_params);
 
        /* force HC to halt state */
-       if ((retval = ehci_halt (ehci)) != 0)
-               return retval;
+       return ehci_halt (ehci);
+}
+
+static int ehci_start (struct usb_hcd *hcd)
+{
+       struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
+       u32                     temp;
+       struct usb_device       *udev;
+       struct usb_bus          *bus;
+       int                     retval;
+       u32                     hcc_params;
+       u8                      tempbyte;
 
        /*
         * hw default: 1K periodic list heads, one per frame.
@@ -376,6 +379,7 @@
                return retval;
 
        /* controllers may cache some of the periodic schedule ... */
+       hcc_params = readl (&ehci->caps->hcc_params);
        if (HCC_ISOC_CACHE (hcc_params))        // full frame cache
                ehci->i_thresh = 8;
        else                                    // N microframes cached
@@ -937,6 +941,7 @@
        /*
         * basic lifecycle operations
         */
+       .reset =                ehci_hc_reset,
        .start =                ehci_start,
 #ifdef CONFIG_PM
        .suspend =              ehci_suspend,



-------------------------------------------------------
This SF.Net email sponsored by: Free pre-built ASP.NET sites including
Data Reports, E-commerce, Portals, and Forums are available now.
Download today and enter to win an XBOX or Visual Studio .NET.
http://aspnet.click-url.com/go/psa00100003ave/direct;at.aspnet_072303_01/01
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to