On Fri, 22 Oct 2004, David Brownell wrote: > > I've only been able to test this with UHCI and EHCI. Maybe you can try it > > out with some of the more obscure drivers. I can't even compile them. > > I can't either, without your patch ... ;)
Did I forget to send the patch? Sometimes I think my brain must need a RAM replacement... This time I'll remember it. By the way, I made similar changes to dummy_hcd.c (not included below) but they needed to be more extensive. I can test those by myself easily enough. > > The order of acquisition of some resources has been changed, > > maybe even rearranged with respect to a device-specific > > initialization routine. It doesn't look like it will cause > > trouble, but I can't be sure. > > I think the main rule is that they should all be claimed by the > time the driver is asked to do Real Work. I just wanted to check that they weren't needed by an init routine that got moved in front of the acquisition. There are only one or two places like that. > > The resource value displayed in the dev_info() in usb_hcd_init2 > > is sometimes a pointer and sometimes not. The code casts it > > to unsigned long; is this okay? > > I'd need to see the patch ... the resource values might be good > cases to use the iomap() infrastructure. Judge for yourself; it's the last argument to usb_hcd_init2(). > > I don't understand the call to omap_free_gpio(), which appears > > in the shutdown path but not the error path in ohci-omap.c. > > Looks a little quirky, but it's board-specific. The OSK board seems > to wire that "General Purpose I/O" pin from the chip for some kind > of USB-related output. (Not VBUS switching; that uses a GPIO from > the TPS65010 battery management chip, not the OMAP-5912 chip.) > It'd be better to claim it in the driver probe() routine, release it in > remove(); the claim is just to catch inter-driver confusion. Well, the patch ought to reproduce the existing behavior pretty closely. If it still needs to be changed, that can be done separately. Alan Stern Signed-off-by: Alan Stern <[EMAIL PROTECTED]> ===== drivers/usb/core/hcd-pci.c 1.63 vs edited ===== --- 1.63/drivers/usb/core/hcd-pci.c 2004-10-20 12:53:13 -04:00 +++ edited/drivers/usb/core/hcd-pci.c 2004-10-21 16:58:54 -04:00 @@ -38,14 +38,6 @@ /*-------------------------------------------------------------------------*/ -static void hcd_pci_release(struct usb_bus *bus) -{ - struct usb_hcd *hcd = bus->hcpriv; - - if (hcd) - hcd->driver->hcd_free(hcd); -} - /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -68,7 +60,7 @@ void __iomem *base; struct usb_hcd *hcd; int retval, region; - char buf [8], *bufp = buf; + char *product_desc = NULL; if (usb_disabled()) return -ENODEV; @@ -83,7 +75,8 @@ dev_err (&dev->dev, "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", pci_name(dev)); - return -ENODEV; + retval = -ENODEV; + goto clean_1; } if (driver->flags & HCD_MEMORY) { // EHCI, OHCI @@ -92,17 +85,14 @@ len = pci_resource_len (dev, 0); if (!request_mem_region (resource, len, driver->description)) { dev_dbg (&dev->dev, "controller already in use\n"); - return -EBUSY; + retval = -EBUSY; + goto clean_1; } base = ioremap_nocache (resource, len); if (base == NULL) { dev_dbg (&dev->dev, "error mapping memory\n"); retval = -EFAULT; -clean_1: - release_mem_region (resource, len); - dev_err (&dev->dev, "init %s fail, %d\n", - pci_name(dev), retval); - return retval; + goto clean_2; } } else { // UHCI @@ -119,94 +109,43 @@ } if (region == PCI_ROM_RESOURCE) { dev_dbg (&dev->dev, "no i/o regions available\n"); - return -EBUSY; - } - base = (void __iomem *) resource; - } - - // driver->reset(), later on, will transfer device from - // control by SMM/BIOS to control by Linux (if needed) - - hcd = driver->hcd_alloc (); - if (hcd == NULL){ - dev_dbg (&dev->dev, "hcd alloc fail\n"); - retval = -ENOMEM; -clean_2: - if (driver->flags & HCD_MEMORY) { - iounmap (base); + retval = -EBUSY; goto clean_1; - } else { - release_region (resource, len); - dev_err (&dev->dev, "init %s fail, %d\n", - pci_name(dev), retval); - return retval; } + base = (void __iomem *) resource; } - // hcd zeroed everything - hcd->regs = base; - hcd->region = region; - pci_set_drvdata (dev, hcd); - hcd->driver = driver; - hcd->description = driver->description; - hcd->self.bus_name = pci_name(dev); #ifdef CONFIG_PCI_NAMES - hcd->product_desc = dev->pretty_name; -#else - if (hcd->product_desc == NULL) - hcd->product_desc = "USB Host Controller"; + product_desc = dev->pretty_name; #endif - hcd->self.controller = &dev->dev; - if ((retval = hcd_buffer_create (hcd)) != 0) { -clean_3: - driver->hcd_free (hcd); - goto clean_2; - } - - dev_info (hcd->self.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->self.controller, "can't reset\n"); + if ((retval = usb_hcd_init1 (&hcd, driver, base, region, &dev->dev, + pci_name(dev), product_desc)) != 0) goto clean_3; - } - hcd->state = USB_STATE_HALT; + pci_set_drvdata (dev, hcd); pci_set_master (dev); -#ifndef __sparc__ - sprintf (buf, "%d", dev->irq); -#else - bufp = __irq_itoa(dev->irq); -#endif - retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, - hcd->description, hcd); - if (retval != 0) { - dev_err (hcd->self.controller, - "request interrupt %s failed\n", bufp); - goto clean_3; - } - hcd->irq = dev->irq; - - dev_info (hcd->self.controller, "irq %s, %s 0x%lx\n", bufp, - (driver->flags & HCD_MEMORY) ? "pci mem" : "io base", - resource); - usb_bus_init (&hcd->self); - hcd->self.op = &usb_hcd_operations; - hcd->self.hcpriv = (void *) hcd; - hcd->self.release = &hcd_pci_release; - init_timer (&hcd->rh_timer); - - INIT_LIST_HEAD (&hcd->dev_list); + if ((retval = usb_hcd_init2 (hcd, dev->irq, usb_hcd_irq, SA_SHIRQ, + resource)) != 0) + goto clean_4; + return retval; - usb_register_bus (&hcd->self); +clean_4: + pci_set_drvdata (dev, NULL); + usb_hcd_uninit1 (hcd); - if ((retval = driver->start (hcd)) < 0) { - dev_err (hcd->self.controller, "init error %d\n", retval); - usb_hcd_pci_remove (dev); - } +clean_3: + if (driver->flags & HCD_MEMORY) { + iounmap (base); +clean_2: + release_mem_region (resource, len); + } else + release_region (resource, len); + dev_err (&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); +clean_1: + pci_disable_device (dev); return retval; } EXPORT_SYMBOL (usb_hcd_pci_probe); @@ -229,39 +168,30 @@ void usb_hcd_pci_remove (struct pci_dev *dev) { struct usb_hcd *hcd; + const struct hc_driver *driver; + void __iomem *regs; + int region; - hcd = pci_get_drvdata(dev); + hcd = pci_get_drvdata (dev); if (!hcd) return; - dev_info (hcd->self.controller, "remove, state %x\n", hcd->state); - - if (in_interrupt ()) - BUG (); - - if (HCD_IS_RUNNING (hcd->state)) - hcd->state = USB_STATE_QUIESCING; - dev_dbg (hcd->self.controller, "roothub graceful disconnect\n"); - usb_disconnect (&hcd->self.root_hub); - - hcd->driver->stop (hcd); - hcd_buffer_destroy (hcd); - hcd->state = USB_STATE_HALT; - pci_set_drvdata(dev, NULL); - - free_irq (hcd->irq, hcd); - if (hcd->driver->flags & HCD_MEMORY) { - iounmap (hcd->regs); + driver = hcd->driver; + regs = hcd->regs; + region = hcd->region; + + usb_hcd_remove (hcd); + + pci_set_drvdata (dev, NULL); + if (driver->flags & HCD_MEMORY) { + iounmap (regs); release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0)); } else { - release_region (pci_resource_start (dev, hcd->region), - pci_resource_len (dev, hcd->region)); + release_region (pci_resource_start (dev, region), + pci_resource_len (dev, region)); } - - usb_deregister_bus (&hcd->self); - - pci_disable_device(dev); + pci_disable_device (dev); } EXPORT_SYMBOL (usb_hcd_pci_remove); ===== drivers/usb/core/hcd.c 1.161 vs edited ===== --- 1.161/drivers/usb/core/hcd.c 2004-10-20 12:38:07 -04:00 +++ edited/drivers/usb/core/hcd.c 2004-10-21 16:27:54 -04:00 @@ -312,7 +312,7 @@ // id 3 == vendor description } else if (id == 3) { sprintf (buf, "%s %s %s", UTS_SYSNAME, UTS_RELEASE, - hcd->description); + hcd->driver_desc); // unsupported IDs --> "protocol stall" } else @@ -1605,3 +1605,185 @@ } EXPORT_SYMBOL (usb_hc_died); +/*-------------------------------------------------------------------------*/ + +static void hcd_release(struct usb_bus *bus) +{ + struct usb_hcd *hcd = bus->hcpriv; + + if (hcd) + hcd->driver->hcd_free(hcd); +} + +/** + * usb_hcd_init1 - initialize a generic HCD structure + * @phcd: location to store the address of the new structure + * @regs: value to store in hcd->regs + * @region: value to store in hcd->region (PCI only) + * @driver: value to store in hcd->driver + * @dev: value to store in hcd->self.controller + * @bus_name: value to store in hcd->self.bus_name + * @product_desc: value to store in hcd->product_desc. If this is NULL + * and the hcd_alloc() routine doesn't fill in the product_desc pointer, + * a generic description string is used. + * + * This utility routine carries out many of the common tasks required for + * creating and initializing a usb_hcd structure. After the structure + * has been initialized, the HC driver can perform driver-dependent + * initialization and then finish up by calling usb_hcd_init2(). + */ +int usb_hcd_init1(struct usb_hcd **phcd, const struct hc_driver *driver, + void __iomem *regs, int region, + struct device *dev, + char *bus_name, char *product_desc) +{ + struct usb_hcd *hcd; + int retval; + + hcd = driver->hcd_alloc (); + if (hcd == NULL) { + dev_dbg (dev, "hcd alloc fail\n"); + return -ENOMEM; + } + + hcd->driver = driver; + hcd->regs = regs; +#ifdef CONFIG_PCI + hcd->region = region; +#endif + hcd->driver_desc = driver->description; + if (product_desc) + hcd->product_desc = product_desc; + else if (hcd->product_desc == NULL) + hcd->product_desc = "USB Host Controller"; + + hcd->self.controller = dev; + hcd->self.bus_name = bus_name; + + init_timer(&hcd->rh_timer); + INIT_LIST_HEAD(&hcd->dev_list); + + if ((retval = hcd_buffer_create(hcd)) != 0) { + dev_dbg(dev, "pool alloc failure\n"); + driver->hcd_free(hcd); + return retval; + } + + dev_info(dev, "%s\n", hcd->product_desc); + *phcd = hcd; + return retval; +} +EXPORT_SYMBOL (usb_hcd_init1); + +/** + * usb_hcd_uninit -- undo the initialization in usb_hcd_init1 + * @hcd: the usb_hcd structure to uninitialize + * + */ +void usb_hcd_uninit1(struct usb_hcd *hcd) +{ + hcd_buffer_destroy(hcd); + hcd->driver->hcd_free(hcd); +} +EXPORT_SYMBOL (usb_hcd_uninit1); + +/** + * usb_hcd_init2 - finish generic HCD structure initialization + * @hcd: the usb_hcd structure to initialize + * @irqnum: Interrupt line to allocate + * @irqfunc: IRQ handler function + * @irqflags: Interrupt type flags + * @resource: IO/memory resource value + * + * Finish the remaining parts of generic HCD initialization. + */ +int usb_hcd_init2(struct usb_hcd *hcd, + unsigned int irqnum, + irqreturn_t (*irqfunc)(int, void *, struct pt_regs *), + unsigned long irqflags, + unsigned long resource) +{ + char buf[8], *bufp = buf; + int retval; + + /* till now HC has been in an indeterminate state ... */ + if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) { + dev_err(hcd->self.controller, "can't reset\n"); + return retval; + } + hcd->state = USB_STATE_HALT; + + usb_bus_init(&hcd->self); + hcd->self.op = &usb_hcd_operations; + hcd->self.hcpriv = (void *) hcd; + if ((retval = usb_register_bus(&hcd->self)) < 0) + return retval; + + snprintf(hcd->description, sizeof(hcd->description), "%s:usb%d", + hcd->driver->description, hcd->self.busnum); + +#ifndef __sparc__ + sprintf(buf, "%d", irqnum); +#else + bufp = __irq_itoa(irqnum); +#endif + + if (irqnum >= 0) { + if ((retval = request_irq(irqnum, irqfunc, irqflags, + hcd->description, hcd)) != 0) { + dev_err(hcd->self.controller, + "request interrupt %s failed\n", bufp); + goto clean_1; + } + + dev_info(hcd->self.controller, "irq %s, %s 0x%lx\n", bufp, + (hcd->driver->flags & HCD_MEMORY) ? "pci mem" : + "io base", resource); + } + hcd->irq = irqnum; + + if ((retval = hcd->driver->start(hcd)) < 0) { + dev_err(hcd->self.controller, "init error %d\n", retval); + goto clean_2; + } + + hcd->self.release = &hcd_release; + return retval; + +clean_2: + if (irqnum >= 0) + free_irq(irqnum, hcd); +clean_1: + usb_deregister_bus(&hcd->self); + return retval; +} +EXPORT_SYMBOL (usb_hcd_init2); + +/** + * usb_hcd_remove - shutdown processing for generic HCDs + * @hcd: the usb_hcd structure to remove + * Context: !in_interrupt() + * + * Reverses the effects of usb_hcd_init2() and usb_hcd_init1(), first + * invoking the HCD's stop() method. As part of deregistering the bus, + * the HCD's hcd_free() method is called. + */ +void usb_hcd_remove(struct usb_hcd *hcd) +{ + dev_info(hcd->self.controller, "remove, state %x\n", hcd->state); + + if (HCD_IS_RUNNING (hcd->state)) + hcd->state = USB_STATE_QUIESCING; + + dev_dbg(hcd->self.controller, "roothub graceful disconnect\n"); + usb_disconnect(&hcd->self.root_hub); + + hcd->driver->stop(hcd); + hcd->state = USB_STATE_HALT; + + if (hcd->irq > 0) + free_irq(hcd->irq, hcd); + hcd_buffer_destroy(hcd); + usb_deregister_bus(&hcd->self); +} +EXPORT_SYMBOL (usb_hcd_remove); ===== drivers/usb/core/hcd.h 1.91 vs edited ===== --- 1.91/drivers/usb/core/hcd.h 2004-10-20 12:53:13 -04:00 +++ edited/drivers/usb/core/hcd.h 2004-10-21 16:58:02 -04:00 @@ -63,7 +63,8 @@ struct usb_bus self; /* hcd is-a bus */ const char *product_desc; /* product/vendor string */ - const char *description; /* "ehci-hcd" etc */ + const char *driver_desc; /* "ehci-hcd" etc */ + char description[24]; /* driver + bus # */ struct timer_list rh_timer; /* drives root hub */ struct list_head dev_list; /* devices on this bus */ @@ -71,7 +72,7 @@ /* * hardware info/state */ - struct hc_driver *driver; /* hw-specific hooks */ + const struct hc_driver *driver; /* hw-specific hooks */ unsigned saw_irq : 1; unsigned can_wakeup:1; /* hw supports wakeup? */ unsigned remote_wakeup:1;/* sw should use wakeup? */ @@ -239,6 +240,19 @@ int mem_flags, dma_addr_t *dma); void hcd_buffer_free (struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma); + +extern int usb_hcd_init1(struct usb_hcd **phcd, + const struct hc_driver *driver, + void __iomem *regs, int region, + struct device *dev, + char *bus_name, char *product_desc); +extern void usb_hcd_uninit1(struct usb_hcd *hcd); +extern int usb_hcd_init2(struct usb_hcd *hcd, + unsigned int irqnum, + irqreturn_t (*irqfunc)(int, void *, struct pt_regs *), + unsigned long irqflags, + unsigned long resource); +extern void usb_hcd_remove(struct usb_hcd *hcd); /* generic bus glue, needed for host controllers that don't use PCI */ extern struct usb_operations usb_hcd_operations; ===== drivers/usb/host/ohci-lh7a404.c 1.3 vs edited ===== --- 1.3/drivers/usb/host/ohci-lh7a404.c 2004-10-20 12:38:09 -04:00 +++ edited/drivers/usb/host/ohci-lh7a404.c 2004-10-21 16:56:24 -04:00 @@ -64,8 +64,6 @@ /*-------------------------------------------------------------------------*/ -void usb_hcd_lh7a404_remove (struct usb_hcd *, struct platform_device *); - /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -84,94 +82,49 @@ struct platform_device *dev) { int retval; - struct usb_hcd *hcd = 0; + unsigned int *addr; - unsigned int *addr = NULL; + if (dev->resource[1].flags != IORESOURCE_IRQ) { + dev_dbg(&dev->dev, "resource[1] is not IORESOURCE_IRQ\n"); + return -ENOMEM; + } if (!request_mem_region(dev->resource[0].start, - dev->resource[0].end - - dev->resource[0].start + 1, hcd_name)) { - pr_debug("request_mem_region failed"); + dev->resource[0].end - dev->resource[0].start + 1, + hcd_name)) { + dev_dbg(&dev->dev, "request_mem_region failed\n"); return -EBUSY; } - - - lh7a404_start_hc(dev); - + addr = ioremap(dev->resource[0].start, - dev->resource[0].end - - dev->resource[0].start + 1); + dev->resource[0].end - dev->resource[0].start + 1); if (!addr) { - pr_debug("ioremap failed"); + dev_dbg(&dev->dev, "ioremap failed\n"); retval = -ENOMEM; goto err1; } + lh7a404_start_hc(dev); - hcd = driver->hcd_alloc (); - if (hcd == NULL){ - pr_debug ("hcd_alloc failed"); - retval = -ENOMEM; - goto err1; - } - - if(dev->resource[1].flags != IORESOURCE_IRQ){ - pr_debug ("resource[1] is not IORESOURCE_IRQ"); - retval = -ENOMEM; - goto err1; - } - - hcd->driver = (struct hc_driver *) driver; - hcd->description = driver->description; - hcd->irq = dev->resource[1].start; - hcd->regs = addr; - hcd->self.controller = &dev->dev; - - retval = hcd_buffer_create (hcd); - if (retval != 0) { - pr_debug ("pool alloc fail"); - goto err1; - } - - retval = request_irq (hcd->irq, usb_hcd_lh7a404_hcim_irq, SA_INTERRUPT, - hcd->description, hcd); - if (retval != 0) { - pr_debug("request_irq failed"); - retval = -EBUSY; + retval = usb_hcd_init1(hcd_out, driver, addr, 0, &dev->dev, + "lh7a404", "LH7A404 OHCI"); + if (retval) goto err2; - } - pr_debug ("%s (LH7A404) at 0x%p, irq %d", - hcd->description, hcd->regs, hcd->irq); - - usb_bus_init (&hcd->self); - hcd->self.op = &usb_hcd_operations; - hcd->self.hcpriv = (void *) hcd; - hcd->self.bus_name = "lh7a404"; - hcd->product_desc = "LH7A404 OHCI"; - - INIT_LIST_HEAD (&hcd->dev_list); - - usb_register_bus (&hcd->self); - - if ((retval = driver->start (hcd)) < 0) - { - usb_hcd_lh7a404_remove(hcd, dev); - return retval; - } - - *hcd_out = hcd; + retval = usb_hcd_init2(*hcd_out, dev->resource[1].start, + usb_hcd_lh7a404_hcim_irq, SA_INTERRUPT, + (unsigned long) addr); + if (retval) + goto err3; return 0; + err3: + usb_hcd_uninit1(*hcd_out); err2: - hcd_buffer_destroy (hcd); - if (hcd) - driver->hcd_free(hcd); - err1: lh7a404_stop_hc(dev); + err1: release_mem_region(dev->resource[0].start, - dev->resource[0].end - - dev->resource[0].start + 1); + dev->resource[0].end - dev->resource[0].start + 1); return retval; } @@ -191,33 +144,10 @@ */ void usb_hcd_lh7a404_remove (struct usb_hcd *hcd, struct platform_device *dev) { - void *base; - - pr_debug ("remove: %s, state %x", hcd->self.bus_name, hcd->state); - - if (in_interrupt ()) - BUG (); - - hcd->state = USB_STATE_QUIESCING; - - pr_debug ("%s: roothub graceful disconnect", hcd->self.bus_name); - usb_disconnect (&hcd->self.root_hub); - - hcd->driver->stop (hcd); - hcd->state = USB_STATE_HALT; - - free_irq (hcd->irq, hcd); - hcd_buffer_destroy (hcd); - - usb_deregister_bus (&hcd->self); - - base = hcd->regs; - hcd->driver->hcd_free (hcd); - + usb_hcd_remove(hcd); lh7a404_stop_hc(dev); release_mem_region(dev->resource[0].start, - dev->resource[0].end - - dev->resource[0].start + 1); + dev->resource[0].end - dev->resource[0].start + 1); } /*-------------------------------------------------------------------------*/ ===== drivers/usb/host/ohci-omap.c 1.16 vs edited ===== --- 1.16/drivers/usb/host/ohci-omap.c 2004-10-20 12:38:09 -04:00 +++ edited/drivers/usb/host/ohci-omap.c 2004-10-21 17:04:35 -04:00 @@ -266,8 +266,6 @@ /*-------------------------------------------------------------------------*/ -void usb_hcd_omap_remove (struct usb_hcd *, struct platform_device *); - /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -300,74 +298,39 @@ } if (!request_mem_region(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start + 1, hcd_name)) { + pdev->resource[0].end - pdev->resource[0].start + 1, + hcd_name)) { dev_dbg(&pdev->dev, "request_mem_region failed\n"); return -EBUSY; } - hcd = driver->hcd_alloc (); - if (hcd == NULL){ - dev_dbg(&pdev->dev, "hcd_alloc failed\n"); - retval = -ENOMEM; + retval = usb_hcd_init1(&hcd, driver, + (void __iomem *) pdev->resource[0].start, 0, + &pdev->dev, pdev->dev.bus_id, "OMAP OHCI"); + if (retval) goto err1; - } + dev_set_drvdata(&pdev->dev, hcd); ohci = hcd_to_ohci(hcd); - hcd->driver = (struct hc_driver *) driver; - hcd->description = driver->description; - hcd->irq = pdev->resource[1].start; - hcd->regs = (void *)pdev->resource[0].start; - hcd->self.controller = &pdev->dev; - retval = omap_start_hc(ohci, pdev); if (retval < 0) goto err2; - retval = hcd_buffer_create (hcd); - if (retval != 0) { - dev_dbg(&pdev->dev, "pool alloc fail\n"); - goto err1; - } - - retval = request_irq (hcd->irq, usb_hcd_irq, - SA_INTERRUPT, hcd->description, hcd); - if (retval != 0) { - dev_dbg(&pdev->dev, "request_irq failed\n"); - retval = -EBUSY; - goto err2; - } - - dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq); - - usb_bus_init (&hcd->self); - hcd->self.op = &usb_hcd_operations; - hcd->self.hcpriv = (void *) hcd; - hcd->self.bus_name = pdev->dev.bus_id; - hcd->product_desc = "OMAP OHCI"; - - INIT_LIST_HEAD (&hcd->dev_list); - usb_register_bus (&hcd->self); - - if ((retval = driver->start (hcd)) < 0) - { - usb_hcd_omap_remove(hcd, pdev); - return retval; - } - + retval = usb_hcd_init2(hcd, pdev->resource[1].start, + usb_hcd_irq, SA_INTERRUPT, (unsigned long) hcd->regs); + if (retval) + goto err3; return 0; + err3: + omap_stop_hc(pdev); err2: - hcd_buffer_destroy (hcd); - if (hcd) - driver->hcd_free(hcd); + usb_hcd_uninit1(hcd); err1: - omap_stop_hc(pdev); - release_mem_region(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start + 1); - - dev_set_drvdata(&pdev->dev, 0); + pdev->resource[0].end - pdev->resource[0].start + 1); + dev_set_drvdata(&pdev->dev, NULL); return retval; } @@ -387,36 +350,12 @@ */ void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) { - void *base; - - dev_info(&pdev->dev, "remove: state %x\n", hcd->state); - - if (in_interrupt ()) - BUG (); - - hcd->state = USB_STATE_QUIESCING; - - dev_dbg(&pdev->dev, "roothub graceful disconnect\n"); - usb_disconnect (&hcd->self.root_hub); - - hcd->driver->stop (hcd); - hcd_buffer_destroy (hcd); - hcd->state = USB_STATE_HALT; - + usb_hcd_remove(hcd); if (machine_is_omap_osk()) omap_free_gpio(9); - - free_irq (hcd->irq, hcd); - - usb_deregister_bus (&hcd->self); - - base = hcd->regs; - hcd->driver->hcd_free (hcd); - omap_stop_hc(pdev); - release_mem_region(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start + 1); + pdev->resource[0].end - pdev->resource[0].start + 1); } /*-------------------------------------------------------------------------*/ ===== drivers/usb/host/ohci-pxa27x.c 1.1 vs edited ===== --- 1.1/drivers/usb/host/ohci-pxa27x.c 2004-10-20 12:28:19 -04:00 +++ edited/drivers/usb/host/ohci-pxa27x.c 2004-10-21 17:04:45 -04:00 @@ -151,8 +151,6 @@ /*-------------------------------------------------------------------------*/ -void usb_hcd_pxa27x_remove (struct usb_hcd *, struct platform_device *); - /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -171,17 +169,28 @@ struct platform_device *dev) { int retval; - struct usb_hcd *hcd = 0; + unsigned int *addr; - unsigned int *addr = NULL; + if (dev->resource[1].flags != IORESOURCE_IRQ) { + dev_dbg(&dev->dev, "resource[1] is not IORESOURCE_IRQ\n"); + return -ENOMEM; + } if (!request_mem_region(dev->resource[0].start, dev->resource[0].end - dev->resource[0].start + 1, hcd_name)) { - pr_debug("request_mem_region failed"); + dev_dbg(&dev->dev, "request_mem_region failed\n"); return -EBUSY; } + addr = ioremap(dev->resource[0].start, + dev->resource[0].end - dev->resource[0].start + 1); + if (!addr) { + dev_dbg(&dev->dev, "ioremap failed\n"); + retval = -ENOMEM; + goto err1; + } + pxa27x_start_hc(dev); /* Select Power Management Mode */ @@ -189,85 +198,33 @@ /* If choosing PMM_PERPORT_MODE, we should set the port power before we use it. */ if (pxa27x_ohci_set_port_power(1) < 0) - printk(KERN_ERR "Setting port 1 power failed.\n"); + dev_err(&dev->dev, "Setting port 1 power failed.\n"); if (pxa27x_ohci_clear_port_power(2) < 0) - printk(KERN_ERR "Setting port 2 power failed.\n"); + dev_err(&dev->dev, "Setting port 2 power failed.\n"); if (pxa27x_ohci_clear_port_power(3) < 0) - printk(KERN_ERR "Setting port 3 power failed.\n"); - - addr = ioremap(dev->resource[0].start, - dev->resource[0].end - dev->resource[0].start + 1); - if (!addr) { - pr_debug("ioremap failed"); - retval = -ENOMEM; - goto err1; - } + dev_err(&dev->dev, "Setting port 3 power failed.\n"); - hcd = driver->hcd_alloc (); - if (hcd == NULL){ - pr_debug ("hcd_alloc failed"); - retval = -ENOMEM; - goto err1; - } - - if(dev->resource[1].flags != IORESOURCE_IRQ){ - pr_debug ("resource[1] is not IORESOURCE_IRQ"); - retval = -ENOMEM; - goto err1; - } - - hcd->driver = (struct hc_driver *) driver; - hcd->description = driver->description; - hcd->irq = dev->resource[1].start; - hcd->regs = addr; - hcd->self.controller = &dev->dev; - - retval = hcd_buffer_create (hcd); - if (retval != 0) { - pr_debug ("pool alloc fail"); - goto err1; - } - - retval = request_irq (hcd->irq, usb_hcd_irq, SA_INTERRUPT, - hcd->description, hcd); - if (retval != 0) { - pr_debug("request_irq(%d) failed with retval %d\n",hcd->irq,retval); - retval = -EBUSY; + retval = usb_hcd_init1(hcd_out, driver, addr, 0, &dev->dev, + "pxa27x", "PXA27x OHCI"); + if (retval) goto err2; - } - pr_debug ("%s (pxa27x) at 0x%p, irq %d", - hcd->description, hcd->regs, hcd->irq); - - usb_bus_init (&hcd->self); - hcd->self.op = &usb_hcd_operations; - hcd->self.hcpriv = (void *) hcd; - hcd->self.bus_name = "pxa27x"; - hcd->product_desc = "PXA27x OHCI"; - - INIT_LIST_HEAD (&hcd->dev_list); - - usb_register_bus (&hcd->self); - - if ((retval = driver->start (hcd)) < 0) { - usb_hcd_pxa27x_remove(hcd, dev); - return retval; - } - - *hcd_out = hcd; + retval = usb_hcd_init2(*hcd_out, dev->resource[1].start, + usb_hcd_irq, SA_INTERRUPT, + (unsigned long) addr); + if (retval) + goto err3; return 0; + err3: + usb_hcd_uninit1(*hcd_out); err2: - hcd_buffer_destroy (hcd); - if (hcd) - driver->hcd_free(hcd); - err1: pxa27x_stop_hc(dev); + err1: release_mem_region(dev->resource[0].start, - dev->resource[0].end - - dev->resource[0].start + 1); + dev->resource[0].end - dev->resource[0].start + 1); return retval; } @@ -287,29 +244,7 @@ */ void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev) { - void *base; - - pr_debug ("remove: %s, state %x", hcd->self.bus_name, hcd->state); - - if (in_interrupt ()) - BUG (); - - hcd->state = USB_STATE_QUIESCING; - - pr_debug ("%s: roothub graceful disconnect", hcd->self.bus_name); - usb_disconnect (&hcd->self.root_hub); - - hcd->driver->stop (hcd); - hcd->state = USB_STATE_HALT; - - free_irq (hcd->irq, hcd); - hcd_buffer_destroy (hcd); - - usb_deregister_bus (&hcd->self); - - base = hcd->regs; - hcd->driver->hcd_free (hcd); - + usb_hcd_remove(hcd); pxa27x_stop_hc(dev); release_mem_region(dev->resource[0].start, dev->resource[0].end - dev->resource[0].start + 1); ===== drivers/usb/host/ohci-sa1111.c 1.40 vs edited ===== --- 1.40/drivers/usb/host/ohci-sa1111.c 2004-10-20 12:38:10 -04:00 +++ edited/drivers/usb/host/ohci-sa1111.c 2004-10-21 17:04:56 -04:00 @@ -131,8 +131,6 @@ /*-------------------------------------------------------------------------*/ -void usb_hcd_sa1111_remove (struct usb_hcd *, struct sa1111_dev *); - /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -152,69 +150,29 @@ struct sa1111_dev *dev) { int retval; - struct usb_hcd *hcd = 0; if (!request_mem_region(dev->res.start, dev->res.end - dev->res.start + 1, hcd_name)) { - dbg("request_mem_region failed"); + dev_dbg(&dev->dev, "request_mem_region failed\n"); return -EBUSY; } sa1111_start_hc(dev); - hcd = driver->hcd_alloc (); - if (hcd == NULL){ - dbg ("hcd_alloc failed"); - retval = -ENOMEM; + retval = usb_hcd_init1(hcd_out, driver, dev->mapbase, 0, &dev->dev, + "sa1111", "SA-1111 OHCI"); + if (retval) goto err1; - } - - hcd->driver = (struct hc_driver *) driver; - hcd->description = driver->description; - hcd->irq = dev->irq[1]; - hcd->regs = dev->mapbase; - hcd->self.controller = &dev->dev; - - retval = hcd_buffer_create (hcd); - if (retval != 0) { - dbg ("pool alloc fail"); - goto err1; - } - retval = request_irq (hcd->irq, usb_hcd_sa1111_hcim_irq, SA_INTERRUPT, - hcd->description, hcd); - if (retval != 0) { - dbg("request_irq failed"); - retval = -EBUSY; + retval = usb_hcd_init2(*hcd_out, dev->irq[1], + usb_hcd_sa1111_hcim_irq, SA_INTERRUPT, + (unsigned long) hcd->regs); + if (retval) goto err2; - } - - info ("%s (SA-1111) at 0x%p, irq %d\n", - hcd->description, hcd->regs, hcd->irq); - - usb_bus_init (&hcd->self); - hcd->self.op = &usb_hcd_operations; - hcd->self.hcpriv = (void *) hcd; - hcd->self.bus_name = "sa1111"; - hcd->product_desc = "SA-1111 OHCI"; - - INIT_LIST_HEAD (&hcd->dev_list); - - usb_register_bus (&hcd->self); - - if ((retval = driver->start (hcd)) < 0) - { - usb_hcd_sa1111_remove(hcd, dev); - return retval; - } - - *hcd_out = hcd; return 0; err2: - hcd_buffer_destroy (hcd); - if (hcd) - driver->hcd_free(hcd); + usb_hcd_uninit1(*hcd_out); err1: sa1111_stop_hc(dev); release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1); @@ -237,29 +195,7 @@ */ void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev) { - void *base; - - info ("remove: %s, state %x", hcd->self.bus_name, hcd->state); - - if (in_interrupt ()) - BUG (); - - hcd->state = USB_STATE_QUIESCING; - - dbg ("%s: roothub graceful disconnect", hcd->self.bus_name); - usb_disconnect (&hcd->self.root_hub); - - hcd->driver->stop (hcd); - hcd->state = USB_STATE_HALT; - - free_irq (hcd->irq, hcd); - hcd_buffer_destroy (hcd); - - usb_deregister_bus (&hcd->self); - - base = hcd->regs; - hcd->driver->hcd_free (hcd); - + usb_hcd_remove(hcd); sa1111_stop_hc(dev); release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1); } ------------------------------------------------------- This SF.net email is sponsored by: IT Product Guide on ITManagersJournal Use IT products in your business? Tell us what you think of them. Give us Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more http://productguide.itmanagersjournal.com/guidepromo.tmpl _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel