# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.369.105.15 -> 1.369.105.16 # drivers/usb/host/ohci-hcd.c 1.9 -> 1.10 # drivers/usb/host/ohci-hub.c 1.4 -> 1.5 # drivers/usb/host/usb-ohci.c 1.31 -> 1.32 # drivers/usb/host/ehci-dbg.c 1.2 -> 1.3 # drivers/usb/host/ehci-q.c 1.9 -> 1.10 # drivers/usb/host/ohci-dbg.c 1.4 -> 1.5 # drivers/usb/core/hcd.h 1.5 -> 1.6 # include/linux/usb.h 1.26 -> 1.27 # drivers/usb/host/ehci-hub.c 1.7 -> 1.8 # drivers/usb/host/usb-uhci.c 1.32 -> 1.33 # drivers/usb/core/hub.c 1.22 -> 1.23 # drivers/usb/core/usb.c 1.41 -> 1.42 # drivers/usb/core/hcd.c 1.15 -> 1.16 # drivers/usb/host/ehci-hcd.c 1.11 -> 1.12 # drivers/usb/host/uhci.c 1.39 -> 1.40 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/04/09 david-b@pacbell.net 1.369.105.16 # [PATCH] USB physical paths id # # This provides something that gets discussed regularly: stable # device IDs. Straightforward; most of it was already present: # # - Moves "bus_name" out of HCD framework into usb_bus. # This accounts for _by far the bulk_ of this patch, since # every use of that original field needed to change. # # - Make Vojtech's usb_make_path() use bus_name instead # of unstable bus numbers ... and usb_device->devpath # instead of recomputing that same info. Combine two # stable IDs, and the result is still stable. And since both # are precomputed, usb_make_path() turns into only an # error check wrapped around snprintf() ... so I inlined it. # # - Minor tweak to usb_device->devpath construction. It # still uses "/" for the root hub (better suggestions?) but # Vojtech wanted "." for separators, so I changed that. # # - The older HCDs (uhci.c etc) initialize usb_bus.bus_name, # as well as the sharable HCD framework # # - HCD framework no longer uses "bus" member. # # These IDs are currently exposed in "input" hotplugging, and # my next patch addresses that for USB network devices. # -------------------------------------------- # diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c --- a/drivers/usb/core/hcd.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/core/hcd.c Tue Apr 16 11:36:06 2002 @@ -310,7 +310,7 @@ // serial number } else if (id == 1) { - strcpy (buf, hcd->bus_name); + strcpy (buf, hcd->self.bus_name); // product description } else if (id == 2) { @@ -406,7 +406,7 @@ case DeviceOutRequest | USB_REQ_SET_ADDRESS: // wValue == urb->dev->devaddr dbg ("%s root hub device address %d", - hcd->bus_name, wValue); + hcd->self.bus_name, wValue); break; /* INTERFACE REQUESTS (no defined feature/status flags) */ @@ -520,7 +520,7 @@ && rh_status_urb (hcd, urb) != 0) { /* another driver snuck in? */ dbg ("%s, can't resubmit roothub status urb?", - hcd->bus_name); + hcd->self.bus_name); spin_unlock_irqrestore (&hcd_data_lock, flags); BUG (); } @@ -1051,8 +1051,7 @@ usb_init_bus (&hcd->self); hcd->self.op = &hcd_operations; hcd->self.hcpriv = (void *) hcd; - hcd->bus = &hcd->self; - hcd->bus_name = dev->slot_name; + hcd->self.bus_name = dev->slot_name; hcd->product_desc = dev->name; INIT_LIST_HEAD (&hcd->dev_list); @@ -1089,16 +1088,15 @@ hcd = pci_get_drvdata(dev); if (!hcd) return; - info ("remove: %s, state %x", hcd->bus_name, hcd->state); + info ("remove: %s, state %x", hcd->self.bus_name, hcd->state); if (in_interrupt ()) BUG (); - hub = hcd->bus->root_hub; + hub = hcd->self.root_hub; hcd->state = USB_STATE_QUIESCING; - dbg ("%s: roothub graceful disconnect", hcd->bus_name); + dbg ("%s: roothub graceful disconnect", hcd->self.bus_name); usb_disconnect (&hub); - // usb_disconnect (&hcd->bus->root_hub); hcd->driver->stop (hcd); hcd->state = USB_STATE_HALT; @@ -1113,10 +1111,9 @@ pci_resource_len (dev, hcd->region)); } - usb_deregister_bus (hcd->bus); + usb_deregister_bus (&hcd->self); if (atomic_read (&hcd->self.refcnt) != 1) - err ("usb_hcd_pci_remove %s, count != 1", hcd->bus_name); - hcd->bus = NULL; + err ("usb_hcd_pci_remove %s, count != 1", hcd->self.bus_name); hcd->driver->hcd_free (hcd); } @@ -1164,7 +1161,7 @@ int retval; hcd = pci_get_drvdata(dev); - info ("suspend %s to state %d", hcd->bus_name, state); + info ("suspend %s to state %d", hcd->self.bus_name, state); pci_save_state (dev, hcd->pci_state); @@ -1193,12 +1190,12 @@ int retval; hcd = pci_get_drvdata(dev); - info ("resume %s", hcd->bus_name); + info ("resume %s", hcd->self.bus_name); /* guard against multiple resumes (APM bug?) */ atomic_inc (&hcd->resume_count); if (atomic_read (&hcd->resume_count) != 1) { - err ("concurrent PCI resumes for %s", hcd->bus_name); + err ("concurrent PCI resumes for %s", hcd->self.bus_name); retval = 0; goto done; } @@ -1215,7 +1212,7 @@ retval = hcd->driver->resume (hcd); if (!HCD_IS_RUNNING (hcd->state)) { - dbg ("resume %s failure, retval %d", hcd->bus_name, retval); + dbg ("resume %s failure, retval %d", hcd->self.bus_name, retval); hc_died (hcd); // FIXME: recover, reset etc. } else { @@ -1290,7 +1287,7 @@ list_for_each (urblist, &dev->urb_list) { urb = list_entry (urblist, struct urb, urb_list); dbg ("shutdown %s urb %p pipe %x, current status %d", - hcd->bus_name, urb, urb->pipe, urb->status); + hcd->self.bus_name, urb, urb->pipe, urb->status); if (urb->status == -EINPROGRESS) urb->status = -ESHUTDOWN; } @@ -1534,7 +1531,7 @@ * since we report some queuing/setup errors ourselves */ urb = usb_get_urb (urb); - if (urb->dev == hcd->bus->root_hub) + if (urb->dev == hcd->self.root_hub) status = rh_urb_enqueue (hcd, urb); else status = hcd->driver->urb_enqueue (hcd, urb, mem_flags); @@ -1686,7 +1683,7 @@ && HCD_IS_RUNNING (hcd->state) && !retval) { dbg ("%s: wait for giveback urb %p", - hcd->bus_name, urb); + hcd->self.bus_name, urb); wait_for_completion (&splice.done); } else if ((urb->transfer_flags & USB_ASYNC_UNLINK) && retval == 0) { return -EINPROGRESS; @@ -1698,7 +1695,7 @@ bye: if (retval) dbg ("%s: hcd_unlink_urb fail %d", - hcd ? hcd->bus_name : "(no bus?)", + hcd ? hcd->self.bus_name : "(no bus?)", retval); return retval; } @@ -1731,7 +1728,7 @@ /* device driver problem with refcounts? */ if (!list_empty (&dev->urb_list)) { dbg ("free busy dev, %s devnum %d (bug!)", - hcd->bus_name, udev->devnum); + hcd->self.bus_name, udev->devnum); return -EINVAL; } diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/core/hcd.h Tue Apr 16 11:36:06 2002 @@ -35,10 +35,8 @@ /* * housekeeping */ - struct usb_bus *bus; /* FIXME only use "self" */ struct usb_bus self; /* hcd is-a bus */ - const char *bus_name; const char *product_desc; /* product/vendor string */ const char *description; /* "ehci-hcd" etc */ diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/core/hub.c Tue Apr 16 11:36:06 2002 @@ -765,23 +765,23 @@ * devices by location for diagnostics, tools, etc. The * string is a path along hub ports, from the root. Each * device's id will be stable until USB is re-cabled, and - * hubs are often labled with these port numbers. + * hubs are often labeled with these port numbers. * - * Initial size: "/NN" times five hubs + NUL = 16 bytes max + * Initial size: ".NN" times five hubs + NUL = 16 bytes max * (quite rare, since most hubs have 4-6 ports). */ pdev = dev->parent; - if (pdev->devpath [1] != '\0') /* parent not root */ + if (pdev->devpath [0] != '/') /* parent not root */ len = snprintf (dev->devpath, sizeof dev->devpath, - "%s/%d", pdev->devpath, port + 1); - else /* root == "/", root port 2 == "/2" */ + "%s.%d", pdev->devpath, port + 1); + else /* root == "/", root port 2 == "2", port 3 that hub "/2.3" */ len = snprintf (dev->devpath, sizeof dev->devpath, - "/%d", port + 1); + "%d", port + 1); if (len == sizeof dev->devpath) warn ("devpath size! usb/%03d/%03d path %s", dev->bus->busnum, dev->devnum, dev->devpath); - info("new USB device on bus %d path %s, assigned address %d", - dev->bus->busnum, dev->devpath, dev->devnum); + info("new USB device %s-%s, assigned address %d", + dev->bus->bus_name, dev->devpath, dev->devnum); /* put the device in the global device tree */ dev->dev.parent = &dev->parent->dev; diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/core/usb.c Tue Apr 16 11:36:06 2002 @@ -2407,56 +2407,6 @@ return err; } -/** - * usb_make_path - returns device path in the hub tree - * @dev: the device whose path is being constructed - * @buf: where to put the string - * @size: how big is "buf"? - * Context: !in_interrupt () - * - * Returns length of the string (>= 0) or out of memory status (< 0). - * - * NOTE: prefer to use use dev->devpath directly. - */ -int usb_make_path(struct usb_device *dev, char *buf, size_t size) -{ - struct usb_device *pdev = dev->parent; - char *tmp; - char *port; - int i; - - if (!(port = kmalloc(size, GFP_KERNEL))) - return -ENOMEM; - if (!(tmp = kmalloc(size, GFP_KERNEL))) { - kfree(port); - return -ENOMEM; - } - - *port = 0; - while (pdev) { - for (i = 0; i < pdev->maxchild; i++) - if (pdev->children[i] == dev) - break; - - if (pdev->children[i] != dev) { - kfree(port); - kfree(tmp); - return -ENODEV; - } - - strcpy(tmp, port); - snprintf(port, size, strlen(port) ? "%d.%s" : "%d", i + 1, tmp); - - dev = pdev; - pdev = dev->parent; - } - - snprintf(buf, size, "usb%d:%s", dev->bus->busnum, port); - kfree(port); - kfree(tmp); - return strlen(buf); -} - /* * By the time we get here, the device has gotten a new device ID * and is in the default state. We need to identify the thing and diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c --- a/drivers/usb/host/ehci-dbg.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/host/ehci-dbg.c Tue Apr 16 11:36:06 2002 @@ -55,7 +55,7 @@ strcat(buf, tmp); } dbg ("%s: %s portroute %s", - ehci->hcd.bus_name, label, + ehci->hcd.self.bus_name, label, buf); } } diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c --- a/drivers/usb/host/ehci-hcd.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/host/ehci-hcd.c Tue Apr 16 11:36:06 2002 @@ -248,7 +248,7 @@ ehci->tasklet.data = (unsigned long) ehci; /* wire up the root hub */ - hcd->bus->root_hub = udev = usb_alloc_dev (NULL, hcd->bus); + hcd->self.root_hub = udev = usb_alloc_dev (NULL, &hcd->self); if (!udev) { done2: ehci_mem_cleanup (ehci); @@ -288,8 +288,7 @@ while (readl (&ehci->regs->status) & (STS_ASS | STS_PSS)) udelay (100); ehci_reset (ehci); - // usb_disconnect (udev); - hcd->bus->root_hub = 0; + hcd->self.root_hub = 0; usb_free_dev (udev); retval = -ENODEV; goto done2; @@ -304,7 +303,7 @@ { struct ehci_hcd *ehci = hcd_to_ehci (hcd); - dbg ("%s: stop", hcd->bus_name); + dbg ("%s: stop", hcd->self.bus_name); if (hcd->state == USB_STATE_RUNNING) ehci_ready (ehci); @@ -339,7 +338,7 @@ int ports; int i; - dbg ("%s: suspend to %d", hcd->bus_name, state); + dbg ("%s: suspend to %d", hcd->self.bus_name, state); ports = HCS_N_PORTS (ehci->hcs_params); @@ -356,7 +355,7 @@ if ((temp & PORT_PE) == 0 || (temp & PORT_OWNER) != 0) continue; -dbg ("%s: suspend port %d", hcd->bus_name, i); +dbg ("%s: suspend port %d", hcd->self.bus_name, i); temp |= PORT_SUSPEND; writel (temp, &ehci->regs->port_status [i]); } @@ -380,7 +379,7 @@ int ports; int i; - dbg ("%s: resume", hcd->bus_name); + dbg ("%s: resume", hcd->self.bus_name); ports = HCS_N_PORTS (ehci->hcs_params); @@ -400,7 +399,7 @@ if ((temp & PORT_PE) == 0 || (temp & PORT_SUSPEND) != 0) continue; -dbg ("%s: resume port %d", hcd->bus_name, i); +dbg ("%s: resume port %d", hcd->self.bus_name, i); temp |= PORT_RESUME; writel (temp, &ehci->regs->port_status [i]); readl (&ehci->regs->command); /* unblock posted writes */ @@ -472,7 +471,7 @@ /* PCI errors [4.15.2.4] */ if (unlikely ((status & STS_FATAL) != 0)) { - err ("%s: fatal error, state %x", hcd->bus_name, hcd->state); + err ("%s: fatal error, state %x", hcd->self.bus_name, hcd->state); ehci_reset (ehci); // generic layer kills/unlinks all urbs // then tasklet cleans up the rest @@ -547,7 +546,7 @@ unsigned long flags; dbg ("%s urb_dequeue %p qh state %d", - hcd->bus_name, urb, qh->qh_state); + hcd->self.bus_name, urb, qh->qh_state); switch (usb_pipetype (urb->pipe)) { case PIPE_CONTROL: @@ -608,7 +607,7 @@ /* ASSERT: nobody can be submitting urbs for this any more */ - dbg ("%s: free_config devnum %d", hcd->bus_name, udev->devnum); + dbg ("%s: free_config devnum %d", hcd->self.bus_name, udev->devnum); spin_lock_irqsave (&ehci->lock, flags); for (i = 0; i < 32; i++) { diff -Nru a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c --- a/drivers/usb/host/ehci-hub.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/host/ehci-hub.c Tue Apr 16 11:36:06 2002 @@ -41,14 +41,14 @@ /* if reset finished and it's still not enabled -- handoff */ if (!(port_status & PORT_PE)) { dbg ("%s port %d full speed, give to companion, 0x%x", - ehci->hcd.bus_name, index + 1, port_status); + ehci->hcd.self.bus_name, index + 1, port_status); // what happens if HCS_N_CC(params) == 0 ? port_status |= PORT_OWNER; writel (port_status, &ehci->regs->port_status [index]); } else - dbg ("%s port %d high speed", ehci->hcd.bus_name, index + 1); + dbg ("%s port %d high speed", ehci->hcd.self.bus_name, index + 1); return port_status; } @@ -306,11 +306,11 @@ if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT && PORT_USB11 (temp)) { dbg ("%s port %d low speed, give to companion", - hcd->bus_name, wIndex + 1); + hcd->self.bus_name, wIndex + 1); temp |= PORT_OWNER; } else { vdbg ("%s port %d reset", - hcd->bus_name, wIndex + 1); + hcd->self.bus_name, wIndex + 1); temp |= PORT_RESET; temp &= ~PORT_PE; diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c --- a/drivers/usb/host/ehci-q.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/host/ehci-q.c Tue Apr 16 11:36:06 2002 @@ -733,7 +733,7 @@ epnum |= 0x10; vdbg ("%s: submit_async urb %p len %d ep %d-%s qtd %p [qh %p]", - ehci->hcd.bus_name, urb, urb->transfer_buffer_length, + ehci->hcd.self.bus_name, urb, urb->transfer_buffer_length, epnum & 0x0f, (epnum & 0x10) ? "in" : "out", qtd, dev ? dev->ep [epnum] : (void *)~0); diff -Nru a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c --- a/drivers/usb/host/ohci-dbg.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/host/ohci-dbg.c Tue Apr 16 11:36:06 2002 @@ -89,7 +89,7 @@ continue; printed = 1; printk (KERN_DEBUG "%s, ohci %s frame %2d:", - label, ohci->hcd.bus_name, i); + label, ohci->hcd.self.bus_name, i); while (*ed_p != 0 && j--) { struct ed *ed = dma_to_ed (ohci, le32_to_cpup(ed_p)); printk (" %p/%08x;", ed, ed->hwINFO); @@ -99,7 +99,7 @@ } if (!printed) printk (KERN_DEBUG "%s, ohci %s, empty periodic schedule\n", - label, ohci->hcd.bus_name); + label, ohci->hcd.self.bus_name); } #endif @@ -229,7 +229,7 @@ static void ohci_dump (struct ohci_hcd *controller, int verbose) { - dbg ("OHCI controller %s state", controller->hcd.bus_name); + dbg ("OHCI controller %s state", controller->hcd.self.bus_name); // dumps some of the state we know about ohci_dump_status (controller); diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/host/ohci-hcd.c Tue Apr 16 11:36:06 2002 @@ -379,7 +379,7 @@ writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); dbg ("USB HC reset_hc %s: ctrl = 0x%x ;", - ohci->hcd.bus_name, + ohci->hcd.self.bus_name, readl (&ohci->regs->control)); /* Reset USB (needed by some controllers) */ @@ -449,7 +449,7 @@ mdelay ((roothub_a (ohci) >> 23) & 0x1fe); /* connect the virtual root hub */ - ohci->hcd.bus->root_hub = udev = usb_alloc_dev (NULL, ohci->hcd.bus); + ohci->hcd.self.root_hub = udev = usb_alloc_dev (NULL, &ohci->hcd.self); ohci->hcd.state = USB_STATE_READY; if (!udev) { ohci->disabled = 1; @@ -491,7 +491,7 @@ if (ints & OHCI_INTR_UE) { ohci->disabled++; - err ("OHCI Unrecoverable Error, %s disabled", hcd->bus_name); + err ("OHCI Unrecoverable Error, %s disabled", hcd->self.bus_name); // e.g. due to PCI Master/Target Abort #ifdef DEBUG @@ -530,7 +530,7 @@ struct ohci_hcd *ohci = hcd_to_ohci (hcd); dbg ("%s: stop %s controller%s", - hcd->bus_name, + hcd->self.bus_name, hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), ohci->disabled ? " (disabled)" : "" ); @@ -571,7 +571,7 @@ && hcd->pdev->device == 0x740c) { ohci->flags = OHCI_QUIRK_AMD756; info ("%s: AMD756 erratum 4 workaround", - hcd->bus_name); + hcd->self.bus_name); } /* Apple's OHCI driver has a lot of bizarre workarounds @@ -581,7 +581,7 @@ else if (hcd->pdev->vendor == 0x1045 && hcd->pdev->device == 0xc861) { info ("%s: WARNING: OPTi workarounds unavailable", - hcd->bus_name); + hcd->self.bus_name); } } #else @@ -601,7 +601,7 @@ } if (hc_start (ohci) < 0) { - err ("can't start %s", ohci->hcd.bus_name); + err ("can't start %s", ohci->hcd.self.bus_name); ohci_stop (hcd); return -EBUSY; } @@ -623,13 +623,13 @@ u16 cmd; if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) { - dbg ("can't suspend %s (state is %s)", hcd->bus_name, + dbg ("can't suspend %s (state is %s)", hcd->self.bus_name, hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS)); return -EIO; } /* act as if usb suspend can always be used */ - dbg ("%s: suspend to %d", hcd->bus_name, state); + dbg ("%s: suspend to %d", hcd->self.bus_name, state); ohci->sleeping = 1; /* First stop processing */ @@ -664,16 +664,16 @@ switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) { case OHCI_USB_RESET: - dbg ("%s suspend->reset ?", hcd->bus_name); + dbg ("%s suspend->reset ?", hcd->self.bus_name); break; case OHCI_USB_RESUME: - dbg ("%s suspend->resume ?", hcd->bus_name); + dbg ("%s suspend->resume ?", hcd->self.bus_name); break; case OHCI_USB_OPER: - dbg ("%s suspend->operational ?", hcd->bus_name); + dbg ("%s suspend->operational ?", hcd->self.bus_name); break; case OHCI_USB_SUSPEND: - dbg ("%s suspended", hcd->bus_name); + dbg ("%s suspended", hcd->self.bus_name); break; } @@ -711,8 +711,8 @@ ohci->disabled = 1; ohci->sleeping = 0; - if (ohci->hcd.bus->root_hub) - usb_disconnect (&ohci->hcd.bus->root_hub); + if (ohci->hcd.self.root_hub) + usb_disconnect (&ohci->hcd.self.root_hub); /* empty the interrupt branches */ for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load [i] = 0; @@ -728,10 +728,10 @@ ohci->ed_bulktail = NULL; if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) { - err ("can't restart %s, %d", ohci->hcd.bus_name, temp); + err ("can't restart %s, %d", ohci->hcd.self.bus_name, temp); return temp; } else - dbg ("restart %s completed", ohci->hcd.bus_name); + dbg ("restart %s completed", ohci->hcd.self.bus_name); return 0; } @@ -767,13 +767,13 @@ switch (temp) { case OHCI_USB_RESET: // lost power - info ("USB restart: %s", hcd->bus_name); + info ("USB restart: %s", hcd->self.bus_name); retval = hc_restart (ohci); break; case OHCI_USB_SUSPEND: // host wakeup case OHCI_USB_RESUME: // remote wakeup - info ("USB continue: %s from %s wakeup", hcd->bus_name, + info ("USB continue: %s from %s wakeup", hcd->self.bus_name, (temp == OHCI_USB_SUSPEND) ? "host" : "remote"); ohci->hc_control = OHCI_USB_RESUME; @@ -786,7 +786,7 @@ temp = readl (&ohci->regs->control); temp = ohci->hc_control & OHCI_CTRL_HCFS; if (temp != OHCI_USB_RESUME) { - err ("controller %s won't resume", hcd->bus_name); + err ("controller %s won't resume", hcd->self.bus_name); ohci->disabled = 1; retval = -EIO; break; @@ -836,7 +836,7 @@ break; default: - warn ("odd PCI resume for %s", hcd->bus_name); + warn ("odd PCI resume for %s", hcd->self.bus_name); } return retval; } diff -Nru a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c --- a/drivers/usb/host/ohci-hub.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/host/ohci-hub.c Tue Apr 16 11:36:06 2002 @@ -41,7 +41,7 @@ #define dbg_port(hc,label,num,value) \ dbg ("%s: %s roothub.portstatus [%d] " \ "= 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", \ - hc->hcd.bus_name, label, num, temp, \ + hc->hcd.self.bus_name, label, num, temp, \ (temp & RH_PS_PRSC) ? " PRSC" : "", \ (temp & RH_PS_OCIC) ? " OCIC" : "", \ (temp & RH_PS_PSSC) ? " PSSC" : "", \ @@ -71,7 +71,7 @@ ports = roothub_a (ohci) & RH_A_NDP; if (ports > MAX_ROOT_PORTS) { - err ("%s: bogus NDP=%d", hcd->bus_name, ports); + err ("%s: bogus NDP=%d", hcd->self.bus_name, ports); err ("rereads as NDP=%d", readl (&ohci->regs->roothub.a) & RH_A_NDP); /* retry later; "should not happen" */ diff -Nru a/drivers/usb/host/uhci.c b/drivers/usb/host/uhci.c --- a/drivers/usb/host/uhci.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/host/uhci.c Tue Apr 16 11:36:06 2002 @@ -2799,6 +2799,7 @@ uhci->bus = bus; bus->hcpriv = uhci; + bus->bus_name = dev->slot_name; usb_register_bus(uhci->bus); diff -Nru a/drivers/usb/host/usb-ohci.c b/drivers/usb/host/usb-ohci.c --- a/drivers/usb/host/usb-ohci.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/host/usb-ohci.c Tue Apr 16 11:36:06 2002 @@ -2400,6 +2400,7 @@ return NULL; } ohci->bus->hcpriv = (void *) ohci; + ohci->bus->bus_name = dev->slot_name; return ohci; } diff -Nru a/drivers/usb/host/usb-uhci.c b/drivers/usb/host/usb-uhci.c --- a/drivers/usb/host/usb-uhci.c Tue Apr 16 11:36:06 2002 +++ b/drivers/usb/host/usb-uhci.c Tue Apr 16 11:36:06 2002 @@ -2977,6 +2977,7 @@ s->bus = bus; bus->hcpriv = s; + bus->bus_name = dev->slot_name; /* UHCI specs says devices must have 2 ports, but goes on to say */ /* they may have more but give no way to determine how many they */ diff -Nru a/include/linux/usb.h b/include/linux/usb.h --- a/include/linux/usb.h Tue Apr 16 11:36:06 2002 +++ b/include/linux/usb.h Tue Apr 16 11:36:06 2002 @@ -890,7 +890,6 @@ char *buf, size_t size); extern int usb_set_configuration(struct usb_device *dev, int configuration); extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate); -extern int usb_make_path(struct usb_device *dev, char *buf, size_t size); /* * timeouts, in seconds, used for sending/receiving control messages @@ -917,6 +916,7 @@ */ struct usb_bus { int busnum; /* Bus number (in order of reg) */ + char *bus_name; /* stable id (PCI slot_name etc) */ #ifdef DEVNUM_ROUND_ROBIN int devnum_next; /* Next open device number in round-robin allocation */ @@ -1086,6 +1086,37 @@ const struct usb_device_id *usb_match_id(struct usb_device *dev, struct usb_interface *interface, const struct usb_device_id *id); + +/** + * usb_make_path - returns stable device path in the usb tree + * @dev: the device whose path is being constructed + * @buf: where to put the string + * @size: how big is "buf"? + * + * Returns length of the string (> 0) or negative if size was too small. + * + * This identifier is intended to be "stable", reflecting physical paths in + * hardware such as physical bus addresses for host controllers or ports on + * USB hubs. That makes it stay the same until systems are physically + * reconfigured, by re-cabling a tree of USB devices or by moving USB host + * controllers. Adding and removing devices, including virtual root hubs + * in host controller driver modules, does not change these path identifers; + * neither does rebooting or re-enumerating. These are more useful identifiers + * than changeable ("unstable") ones like bus numbers or device addresses. + * + * With a partial exception for devices connected to USB 2.0 root hubs, these + * identifiers are also predictable: so long as the device tree isn't changed, + * plugging any USB device into a given hub port always gives it the same path. + * Because of the use of "companion" controllers, devices connected to ports on + * USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are + * high speed, and a different one if they are full or low speed. + */ +static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size) +{ + int actual; + actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath); + return (actual >= size) ? -1 : actual; +} /* -------------------------------------------------------------------------- */