diff -Nru a/drivers/usb/hcd/ehci-hcd.c b/drivers/usb/hcd/ehci-hcd.c --- a/drivers/usb/hcd/ehci-hcd.c Thu Feb 7 13:55:10 2002 +++ b/drivers/usb/hcd/ehci-hcd.c Thu Feb 7 13:55:10 2002 @@ -277,7 +277,7 @@ */ usb_connect (udev); udev->speed = USB_SPEED_HIGH; - if (usb_new_device (udev) != 0) { + if (usb_register_root_hub (udev, &ehci->hcd.pdev->dev) != 0) { if (hcd->state == USB_STATE_RUNNING) ehci_ready (ehci); while (readl (&ehci->regs->status) & (STS_ASS | STS_PSS)) diff -Nru a/drivers/usb/hcd/ohci-hcd.c b/drivers/usb/hcd/ohci-hcd.c --- a/drivers/usb/hcd/ohci-hcd.c Thu Feb 7 13:55:11 2002 +++ b/drivers/usb/hcd/ohci-hcd.c Thu Feb 7 13:55:11 2002 @@ -469,7 +469,7 @@ usb_connect (udev); udev->speed = USB_SPEED_FULL; - if (usb_new_device (udev) != 0) { + if (usb_register_root_hub (udev, &ohci->hcd.pdev->dev) != 0) { usb_free_dev (udev); ohci->disabled = 1; // FIXME cleanup diff -Nru a/drivers/usb/hub.c b/drivers/usb/hub.c --- a/drivers/usb/hub.c Thu Feb 7 13:55:11 2002 +++ b/drivers/usb/hub.c Thu Feb 7 13:55:11 2002 @@ -721,6 +721,20 @@ info("new USB device on bus %d path %s, assigned address %d", dev->bus->busnum, dev->devpath, dev->devnum); + /* put the device in the global device tree */ + dev->dev.parent = &dev->parent->dev; + sprintf (&dev->dev.name[0], "USB device %04x:%04x", + dev->descriptor.idVendor, + dev->descriptor.idProduct); + /* find the number of the port this device is connected to */ + sprintf (&dev->dev.bus_id[0], "unknown_port_%03d", dev->devnum); + for (i = 0; i < USB_MAXCHILDREN; ++i) { + if (dev->parent->children[i] == dev) { + sprintf (&dev->dev.bus_id[0], "%02d", i); + break; + } + } + /* Run it through the hoops (find a driver, etc) */ if (!usb_new_device(dev)) goto done; diff -Nru a/drivers/usb/uhci.c b/drivers/usb/uhci.c --- a/drivers/usb/uhci.c Thu Feb 7 13:55:11 2002 +++ b/drivers/usb/uhci.c Thu Feb 7 13:55:11 2002 @@ -2842,7 +2842,7 @@ usb_connect(uhci->rh.dev); - if (usb_new_device(uhci->rh.dev) != 0) { + if (usb_register_root_hub(uhci->rh.dev, &dev->dev) != 0) { err("unable to start root hub"); retval = -ENOMEM; goto err_start_root_hub; diff -Nru a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c --- a/drivers/usb/usb-ohci.c Thu Feb 7 13:55:10 2002 +++ b/drivers/usb/usb-ohci.c Thu Feb 7 13:55:10 2002 @@ -2231,7 +2231,7 @@ dev = usb_to_ohci (usb_dev); ohci->bus->root_hub = usb_dev; usb_connect (usb_dev); - if (usb_new_device (usb_dev) != 0) { + if (usb_register_root_hub (usb_dev, &ohci->ohci_dev->dev) != 0) { usb_free_dev (usb_dev); ohci->disabled = 1; return -ENODEV; diff -Nru a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c --- a/drivers/usb/usb-uhci.c Thu Feb 7 13:55:10 2002 +++ b/drivers/usb/usb-uhci.c Thu Feb 7 13:55:10 2002 @@ -2907,7 +2907,7 @@ s->bus->root_hub = usb_dev; usb_connect (usb_dev); - if (usb_new_device (usb_dev) != 0) { + if (usb_register_root_hub (usb_dev, &s->uhci_pci->dev) != 0) { usb_free_dev (usb_dev); return -1; } diff -Nru a/drivers/usb/usb.c b/drivers/usb/usb.c --- a/drivers/usb/usb.c Thu Feb 7 13:55:11 2002 +++ b/drivers/usb/usb.c Thu Feb 7 13:55:11 2002 @@ -980,8 +980,16 @@ unsigned claimed = 0; for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) { + struct usb_interface *interface = &dev->actconfig->interface[ifnum]; + + /* register this interface with driverfs */ + interface->dev.parent = &dev->dev; + sprintf (&interface->dev.bus_id[0], "%03d", ifnum); + sprintf (&interface->dev.name[0], "figure out some name..."); + device_register (&interface->dev); + /* if this interface hasn't already been claimed */ - if (!usb_interface_claimed(dev->actconfig->interface + ifnum)) { + if (!usb_interface_claimed(interface)) { if (usb_find_interface_driver(dev, ifnum)) rejected++; else @@ -1969,8 +1977,10 @@ if (driver->owner) __MOD_DEC_USE_COUNT(driver->owner); /* if driver->disconnect didn't release the interface */ - if (interface->driver) + if (interface->driver) { + put_device (&interface->dev); usb_driver_release_interface(driver, interface); + } } } } @@ -1989,6 +1999,7 @@ if (dev->devnum > 0) { clear_bit(dev->devnum, &dev->bus->devmap.devicemap); usbfs_remove_device(dev); + put_device(&dev->dev); } /* Free up the device itself */ @@ -2715,6 +2726,11 @@ usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber); #endif + /* register this device in the driverfs tree */ + err = device_register (&dev->dev); + if (err) + return err; + /* now that the basic setup is over, add a /proc/bus/usb entry */ usbfs_add_device(dev); @@ -2727,6 +2743,29 @@ return 0; } +/** + * usb_register_root_hub - called by a usb host controller to register the root hub device in the system + * @usb_dev: the usb root hub device to be registered. + * @parent_dev: the parent device of this root hub. + * + * The USB host controller calls this function to register the root hub + * properly with the USB subsystem. It sets up the device properly in + * the driverfs tree, and then calls usb_new_device() to register the + * usb device. + */ +int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev) +{ + int retval; + + usb_dev->dev.parent = parent_dev; + strcpy (&usb_dev->dev.name[0], "usb_name"); + strcpy (&usb_dev->dev.bus_id[0], "usb_bus"); + retval = usb_new_device (usb_dev); + if (retval) + put_device (&usb_dev->dev); + return retval; +} + static int usb_open(struct inode * inode, struct file * file) { int minor = minor(inode->i_rdev); @@ -2832,6 +2871,7 @@ EXPORT_SYMBOL(usb_free_bus); EXPORT_SYMBOL(usb_register_bus); EXPORT_SYMBOL(usb_deregister_bus); +EXPORT_SYMBOL(usb_register_root_hub); EXPORT_SYMBOL(usb_alloc_dev); EXPORT_SYMBOL(usb_free_dev); EXPORT_SYMBOL(usb_inc_dev_use); diff -Nru a/include/linux/usb.h b/include/linux/usb.h --- a/include/linux/usb.h Thu Feb 7 13:55:11 2002 +++ b/include/linux/usb.h Thu Feb 7 13:55:11 2002 @@ -1,6 +1,8 @@ #ifndef __LINUX_USB_H #define __LINUX_USB_H +#include + /* USB constants */ /* @@ -260,6 +262,7 @@ int max_altsetting; /* total memory allocated */ struct usb_driver *driver; /* driver */ + struct device dev; /* interface specific device info */ void *private_data; }; @@ -945,6 +948,7 @@ extern void usb_free_bus(struct usb_bus *); extern void usb_register_bus(struct usb_bus *); extern void usb_deregister_bus(struct usb_bus *); +extern int usb_register_root_hub(struct usb_device *usb_dev, struct device *parent_dev); extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, @@ -1040,6 +1044,8 @@ struct usb_device *parent; struct usb_bus *bus; /* Bus we're part of */ + + struct device dev; /* Generic device interface */ struct usb_device_descriptor descriptor;/* Descriptor */ struct usb_config_descriptor *config; /* All of the configs */