Commit 6022ea62 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Added driverfs support for the USB subsystem.

parent 5f9bc7f1
......@@ -277,7 +277,7 @@ static int ehci_start (struct usb_hcd *hcd)
*/
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))
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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);
......
#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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment