diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/Makefile linux-2.5-driverfs/drivers/usb/core/Makefile --- ../linux-2.5/drivers/usb/core/Makefile Mon Jun 3 10:01:01 2002 +++ linux-2.5-driverfs/drivers/usb/core/Makefile Wed Jun 5 09:40:29 2002 @@ -11,6 +11,10 @@ usbcore-objs += devio.o inode.o drivers.o devices.o endif +ifeq ($(CONFIG_DEVFS),y) + usbcore-objs += fs.o +endif + obj-$(CONFIG_USB) += usbcore.o include $(TOPDIR)/Rules.make diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/devio.c linux-2.5-driverfs/drivers/usb/core/devio.c --- ../linux-2.5/drivers/usb/core/devio.c Tue May 28 09:11:55 2002 +++ linux-2.5-driverfs/drivers/usb/core/devio.c Mon Jun 3 11:29:16 2002 @@ -431,9 +431,9 @@ return -ENOENT; } +#if 0 extern struct list_head usb_driver_list; -#if 0 static int finddriver(struct usb_driver **driver, char *name) { struct list_head *tmp; @@ -1096,6 +1096,7 @@ else switch (ctrl.ioctl_code) { /* disconnect kernel driver from interface, leaving it unbound. */ +#if 0 case USBDEVFS_DISCONNECT: driver = ifp->driver; if (driver) { @@ -1113,7 +1114,7 @@ case USBDEVFS_CONNECT: usb_find_interface_driver_for_ifnum (ps->dev, ctrl.ifno); break; - +#endif /* talk directly to the interface's driver */ default: driver = ifp->driver; diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/drivers.c linux-2.5-driverfs/drivers/usb/core/drivers.c --- ../linux-2.5/drivers/usb/core/drivers.c Thu May 23 16:06:21 2002 +++ linux-2.5-driverfs/drivers/usb/core/drivers.c Mon Jun 3 11:29:16 2002 @@ -50,7 +50,7 @@ */ static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) { - struct list_head *tmp = usb_driver_list.next; + struct list_head *tmp = &usb_bus_type.drivers.next char *page, *start, *end; ssize_t ret = 0; unsigned int pos, len; @@ -66,7 +66,7 @@ start = page; end = page + (PAGE_SIZE - 100); pos = *ppos; - for (; tmp != &usb_driver_list; tmp = tmp->next) { + for (; tmp != &usb_bus_type.drivers; tmp = tmp->next) { struct usb_driver *driver = list_entry(tmp, struct usb_driver, driver_list); int minor = driver->fops ? driver->minor : -1; if (minor == -1) diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/fs.c linux-2.5-driverfs/drivers/usb/core/fs.c --- ../linux-2.5/drivers/usb/core/fs.c Wed Dec 31 16:00:00 1969 +++ linux-2.5-driverfs/drivers/usb/core/fs.c Mon Jun 3 11:09:08 2002 @@ -0,0 +1,61 @@ + +#include +#include +#include + +devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */ + + +static int usb_open(struct inode * inode, struct file * file) +{ + int minor = minor(inode->i_rdev); + struct usb_driver *c; + int err = -ENODEV; + struct file_operations *old_fops, *new_fops = NULL; + + spin_lock (&minor_lock); + c = usb_minors[minor]; + spin_unlock (&minor_lock); + + if (!c || !(new_fops = fops_get(c->fops))) + return err; + old_fops = file->f_op; + file->f_op = new_fops; + /* Curiouser and curiouser... NULL ->open() as "no device" ? */ + if (file->f_op->open) + err = file->f_op->open(inode,file); + if (err) { + fops_put(file->f_op); + file->f_op = fops_get(old_fops); + } + fops_put(old_fops); + return err; +} + +static struct file_operations usb_fops = { + owner: THIS_MODULE, + open: usb_open, +}; + +static int __init usb_major_init(void) +{ + if (devfs_register_chrdev(USB_MAJOR, "usb", &usb_fops)) { + err("unable to get major %d for usb devices", USB_MAJOR); + return -EBUSY; + } + + usb_devfs_handle = devfs_mk_dir(NULL, "usb", NULL); + + return 0; +} + +static void __exit usb_major_cleanup(void) +{ + devfs_unregister(usb_devfs_handle); + devfs_unregister_chrdev(USB_MAJOR, "usb"); +} + +subsys_initcall(usb_major_init); +module_exit(usb_major_cleanup); + +EXPORT_SYMBOL(usb_devfs_handle); diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/hcd.c linux-2.5-driverfs/drivers/usb/core/hcd.c --- ../linux-2.5/drivers/usb/core/hcd.c Wed May 29 12:39:43 2002 +++ linux-2.5-driverfs/drivers/usb/core/hcd.c Mon Jun 3 11:29:16 2002 @@ -730,15 +730,7 @@ */ 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; + return usb_new_device(usb_dev,parent_dev); } EXPORT_SYMBOL (usb_register_root_hub); diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/hcd.h linux-2.5-driverfs/drivers/usb/core/hcd.h --- ../linux-2.5/drivers/usb/core/hcd.h Mon Jun 3 10:24:32 2002 +++ linux-2.5-driverfs/drivers/usb/core/hcd.h Mon Jun 3 11:29:16 2002 @@ -182,7 +182,7 @@ /* -------------------------------------------------------------------------- */ /* Enumeration is only for the hub driver, or HCD virtual root hubs */ -extern int usb_new_device(struct usb_device *dev); +extern int usb_new_device(struct usb_device *dev, struct device * parent); extern void usb_connect(struct usb_device *dev); extern void usb_disconnect(struct usb_device **); diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/hub.c linux-2.5-driverfs/drivers/usb/core/hub.c --- ../linux-2.5/drivers/usb/core/hub.c Wed May 29 12:39:43 2002 +++ linux-2.5-driverfs/drivers/usb/core/hub.c Mon Jun 3 11:29:16 2002 @@ -250,49 +250,17 @@ /* Enable power to the ports */ dbg("enabling power on all ports"); for (i = 0; i < hub->descriptor->bNbrPorts; i++) - usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER); + usb_set_port_feature(hub->intf->usb_device, i + 1, USB_PORT_FEAT_POWER); /* Wait for power to be enabled */ wait_ms(hub->descriptor->bPwrOn2PwrGood * 2); } -static int usb_hub_configure(struct usb_hub *hub, - struct usb_endpoint_descriptor *endpoint) +static void usb_hub_report(struct usb_hub * hub) { - struct usb_device *dev = hub->dev; - struct usb_hub_status hubstatus; + struct usb_device *dev = hub->intf->usb_device; char portstr[USB_MAXCHILDREN + 1]; - unsigned int pipe; - int i, maxp, ret; - - hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); - if (!hub->descriptor) { - err("Unable to kmalloc %Zd bytes for hub descriptor", - sizeof(*hub->descriptor)); - return -1; - } - - /* Request the entire hub descriptor. - * hub->descriptor can handle USB_MAXCHILDREN ports, - * but the hub can/will return fewer bytes here. - */ - ret = usb_get_hub_descriptor(dev, hub->descriptor, - sizeof(*hub->descriptor)); - if (ret < 0) { - err("Unable to get hub descriptor (err = %d)", ret); - kfree(hub->descriptor); - return -1; - } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) { - err("Hub is too big! %d children", hub->descriptor->bNbrPorts); - kfree(hub->descriptor); - return -1; - } - - dev->maxchild = hub->descriptor->bNbrPorts; - info("%d port%s detected", dev->maxchild, - (dev->maxchild == 1) ? "" : "s"); - - le16_to_cpus(&hub->descriptor->wHubCharacteristics); + int i; if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND) dbg("part of a compound device"); @@ -376,14 +344,51 @@ [((i + 1) / 8)] & (1 << ((i + 1) % 8)) ? 'F' : 'R'; portstr[dev->maxchild] = 0; - dbg("port removable status: %s", portstr); +} + +static int usb_hub_configure(struct usb_hub *hub, + struct usb_endpoint_descriptor *endpoint) +{ + struct usb_device *dev = hub->intf->usb_device; + struct usb_hub_status hubstatus; + unsigned int pipe; + int maxp, ret; + int error = -EIO; + + hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); + if (!hub->descriptor) { + err("Unable to kmalloc %Zd bytes for hub descriptor", + sizeof(*hub->descriptor)); + goto Done; + } + + /* Request the entire hub descriptor. + * hub->descriptor can handle USB_MAXCHILDREN ports, + * but the hub can/will return fewer bytes here. + */ + ret = usb_get_hub_descriptor(dev, hub->descriptor, + sizeof(*hub->descriptor)); + if (ret < 0) { + err("Unable to get hub descriptor (err = %d)", ret); + goto Done; + } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) { + err("Hub is too big! %d children", hub->descriptor->bNbrPorts); + goto Done; + } + + dev->maxchild = hub->descriptor->bNbrPorts; + info("%d port%s detected", dev->maxchild, + (dev->maxchild == 1) ? "" : "s"); + + le16_to_cpus(&hub->descriptor->wHubCharacteristics); + + usb_hub_report(hub); ret = usb_get_hub_status(dev, &hubstatus); if (ret < 0) { err("Unable to get hub status (err = %d)", ret); - kfree(hub->descriptor); - return -1; + goto Done; } le16_to_cpus(&hubstatus.wHubStatus); @@ -405,147 +410,135 @@ hub->urb = usb_alloc_urb(0, GFP_KERNEL); if (!hub->urb) { err("couldn't allocate interrupt urb"); - kfree(hub->descriptor); - return -1; + goto Done; } FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq, hub, endpoint->bInterval); ret = usb_submit_urb(hub->urb, GFP_KERNEL); - if (ret) { + if (!ret) { + /* Wake up khubd */ + wake_up(&khubd_wait); + + usb_hub_power_on(hub); + error = 0; + } else err("usb_submit_urb failed (%d)", ret); + Done: + if (error && hub->descriptor) kfree(hub->descriptor); - return -1; + return error; +} + +static void hub_disconnect(struct usb_interface *intf) +{ + struct usb_hub *hub = (struct usb_hub *)intf->dev.driver_data; + unsigned long flags; + + spin_lock_irqsave(&hub_event_lock, flags); + + /* Delete it and then reset it */ + list_del_init(&hub->event_list); + list_del_init(&hub->hub_list); + spin_unlock_irqrestore(&hub_event_lock, flags); + + down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */ + up(&hub->khubd_sem); + + if (hub->urb) { + usb_unlink_urb(hub->urb); + usb_free_urb(hub->urb); + hub->urb = NULL; } - - /* Wake up khubd */ - wake_up(&khubd_wait); - usb_hub_power_on(hub); + if (hub->descriptor) { + kfree(hub->descriptor); + hub->descriptor = NULL; + } - return 0; + /* Free the memory */ + kfree(hub); + intf->dev.driver_data = NULL; } -static void *hub_probe(struct usb_device *dev, unsigned int i, - const struct usb_device_id *id) +static int hub_probe(struct usb_interface * intf) { - struct usb_interface_descriptor *interface; + struct usb_interface_descriptor *desc; struct usb_endpoint_descriptor *endpoint; - struct usb_hub *hub; - unsigned long flags; - interface = &dev->actconfig->interface[i].altsetting[0]; + desc = intf->altsetting + intf->act_altsetting; /* Some hubs have a subclass of 1, which AFAICT according to the */ /* specs is not defined, but it works */ - if ((interface->bInterfaceSubClass != 0) && - (interface->bInterfaceSubClass != 1)) { + if ((desc->bInterfaceSubClass != 0) && + (desc->bInterfaceSubClass != 1)) { err("invalid subclass (%d) for USB hub device #%d", - interface->bInterfaceSubClass, dev->devnum); - return NULL; + desc->bInterfaceSubClass, intf->usb_device->devnum); + return -EIO; } /* Multiple endpoints? What kind of mutant ninja-hub is this? */ - if (interface->bNumEndpoints != 1) { + if (desc->bNumEndpoints != 1) { err("invalid bNumEndpoints (%d) for USB hub device #%d", - interface->bNumEndpoints, dev->devnum); - return NULL; + desc->bNumEndpoints, intf->usb_device->devnum); + return -EIO; } - endpoint = &interface->endpoint[0]; + endpoint = &desc->endpoint[0]; /* Output endpoint? Curiousier and curiousier.. */ if (!(endpoint->bEndpointAddress & USB_DIR_IN)) { err("Device #%d is hub class, but has output endpoint?", - dev->devnum); - return NULL; + intf->usb_device->devnum); + return -EIO; } /* If it's not an interrupt endpoint, we'd better punt! */ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) { err("Device #%d is hub class, but endpoint is not interrupt?", - dev->devnum); - return NULL; + intf->usb_device->devnum); + return -EIO; } /* We found a hub */ - info("USB hub found at %s", dev->devpath); + info("USB hub found at %s", intf->usb_device->devpath); + + return 0; +} + +static int hub_init(struct usb_interface * intf) +{ + struct usb_hub * hub; + unsigned long flags; + struct usb_endpoint_descriptor *endpoint; + + endpoint = intf->altsetting[intf->act_altsetting].endpoint; hub = kmalloc(sizeof(*hub), GFP_KERNEL); if (!hub) { err("couldn't kmalloc hub struct"); - return NULL; + return -ENOMEM; } memset(hub, 0, sizeof(*hub)); INIT_LIST_HEAD(&hub->event_list); - hub->dev = dev; + hub->intf = intf; init_MUTEX(&hub->khubd_sem); /* Record the new hub's existence */ spin_lock_irqsave(&hub_event_lock, flags); - INIT_LIST_HEAD(&hub->hub_list); list_add(&hub->hub_list, &hub_list); spin_unlock_irqrestore(&hub_event_lock, flags); + intf->dev.driver_data = hub; if (usb_hub_configure(hub, endpoint) >= 0) - return hub; - - err("hub configuration failed for device at %s", dev->devpath); - - /* free hub, but first clean up its list. */ - spin_lock_irqsave(&hub_event_lock, flags); - - /* Delete it and then reset it */ - list_del(&hub->event_list); - INIT_LIST_HEAD(&hub->event_list); - list_del(&hub->hub_list); - INIT_LIST_HEAD(&hub->hub_list); - - spin_unlock_irqrestore(&hub_event_lock, flags); - - kfree(hub); - - return NULL; -} - -static void hub_disconnect(struct usb_device *dev, void *ptr) -{ - struct usb_hub *hub = (struct usb_hub *)ptr; - unsigned long flags; - - spin_lock_irqsave(&hub_event_lock, flags); - - /* Delete it and then reset it */ - list_del(&hub->event_list); - INIT_LIST_HEAD(&hub->event_list); - list_del(&hub->hub_list); - INIT_LIST_HEAD(&hub->hub_list); - - spin_unlock_irqrestore(&hub_event_lock, flags); - - down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */ - up(&hub->khubd_sem); - - /* assuming we used keventd, it must quiesce too */ - if (hub->tt.hub) - flush_scheduled_tasks (); - - if (hub->urb) { - usb_unlink_urb(hub->urb); - usb_free_urb(hub->urb); - hub->urb = NULL; - } - - if (hub->descriptor) { - kfree(hub->descriptor); - hub->descriptor = NULL; - } + return 0; - /* Free the memory */ - kfree(hub); + err("hub configuration failed for device at %s", intf->usb_device->devpath); + hub_disconnect(intf); + return -ENODEV; } static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data) @@ -582,7 +575,7 @@ static int usb_hub_reset(struct usb_hub *hub) { - struct usb_device *dev = hub->dev; + struct usb_device *dev = hub->intf->usb_device; int i; /* Disconnect any attached devices */ @@ -793,7 +786,7 @@ static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port, u16 portstatus, u16 portchange) { - struct usb_device *hub = hubstate->dev; + struct usb_device *hub = hubstate->intf->usb_device; struct usb_device *dev; unsigned int delay = HUB_SHORT_RESET_TIME; int i; @@ -884,22 +877,8 @@ 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; - 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)) + if (!usb_new_device(dev,&hubstate->intf->dev)) goto done; /* Free the configuration if there was an error */ @@ -944,7 +923,7 @@ tmp = hub_event_list.next; hub = list_entry(tmp, struct usb_hub, event_list); - dev = hub->dev; + dev = hub->intf->usb_device; list_del(tmp); INIT_LIST_HEAD(tmp); @@ -1088,20 +1067,21 @@ static struct usb_driver hub_driver = { name: "hub", - probe: hub_probe, + new_probe: hub_probe, + init: hub_init, ioctl: hub_ioctl, - disconnect: hub_disconnect, + new_disco: hub_disconnect, id_table: hub_id_table, }; /* * This should be a separate module. */ -int usb_hub_init(void) +static int __init usb_hub_init(void) { int pid; - if (usb_register(&hub_driver) < 0) { + if (usb_driver_register(&hub_driver) < 0) { err("Unable to register USB hub driver"); return -1; } @@ -1121,7 +1101,7 @@ return -1; } -void usb_hub_cleanup(void) +static void __exit usb_hub_cleanup(void) { int ret; @@ -1138,7 +1118,10 @@ * individual hub resources. -greg */ usb_deregister(&hub_driver); -} /* usb_hub_cleanup() */ +} + +module_init(usb_hub_init); +module_exit(usb_hub_cleanup); /* * WARNING - If a driver calls usb_reset_device, you should simulate a diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/hub.h linux-2.5-driverfs/drivers/usb/core/hub.h --- ../linux-2.5/drivers/usb/core/hub.h Mon Jun 3 10:24:22 2002 +++ linux-2.5-driverfs/drivers/usb/core/hub.h Mon Jun 3 11:29:16 2002 @@ -134,7 +134,7 @@ __u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8]; } __attribute__ ((packed)); -struct usb_device; +struct usb_interface; /* * As of USB 2.0, full/low speed devices are segregated into trees. @@ -165,7 +165,7 @@ extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe); struct usb_hub { - struct usb_device *dev; /* the "real" device */ + struct usb_interface *intf; /* the "real" device */ struct urb *urb; /* for interrupt polling pipe */ /* buffer for urb ... 1 bit each for hub and children, rounded up */ diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/usb.c linux-2.5-driverfs/drivers/usb/core/usb.c --- ../linux-2.5/drivers/usb/core/usb.c Mon Jun 3 10:01:01 2002 +++ linux-2.5-driverfs/drivers/usb/core/usb.c Mon Jun 3 11:29:16 2002 @@ -30,7 +30,6 @@ #include /* for in_interrupt() */ #include #include -#include #include #include @@ -43,23 +42,6 @@ #include "hcd.h" -extern int usb_hub_init(void); -extern void usb_hub_cleanup(void); - -/* - * Prototypes for the device driver probing/loading functions - */ -static void usb_find_drivers(struct usb_device *); -static int usb_find_interface_driver(struct usb_device *, unsigned int); -static void usb_check_support(struct usb_device *); - -/* - * We have a per-interface "registered driver" list. - */ -LIST_HEAD(usb_driver_list); - -devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */ - #define MAX_USB_MINORS 256 static struct usb_driver *usb_minors[MAX_USB_MINORS]; static spinlock_t minor_lock = SPIN_LOCK_UNLOCKED; @@ -102,6 +84,51 @@ spin_unlock (&minor_lock); } +static int usb_device_probe(struct device * dev) +{ + struct usb_interface * intf = list_entry(dev,struct usb_interface,dev); + struct usb_driver * drv = list_entry(dev->driver,struct usb_driver,driver); + int error = -ENODEV; + + if (drv->new_probe) + error = drv->new_probe(intf); + if (!error) + intf->driver = drv; + return error; +} + +static int usb_device_init(struct device * dev) +{ + struct usb_interface * intf = list_entry(dev,struct usb_interface, dev); + struct usb_driver * drv = intf->driver; + + return (drv->init) ? drv->init(intf) : 0; +} + +static int usb_device_remove(struct device * dev) +{ + struct usb_interface * intf = list_entry(dev,struct usb_interface,dev); + + if (intf->driver && intf->driver->new_disco) + intf->driver->new_disco(intf); + return 0; +} + +int usb_driver_register(struct usb_driver * drv) +{ + drv->driver.name = drv->name; + drv->driver.bus = &usb_bus_type; + drv->driver.probe = usb_device_probe; + drv->driver.init = usb_device_init; + drv->driver.remove = usb_device_remove; + + info("registered new driver %s", drv->name); + + init_MUTEX(&drv->serialize); + + return driver_register(&drv->driver); +} + /** * usb_register - register a USB driver * @new_driver: USB operations for the driver @@ -128,14 +155,17 @@ } #endif + new_driver->driver.name = new_driver->name; + new_driver->driver.bus = &usb_bus_type; + new_driver->driver.probe = usb_device_probe; + new_driver->driver.init = usb_device_init; + new_driver->driver.remove = usb_device_remove; + info("registered new driver %s", new_driver->name); init_MUTEX(&new_driver->serialize); - /* Add it to the list of known drivers */ - list_add_tail(&new_driver->driver_list, &usb_driver_list); - - usb_scan_devices(); + driver_register(&new_driver->driver); usbfs_update_special(); @@ -228,75 +258,6 @@ } #endif /* CONFIG_USB_DYNAMIC_MINORS */ - -/** - * usb_scan_devices - scans all unclaimed USB interfaces - * Context: !in_interrupt () - * - * Goes through all unclaimed USB interfaces, and offers them to all - * registered USB drivers through the 'probe' function. - * This will automatically be called after usb_register is called. - * It is called by some of the subsystems layered over USB - * after one of their subdrivers are registered. - */ -void usb_scan_devices(void) -{ - struct list_head *tmp; - - down (&usb_bus_list_lock); - tmp = usb_bus_list.next; - while (tmp != &usb_bus_list) { - struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list); - - tmp = tmp->next; - usb_check_support(bus->root_hub); - } - up (&usb_bus_list_lock); -} - -/* - * This function is part of a depth-first search down the device tree, - * removing any instances of a device driver. - */ -static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev) -{ - int i; - - if (!dev) { - err("null device being purged!!!"); - return; - } - - for (i=0; ichildren[i]) - usb_drivers_purge(driver, dev->children[i]); - - if (!dev->actconfig) - return; - - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { - struct usb_interface *interface = &dev->actconfig->interface[i]; - - if (interface->driver == driver) { - if (driver->owner) - __MOD_INC_USE_COUNT(driver->owner); - down(&driver->serialize); - driver->disconnect(dev, interface->private_data); - up(&driver->serialize); - if (driver->owner) - __MOD_DEC_USE_COUNT(driver->owner); - /* if driver->disconnect didn't release the interface */ - if (interface->driver) - usb_driver_release_interface(driver, interface); - /* - * This will go through the list looking for another - * driver that can handle the device - */ - usb_find_interface_driver(dev, i); - } - } -} - /** * usb_deregister - unregister a USB driver * @driver: USB operations of the driver to unregister @@ -306,8 +267,6 @@ */ void usb_deregister(struct usb_driver *driver) { - struct list_head *tmp; - info("deregistering driver %s", driver->name); #ifndef CONFIG_USB_DYNAMIC_MINORS @@ -315,21 +274,7 @@ usb_deregister_minors (driver, driver->num_minors, driver->minor); #endif - /* - * first we remove the driver, to be sure it doesn't get used by - * another thread while we are stepping through removing entries - */ - list_del(&driver->driver_list); - - down (&usb_bus_list_lock); - tmp = usb_bus_list.next; - while (tmp != &usb_bus_list) { - struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list); - - tmp = tmp->next; - usb_drivers_purge(driver, bus->root_hub); - } - up (&usb_bus_list_lock); + put_driver(&driver->driver); usbfs_update_special(); } @@ -410,33 +355,6 @@ return NULL; } -/* - * This function is for doing a depth-first search for devices which - * have support, for dynamic loading of driver modules. - */ -static void usb_check_support(struct usb_device *dev) -{ - int i; - - if (!dev) { - err("null device being checked!!!"); - return; - } - - for (i=0; ichildren[i]) - usb_check_support(dev->children[i]); - - if (!dev->actconfig) - return; - - /* now we check this device */ - if (dev->devnum > 0) - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) - usb_find_interface_driver(dev, i); -} - - /** * usb_driver_claim_interface - bind a driver to an interface * @driver: the driver to be bound @@ -468,7 +386,7 @@ iface->driver = driver; iface->private_data = priv; -} /* usb_driver_claim_interface() */ +} /** * usb_interface_claimed - returns true iff an interface is claimed @@ -487,7 +405,7 @@ return 0; return (iface->driver != NULL); -} /* usb_interface_claimed() */ +} /** * usb_driver_release_interface - unbind a driver from an interface @@ -645,110 +563,70 @@ return NULL; } -/* - * This entrypoint gets called for each new device. - * - * We now walk the list of registered USB drivers, - * looking for one that will accept this interface. - * - * "New Style" drivers use a table describing the devices and interfaces - * they handle. Those tables are available to user mode tools deciding - * whether to load driver modules for a new device. - * - * The probe return value is changed to be a private pointer. This way - * the drivers don't have to dig around in our structures to set the - * private pointer if they only need one interface. - * - * Returns: 0 if a driver accepted the interface, -1 otherwise - */ -static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum) +static int usb_device_bind(struct device * dev, struct device_driver * drv) { - struct list_head *tmp; - struct usb_interface *interface; - void *private; - const struct usb_device_id *id; - struct usb_driver *driver; - int i; - - if ((!dev) || (ifnum >= dev->actconfig->bNumInterfaces)) { - err("bad find_interface_driver params"); - return -1; - } - - down(&dev->serialize); - - interface = dev->actconfig->interface + ifnum; - - if (usb_interface_claimed(interface)) - goto out_err; - - private = NULL; - for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) { - driver = list_entry(tmp, struct usb_driver, driver_list); - tmp = tmp->next; - - if (driver->owner) - __MOD_INC_USE_COUNT(driver->owner); - id = driver->id_table; - /* new style driver? */ - if (id) { - for (i = 0; i < interface->num_altsetting; i++) { - interface->act_altsetting = i; - id = usb_match_id(dev, interface, id); - if (id) { - down(&driver->serialize); - private = driver->probe(dev,ifnum,id); - up(&driver->serialize); - if (private != NULL) - break; - } - } + struct usb_interface * intf = list_entry(dev,struct usb_interface,dev); + struct usb_interface_descriptor * desc = &intf->altsetting[intf->act_altsetting]; + struct usb_device * usb_dev = intf->usb_device; + struct usb_driver * usb_drv = list_entry(drv,struct usb_driver,driver); + const struct usb_device_id * id = usb_drv->id_table; - /* if driver not bound, leave defaults unchanged */ - if (private == NULL) - interface->act_altsetting = 0; - } else { /* "old style" driver */ - down(&driver->serialize); - private = driver->probe(dev, ifnum, NULL); - up(&driver->serialize); - } - if (driver->owner) - __MOD_DEC_USE_COUNT(driver->owner); + /* It is important to check that id->driver_info is nonzero, + since an entry that is all zeroes except for a nonzero + id->driver_info is the way to create an entry that + indicates that the driver want to examine every + device and interface. */ + for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || + id->driver_info; id++) { - /* probe() may have changed the config on us */ - interface = dev->actconfig->interface + ifnum; + if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && + id->idVendor != usb_dev->descriptor.idVendor) + continue; - if (private) { - usb_driver_claim_interface(driver, interface, private); - up(&dev->serialize); - return 0; - } - } + if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && + id->idProduct != usb_dev->descriptor.idProduct) + continue; -out_err: - up(&dev->serialize); - return -1; -} + /* No need to test id->bcdDevice_lo != 0, since 0 is never + greater than any unsigned number. */ + if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && + (id->bcdDevice_lo > usb_dev->descriptor.bcdDevice)) + continue; -/** - * usb_find_interface_driver_for_ifnum - finds a usb interface driver for the specified ifnum - * @dev: the device to use - * @ifnum: the interface number (bInterfaceNumber); not interface position! - * - * This converts a ifnum to ifpos via a call to usb_ifnum_to_ifpos and then - * calls usb_find_interface_driver() with the found ifpos. Note - * usb_find_interface_driver's ifnum parameter is actually interface position. - */ -int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned ifnum) -{ - int ifpos = usb_ifnum_to_ifpos(dev, ifnum); + if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && + (id->bcdDevice_hi < usb_dev->descriptor.bcdDevice)) + continue; - if (0 > ifpos) - return -EINVAL; + if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && + (id->bDeviceClass != usb_dev->descriptor.bDeviceClass)) + continue; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && + (id->bDeviceSubClass!= usb_dev->descriptor.bDeviceSubClass)) + continue; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && + (id->bDeviceProtocol != usb_dev->descriptor.bDeviceProtocol)) + continue; - return usb_find_interface_driver(dev, ifpos); + if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && + (id->bInterfaceClass != desc->bInterfaceClass)) + continue; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && + (id->bInterfaceSubClass != desc->bInterfaceSubClass)) + continue; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && + (id->bInterfaceProtocol != desc->bInterfaceProtocol)) + continue; + + return 1; + } + return 0; } + #ifdef CONFIG_HOTPLUG /* @@ -886,51 +764,6 @@ #endif /* CONFIG_HOTPLUG */ - -/* - * This entrypoint gets called for each new device. - * - * All interfaces are scanned for matching drivers. - */ -static void usb_find_drivers(struct usb_device *dev) -{ - unsigned ifnum; - unsigned rejected = 0; - 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; - interface->dev.bus = &usb_bus_type; - sprintf (&interface->dev.bus_id[0], "%03d%03d", dev->devnum,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(interface)) { - if (usb_find_interface_driver(dev, ifnum)) - rejected++; - else - claimed++; - } - } - - if (rejected) - dbg("unhandled interfaces on device"); - - if (!claimed) { - warn("USB device %d (vend/prod 0x%x/0x%x) is not claimed by any active driver.", - dev->devnum, - dev->descriptor.idVendor, - dev->descriptor.idProduct); -#ifdef DEBUG - usb_show_device(dev); -#endif - } -} - /** * usb_alloc_dev - allocate a usb device structure (usbcore-internal) * @parent: hub to which device is connected @@ -1034,7 +867,6 @@ /*-------------------------------------------------------------------*/ - /* for returning string descriptors in UTF-16LE */ static int ascii2utf (char *ascii, __u8 *utf, int utfmax) { @@ -1171,7 +1003,6 @@ if (dev->devnum > 0) { clear_bit(dev->devnum, dev->bus->devmap.devicemap); usbfs_remove_device(dev); - put_device(&dev->dev); } /* Decrement the reference count, it'll auto free everything when */ @@ -1220,21 +1051,6 @@ } /* - * These are the actual routines to send - * and receive control messages. - */ - -// hub-only!! ... and only exported for reset/reinit path. -// otherwise used internally, for usb_new_device() -int usb_set_address(struct usb_device *dev) -{ - return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS, - // FIXME USB_CTRL_SET_TIMEOUT - 0, dev->devnum, 0, NULL, 0, HZ * USB_CTRL_GET_TIMEOUT); -} - - -/* * 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 * get the ball rolling.. @@ -1248,7 +1064,7 @@ */ #define NEW_DEVICE_RETRYS 2 #define SET_ADDRESS_RETRYS 2 -int usb_new_device(struct usb_device *dev) +int usb_new_device(struct usb_device *dev, struct device * parent) { int err = 0; int i; @@ -1339,78 +1155,32 @@ if (dev->descriptor.iSerialNumber) 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); - /* find drivers willing to handle this device */ - usb_find_drivers(dev); - - /* userspace may load modules and/or configure further */ - call_policy ("add", dev); - - return 0; -} - -static int usb_open(struct inode * inode, struct file * file) -{ - int minor = minor(inode->i_rdev); - struct usb_driver *c; - int err = -ENODEV; - struct file_operations *old_fops, *new_fops = NULL; - - spin_lock (&minor_lock); - c = usb_minors[minor]; - spin_unlock (&minor_lock); - - if (!c || !(new_fops = fops_get(c->fops))) - return err; - old_fops = file->f_op; - file->f_op = new_fops; - /* Curiouser and curiouser... NULL ->open() as "no device" ? */ - if (file->f_op->open) - err = file->f_op->open(inode,file); - if (err) { - fops_put(file->f_op); - file->f_op = fops_get(old_fops); - } - fops_put(old_fops); - return err; -} - -static struct file_operations usb_fops = { - owner: THIS_MODULE, - open: usb_open, -}; + for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) { + struct usb_interface *interface = &dev->actconfig->interface[ifnum]; + int _err; -int usb_major_init(void) -{ - if (devfs_register_chrdev(USB_MAJOR, "usb", &usb_fops)) { - err("unable to get major %d for usb devices", USB_MAJOR); - return -EBUSY; + /* register this interface with driverfs */ + interface->usb_device = dev; + interface->dev.parent = parent; + interface->dev.bus = &usb_bus_type; + sprintf (interface->dev.bus_id, "%03d%03d", dev->devnum,ifnum); + sprintf (interface->dev.name, "figure out some name..."); + device_register (&interface->dev); } - usb_devfs_handle = devfs_mk_dir(NULL, "usb", NULL); + /* userspace may load modules and/or configure further */ + call_policy ("add", dev); return 0; } -void usb_major_cleanup(void) -{ - devfs_unregister(usb_devfs_handle); - devfs_unregister_chrdev(USB_MAJOR, "usb"); -} - - #ifdef CONFIG_PROC_FS struct list_head *usb_driver_get_list(void) { - return &usb_driver_list; + return &usb_bus_type.drivers; } struct list_head *usb_bus_get_list(void) @@ -1421,6 +1191,7 @@ struct bus_type usb_bus_type = { name: "usb", + bind: usb_device_bind, }; /* @@ -1429,10 +1200,7 @@ static int __init usb_init(void) { bus_register(&usb_bus_type); - usb_major_init(); usbfs_init(); - usb_hub_init(); - return 0; } @@ -1441,10 +1209,7 @@ */ static void __exit usb_exit(void) { - put_bus(&usb_bus_type); - usb_major_cleanup(); usbfs_cleanup(); - usb_hub_cleanup(); } subsys_initcall(usb_init); @@ -1461,7 +1226,6 @@ EXPORT_SYMBOL(usb_register); EXPORT_SYMBOL(usb_deregister); -EXPORT_SYMBOL(usb_scan_devices); #ifdef CONFIG_USB_DYNAMIC_MINORS EXPORT_SYMBOL(usb_register_dev); @@ -1473,7 +1237,6 @@ EXPORT_SYMBOL(usb_get_dev); EXPORT_SYMBOL(usb_hub_tt_clear_buffer); -EXPORT_SYMBOL(usb_find_interface_driver_for_ifnum); EXPORT_SYMBOL(usb_driver_claim_interface); EXPORT_SYMBOL(usb_interface_claimed); EXPORT_SYMBOL(usb_driver_release_interface); @@ -1489,5 +1252,4 @@ EXPORT_SYMBOL(usb_get_current_frame_number); -EXPORT_SYMBOL(usb_devfs_handle); MODULE_LICENSE("GPL"); diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/hid-core.c linux-2.5-driverfs/drivers/usb/input/hid-core.c --- ../linux-2.5/drivers/usb/input/hid-core.c Thu May 23 16:06:21 2002 +++ linux-2.5-driverfs/drivers/usb/input/hid-core.c Mon Jun 3 11:29:16 2002 @@ -1013,7 +1013,7 @@ hid_output_report(report, hid->outbuf); hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1; - hid->urbout->dev = hid->dev; + hid->urbout->dev = hid->intf->usb_device; dbg("submitting out urb"); @@ -1037,13 +1037,15 @@ hid_output_report(report, hid->ctrlbuf); hid->urbctrl->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + ((report->id > 0) && (dir != USB_DIR_OUT)); - hid->urbctrl->pipe = (dir == USB_DIR_OUT) ? usb_sndctrlpipe(hid->dev, 0) : usb_rcvctrlpipe(hid->dev, 0); - hid->urbctrl->dev = hid->dev; + hid->urbctrl->pipe = (dir == USB_DIR_OUT) ? + usb_sndctrlpipe(hid->intf->usb_device, 0) : + usb_rcvctrlpipe(hid->intf->usb_device, 0); + hid->urbctrl->dev = hid->intf->usb_device; hid->cr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; hid->cr.bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; hid->cr.wValue = ((report->type + 1) << 8) | report->id; - hid->cr.wIndex = cpu_to_le16(hid->ifnum); + hid->cr.wIndex = cpu_to_le16(hid->intf->ifnum); hid->cr.wLength = cpu_to_le16(hid->urbctrl->transfer_buffer_length); dbg("submitting ctrl urb"); @@ -1199,7 +1201,7 @@ if (hid->open++) return 0; - hid->urbin->dev = hid->dev; + hid->urbin->dev = hid->intf->usb_device; if (usb_submit_urb(hid->urbin, GFP_KERNEL)) return -EIO; @@ -1252,9 +1254,9 @@ len = ((report->size - 1) >> 3) + 1 + report_enum->numbered; if (len > hid->urbin->transfer_buffer_length) hid->urbin->transfer_buffer_length = len < HID_BUFFER_SIZE ? len : HID_BUFFER_SIZE; - usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), + usb_control_msg(hid->intf->usb_device, usb_sndctrlpipe(hid->intf->usb_device, 0), 0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id, - hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); + hid->intf->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); list = list->next; } } @@ -1293,9 +1295,10 @@ { 0, 0 } }; -static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum) +static struct hid_device *usb_hid_configure(struct usb_interface * intf) { - struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0; + struct usb_interface_descriptor *interface = intf->altsetting + 0; + struct usb_device * dev = intf->usb_device; struct hid_descriptor *hdesc; struct hid_device *hid; unsigned quirks = 0, rsize = 0; @@ -1385,8 +1388,11 @@ hid->version = hdesc->bcdHID; hid->country = hdesc->bCountryCode; +/* hid->dev = dev; hid->ifnum = interface->bInterfaceNumber; +*/ + hid->intf = intf; hid->name[0] = 0; @@ -1395,18 +1401,7 @@ if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) { strcat(hid->name, buf); - if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0) { - n = snprintf(hid->name, sizeof(hid->name)-1, "%s %s", hid->name, buf); - hid->name[n] = 0; - } - } else { - n = snprintf(hid->name, sizeof(hid->name)-1, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct); - hid->name[n] = 0; - } - - usb_make_path(dev, buf, 64); - n = snprintf(hid->phys, sizeof(hid->phys)-1, "%s/input%d", buf, ifnum); - hid->phys[n] = 0; + snprintf(hid->phys, 64, "%s/input%d", buf, intf->ifnum); if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) hid->uniq[0] = 0; @@ -1428,18 +1423,18 @@ return NULL; } -static void* hid_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int hid_probe(struct usb_interface *intf) { + struct usb_device * dev = intf->usb_device; struct hid_device *hid; char path[64]; int i; char *c; - dbg("HID probe called for ifnum %d", ifnum); + dbg("HID probe called for ifnum %d", intf->ifnum); - if (!(hid = usb_hid_configure(dev, ifnum))) - return NULL; + if (!(hid = usb_hid_configure(intf))) + return -ENODEV; hid_init_reports(hid); hid_dump_device(hid); @@ -1451,7 +1446,7 @@ if (!hid->claimed) { hid_free_device(hid); - return NULL; + return -ENODEV; } printk(KERN_INFO); @@ -1475,12 +1470,14 @@ printk(": USB HID v%x.%02x %s [%s] on %s\n", hid->version >> 8, hid->version & 0xff, c, hid->name, path); - return hid; + intf->dev.driver_data = hid; + + return 0; } -static void hid_disconnect(struct usb_device *dev, void *ptr) +static void hid_disconnect(struct usb_interface * intf) { - struct hid_device *hid = ptr; + struct hid_device *hid = intf->dev.driver_data; dbg("cleanup called"); usb_unlink_urb(hid->urbin); @@ -1509,15 +1506,25 @@ static struct usb_driver hid_driver = { name: "hid", - probe: hid_probe, - disconnect: hid_disconnect, id_table: hid_usb_ids, + new_probe: hid_probe, + new_disco: hid_disconnect, + +#if 0 + driver: { + name: "hid", + id_table: hid_usb_ids, + bus: &usb_bus_type, + devclass: &input_devclass, + probe: hid_dev_probe, + }, +#endif }; static int __init hid_init(void) { hiddev_init(); - usb_register(&hid_driver); + usb_driver_register(&hid_driver); info(DRIVER_VERSION ":" DRIVER_DESC); return 0; diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/hid-input.c linux-2.5-driverfs/drivers/usb/input/hid-input.c --- ../linux-2.5/drivers/usb/input/hid-input.c Thu May 23 16:06:21 2002 +++ linux-2.5-driverfs/drivers/usb/input/hid-input.c Mon Jun 3 11:29:16 2002 @@ -411,7 +411,7 @@ int hidinput_connect(struct hid_device *hid) { - struct usb_device *dev = hid->dev; + struct usb_device *dev = hid->intf->usb_device; struct hid_report_enum *report_enum; struct hid_report *report; struct list_head *list; @@ -436,6 +436,7 @@ hid->input.idvendor = dev->descriptor.idVendor; hid->input.idproduct = dev->descriptor.idProduct; hid->input.idversion = dev->descriptor.bcdDevice; + hid->input.dev = &hid->intf->dev; for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { report_enum = hid->report_enum + k; diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/hid.h linux-2.5-driverfs/drivers/usb/input/hid.h --- ../linux-2.5/drivers/usb/input/hid.h Mon Jun 3 10:25:15 2002 +++ linux-2.5-driverfs/drivers/usb/input/hid.h Mon Jun 3 11:29:16 2002 @@ -325,9 +325,11 @@ unsigned country; /* HID country */ struct hid_report_enum report_enum[HID_REPORT_TYPES]; + struct usb_interface * intf; +#if 0 struct usb_device *dev; /* USB device */ int ifnum; /* USB interface number */ - +#endif unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ struct urb *urbin; /* Input URB */ diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/usbmouse.c linux-2.5-driverfs/drivers/usb/input/usbmouse.c --- ../linux-2.5/drivers/usb/input/usbmouse.c Thu May 23 16:06:21 2002 +++ linux-2.5-driverfs/drivers/usb/input/usbmouse.c Mon Jun 3 11:29:16 2002 @@ -149,6 +149,7 @@ mouse->dev.idvendor = dev->descriptor.idVendor; mouse->dev.idproduct = dev->descriptor.idProduct; mouse->dev.idversion = dev->descriptor.bcdDevice; + mouse->dev.dev = &mouse->usbdev->dev; if (!(buf = kmalloc(63, GFP_KERNEL))) { kfree(mouse); diff -Naur -X ../dontdiff ../linux-2.5/include/linux/usb.h linux-2.5-driverfs/include/linux/usb.h --- ../linux-2.5/include/linux/usb.h Mon Jun 3 12:03:57 2002 +++ linux-2.5-driverfs/include/linux/usb.h Mon Jun 3 11:29:30 2002 @@ -248,11 +248,13 @@ struct usb_interface { struct usb_interface_descriptor *altsetting; + int ifnum; /* interface number of device */ int act_altsetting; /* active alternate setting */ int num_altsetting; /* number of alternate settings */ int max_altsetting; /* total memory allocated */ struct usb_driver *driver; /* driver */ + struct usb_device *usb_device; /* device this interface is on */ struct device dev; /* interface specific device info */ void *private_data; }; @@ -394,8 +396,6 @@ struct usb_device *parent; /* our hub, unless we're the root */ 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 */ @@ -683,6 +683,12 @@ struct module *owner; const char *name; + int (*new_probe)(struct usb_interface * intf); + int (*init)(struct usb_interface * intf); + void (*new_disco)(struct usb_interface * intf); + + struct device_driver driver; + void *(*probe)( struct usb_device *dev, /* the device */ unsigned intf, /* what interface */ @@ -722,6 +728,10 @@ extern int usb_register(struct usb_driver *); extern void usb_deregister(struct usb_driver *); +/* new school */ +extern int usb_driver_register(struct usb_driver *); +extern void usb_driver_unregister(struct usb_driver *); + #ifndef CONFIG_USB_DYNAMIC_MINORS static inline int usb_register_dev(struct usb_driver *new_driver, int num_minors, int *start_minor) { return -ENODEV; } static inline void usb_deregister_dev(struct usb_driver *driver, int num_minors, int start_minor) {}