summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <greg@soap.kroah.net>2002-02-06 22:27:46 -0800
committerGreg Kroah-Hartman <greg@soap.kroah.net>2002-02-06 22:27:46 -0800
commit6022ea62303f2bbcd3cbb1a9bf1000ff046a6839 (patch)
treef0019a0c829c6926b45109aec31a324b831b9d1e
parent5f9bc7f10e1944d83ea5bdb7f4a4252e857cfd36 (diff)
Added driverfs support for the USB subsystem.
-rw-r--r--drivers/usb/hcd/ehci-hcd.c2
-rw-r--r--drivers/usb/hcd/ohci-hcd.c2
-rw-r--r--drivers/usb/hub.c14
-rw-r--r--drivers/usb/uhci.c2
-rw-r--r--drivers/usb/usb-ohci.c2
-rw-r--r--drivers/usb/usb-uhci.c2
-rw-r--r--drivers/usb/usb.c44
-rw-r--r--include/linux/usb.h6
8 files changed, 67 insertions, 7 deletions
diff --git a/drivers/usb/hcd/ehci-hcd.c b/drivers/usb/hcd/ehci-hcd.c
index 6ee303aa0279..e6618253066a 100644
--- a/drivers/usb/hcd/ehci-hcd.c
+++ b/drivers/usb/hcd/ehci-hcd.c
@@ -277,7 +277,7 @@ done2:
*/
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 --git a/drivers/usb/hcd/ohci-hcd.c b/drivers/usb/hcd/ohci-hcd.c
index 48576302f49b..9dbceb3aaa03 100644
--- a/drivers/usb/hcd/ohci-hcd.c
+++ b/drivers/usb/hcd/ohci-hcd.c
@@ -469,7 +469,7 @@ static int hc_start (struct ohci_hcd *ohci)
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 --git a/drivers/usb/hub.c b/drivers/usb/hub.c
index 23eb747a727e..c545bd8ea62b 100644
--- a/drivers/usb/hub.c
+++ b/drivers/usb/hub.c
@@ -721,6 +721,20 @@ static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
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 --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c
index de765d9dc79a..e668cf3f15e4 100644
--- a/drivers/usb/uhci.c
+++ b/drivers/usb/uhci.c
@@ -2842,7 +2842,7 @@ static int alloc_uhci(struct pci_dev *dev, unsigned int io_addr, unsigned int io
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 --git a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c
index 94f84edfc94f..29384b44989a 100644
--- a/drivers/usb/usb-ohci.c
+++ b/drivers/usb/usb-ohci.c
@@ -2231,7 +2231,7 @@ static int hc_start (ohci_t * ohci)
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 --git a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c
index 154f603152b3..958c6d631cde 100644
--- a/drivers/usb/usb-uhci.c
+++ b/drivers/usb/usb-uhci.c
@@ -2907,7 +2907,7 @@ _static int __init uhci_start_usb (uhci_t *s)
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 --git a/drivers/usb/usb.c b/drivers/usb/usb.c
index e94daf9e1e89..be9fa8a786d5 100644
--- a/drivers/usb/usb.c
+++ b/drivers/usb/usb.c
@@ -980,8 +980,16 @@ static void usb_find_drivers(struct usb_device *dev)
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 @@ void usb_disconnect(struct usb_device **pdev)
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 @@ void usb_disconnect(struct usb_device **pdev)
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 @@ int usb_new_device(struct usb_device *dev)
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 @@ int usb_new_device(struct usb_device *dev)
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_alloc_bus);
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 --git a/include/linux/usb.h b/include/linux/usb.h
index d598c720ad2d..b577fce7d0ee 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1,6 +1,8 @@
#ifndef __LINUX_USB_H
#define __LINUX_USB_H
+#include <linux/device.h>
+
/* USB constants */
/*
@@ -260,6 +262,7 @@ struct usb_interface {
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 struct usb_bus *usb_alloc_bus(struct usb_operations *);
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,
@@ -1041,6 +1045,8 @@ struct usb_device {
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 */
struct usb_config_descriptor *actconfig;/* the active configuration */