--- 1.29/drivers/usb/core/hcd.h Tue Jul 1 06:25:37 2003 +++ edited/drivers/usb/core/hcd.h Thu Jul 24 11:20:45 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 */ --- 1.17/drivers/usb/core/hcd-pci.c Tue Jul 15 07:08:20 2003 +++ edited/drivers/usb/core/hcd-pci.c Fri Jul 25 16:30:27 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); --- 1.68/drivers/usb/core/hcd.c Tue Jul 15 09:47:16 2003 +++ edited/drivers/usb/core/hcd.c Thu Jul 24 23:34:01 2003 @@ -1319,6 +1319,7 @@ if (tmp == -EINPROGRESS) urb->status = -ESHUTDOWN; spin_unlock (&urb->lock); + local_irq_restore (flags); /* kick hcd unless it's already returning this */ if (tmp == -EINPROGRESS) { --- 1.53/drivers/usb/host/ehci-hcd.c Wed Jun 18 21:50:06 2003 +++ edited/drivers/usb/host/ehci-hcd.c Fri Jul 25 16:35:10 2003 @@ -318,27 +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 + ehci->caps->length); - dbg_hcs_params (ehci, "ehci_start"); - dbg_hcc_params (ehci, "ehci_start"); - - hcc_params = readl (&ehci->caps->hcc_params); + ehci->regs = (struct ehci_regs *) (hcd->regs + + readb (&ehci->caps->length)); + 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; @@ -363,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. @@ -375,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 +942,7 @@ /* * basic lifecycle operations */ + .reset = ehci_hc_reset, .start = ehci_start, #ifdef CONFIG_PM .suspend = ehci_suspend,