# 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.520 -> 1.521 # drivers/usb/core/hub.h 1.11 -> 1.12 # drivers/usb/core/message.c 1.6 -> 1.7 # drivers/usb/core/hcd.h 1.12 -> 1.13 # include/linux/usb.h 1.44 -> 1.45 # drivers/usb/core/devio.c 1.32 -> 1.33 # drivers/usb/core/usb.c 1.80 -> 1.81 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/08/14 david-b@pacbell.net 1.521 # [PATCH] USB core cleanups # # Moves some functions that are only used by usbfs to be private, and # documents some of the interface issues that need to be cleaned up. # -------------------------------------------- # diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c --- a/drivers/usb/core/devio.c Wed Aug 14 14:41:50 2002 +++ b/drivers/usb/core/devio.c Wed Aug 14 14:41:50 2002 @@ -46,6 +46,7 @@ #include #include +#include "hcd.h" /* for usbcore internals */ struct async { struct list_head asynclist; @@ -724,7 +725,7 @@ lock_kernel(); if (intf->driver && ps->dev) { - usb_bind_driver(intf->driver,ps->dev, i); + usb_bind_driver (intf->driver, intf); } unlock_kernel(); } @@ -1062,8 +1063,8 @@ int size; void *buf = 0; int retval = 0; - struct usb_interface *ifp = 0; - struct usb_driver *driver = 0; + struct usb_interface *ifp = 0; + struct usb_driver *driver = 0; /* get input parameters and alloc buffer */ if (copy_from_user(&ctrl, (void *) arg, sizeof (ctrl))) @@ -1102,10 +1103,10 @@ unlock_kernel(); break; - /* let kernel drivers try to (re)bind to the interface */ - case USBDEVFS_CONNECT: - usb_find_interface_driver_for_ifnum (ps->dev, ctrl.ifno); - break; + /* let kernel drivers try to (re)bind to the interface */ + case USBDEVFS_CONNECT: + usb_find_interface_driver (ps->dev, ifp); + break; /* talk directly to the interface's driver */ default: @@ -1144,6 +1145,11 @@ return retval; } +/* + * NOTE: All requests here that have interface numbers as parameters + * are assuming that somehow the configuration has been prevented from + * changing. But there's no mechanism to ensure that... + */ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct dev_state *ps = (struct dev_state *)file->private_data; diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h Wed Aug 14 14:41:50 2002 +++ b/drivers/usb/core/hcd.h Wed Aug 14 14:41:50 2002 @@ -348,6 +348,16 @@ extern void usb_bus_get (struct usb_bus *bus); extern void usb_bus_put (struct usb_bus *bus); +extern struct usb_interface *usb_ifnum_to_if (struct usb_device *dev, + unsigned ifnum); + +extern int usb_find_interface_driver (struct usb_device *dev, + struct usb_interface *interface); + +/* for probe/disconnect with correct module usage counting */ +void *usb_bind_driver(struct usb_driver *driver, struct usb_interface *intf); +void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf); + /*-------------------------------------------------------------------------*/ /* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */ diff -Nru a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h --- a/drivers/usb/core/hub.h Wed Aug 14 14:41:50 2002 +++ b/drivers/usb/core/hub.h Wed Aug 14 14:41:50 2002 @@ -123,6 +123,10 @@ * Hub descriptor * See USB 2.0 spec Table 11-13 */ + +#define USB_DT_HUB (USB_TYPE_CLASS | 0x09) +#define USB_DT_HUB_NONVAR_SIZE 7 + struct usb_hub_descriptor { __u8 bDescLength; __u8 bDescriptorType; diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c Wed Aug 14 14:41:50 2002 +++ b/drivers/usb/core/message.c Wed Aug 14 14:41:50 2002 @@ -8,6 +8,8 @@ #include #include +#include "hcd.h" /* for usbcore internals */ + struct usb_api_data { wait_queue_head_t wqh; int done; diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Wed Aug 14 14:41:50 2002 +++ b/drivers/usb/core/usb.c Wed Aug 14 14:41:50 2002 @@ -52,7 +52,6 @@ * 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 *); /* @@ -119,7 +118,7 @@ } /** - * usb_unbind_driver - disconnects a driver from a device + * usb_unbind_driver - disconnects a driver from a device (usbcore-internal) * @device: usb device to be disconnected * @intf: interface of the device to be disconnected * Context: BKL held @@ -164,21 +163,27 @@ } /** - * usb_bind_driver - connect a driver to a device's interface - * @driver: device driver to be bound to a devices interface - * @dev: device to be bound - * @ifnum: index number of the interface to be used + * usb_bind_driver - connect a driver to a device's interface (usbcore-internal) + * @driver: device driver to be bound to interface + * @interface: interface that the driver will be using + * Context: BKL held * - * Does a save binding of a driver to a device's interface - * Returns a pointer to the drivers private description of the binding + * Does a safe binding of a driver to one of a device's interfaces. + * Returns the driver's data for the binding, or null indicating + * that the driver did not bind to this interface. + * + * This differs from usb_driver_claim_interface(), which is called from + * drivers and neither calls the driver's probe() entry nor does any + * locking to guard against removing driver modules. */ - -void *usb_bind_driver(struct usb_driver *driver, struct usb_device *dev, unsigned int ifnum) +void * +usb_bind_driver (struct usb_driver *driver, struct usb_interface *interface) { int i,m; void *private = NULL; const struct usb_device_id *id; - struct usb_interface *interface; + struct usb_device *dev = interface_to_usbdev (interface); + int ifnum; if (driver->owner) { m = try_inc_mod_count(driver->owner); @@ -187,7 +192,14 @@ unlock_kernel(); } - interface = &dev->actconfig->interface[ifnum]; + // START TEMPORARY + // driver->probe() hasn't yet changed to take interface not dev+ifnum, + // so we still need ifnum here. + for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) + if (&dev->actconfig->interface [ifnum] == interface) + break; + BUG_ON (ifnum == dev->actconfig->bNumInterfaces); + // END TEMPORARY id = driver->id_table; /* new style driver? */ @@ -252,7 +264,7 @@ * This will go through the list looking for another * driver that can handle the device */ - usb_find_interface_driver(dev, i); + usb_find_interface_driver(dev, interface); } } } @@ -294,29 +306,7 @@ } /** - * usb_ifnum_to_ifpos - convert the interface number to the interface position - * @dev: the device to use - * @ifnum: the interface number (bInterfaceNumber); not interface position - * - * This is used to convert the interface _number_ (as in - * interface.bInterfaceNumber) to the interface _position_ (as in - * dev->actconfig->interface + position). Note that the number is the same as - * the position for all interfaces _except_ devices with interfaces not - * sequentially numbered (e.g., 0, 2, 3, etc). - */ -int usb_ifnum_to_ifpos(struct usb_device *dev, unsigned ifnum) -{ - int i; - - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) - if (dev->actconfig->interface[i].altsetting[0].bInterfaceNumber == ifnum) - return i; - - return -EINVAL; -} - -/** - * usb_ifnum_to_if - get the interface object with a given interface number + * usb_ifnum_to_if - get the interface object with a given interface number (usbcore-internal) * @dev: the device whose current configuration is considered * @ifnum: the desired interface * @@ -392,7 +382,8 @@ /* now we check this device */ if (dev->devnum > 0) for (i = 0; i < dev->actconfig->bNumInterfaces; i++) - usb_find_interface_driver(dev, i); + usb_find_interface_driver (dev, + dev->actconfig->interface + i); } @@ -605,7 +596,7 @@ } /* - * This entrypoint gets called for each new device. + * This entrypoint gets called for unclaimed interfaces. * * We now walk the list of registered USB drivers, * looking for one that will accept this interface. @@ -620,21 +611,27 @@ * * Returns: 0 if a driver accepted the interface, -1 otherwise */ -static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum) +int usb_find_interface_driver ( + struct usb_device *dev, + struct usb_interface *interface +) { struct list_head *tmp; - struct usb_interface *interface; void *private; struct usb_driver *driver; + int ifnum; - if ((!dev) || (ifnum >= dev->actconfig->bNumInterfaces)) { - err("bad find_interface_driver params"); - return -1; - } - down(&dev->serialize); - interface = dev->actconfig->interface + ifnum; + /* FIXME It's just luck that for some devices with drivers that set + * configuration in probe(), the interface numbers still make sense. + * That's one of several unsafe assumptions involved in configuring + * devices, and in binding drivers to their interfaces. + */ + for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) + if (&dev->actconfig->interface [ifnum] == interface) + break; + BUG_ON (ifnum == dev->actconfig->bNumInterfaces); if (usb_interface_claimed(interface)) goto out_err; @@ -645,7 +642,7 @@ driver = list_entry(tmp, struct usb_driver, driver_list); tmp = tmp->next; - private = usb_bind_driver(driver, dev, ifnum); + private = usb_bind_driver(driver, interface); /* probe() may have changed the config on us */ interface = dev->actconfig->interface + ifnum; @@ -664,25 +661,6 @@ return -1; } -/** - * 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 (0 > ifpos) - return -EINVAL; - - return usb_find_interface_driver(dev, ifpos); -} - #ifdef CONFIG_HOTPLUG /* @@ -956,7 +934,7 @@ /* if this interface hasn't already been claimed */ if (!usb_interface_claimed(interface)) { - if (usb_find_interface_driver(dev, ifnum)) + if (usb_find_interface_driver(dev, interface)) rejected++; else claimed++; @@ -1655,8 +1633,6 @@ * These symbols are exported for device (or host controller) * driver modules to use. */ -EXPORT_SYMBOL(usb_ifnum_to_ifpos); -EXPORT_SYMBOL(usb_ifnum_to_if); EXPORT_SYMBOL(usb_epnum_to_ep_desc); EXPORT_SYMBOL(usb_register); @@ -1668,7 +1644,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); @@ -1679,8 +1654,6 @@ EXPORT_SYMBOL(usb_reset_device); EXPORT_SYMBOL(usb_connect); EXPORT_SYMBOL(usb_disconnect); -EXPORT_SYMBOL(usb_bind_driver); -EXPORT_SYMBOL(usb_unbind_driver); EXPORT_SYMBOL(__usb_get_extra_descriptor); diff -Nru a/include/linux/usb.h b/include/linux/usb.h --- a/include/linux/usb.h Wed Aug 14 14:41:50 2002 +++ b/include/linux/usb.h Wed Aug 14 14:41:50 2002 @@ -167,10 +167,6 @@ #define USB_DT_OTHER_SPEED_CONFIG 0x07 #define USB_DT_INTERFACE_POWER 0x08 -// FIXME should be internal to hub driver -#define USB_DT_HUB (USB_TYPE_CLASS | 0x09) -#define USB_DT_HUB_NONVAR_SIZE 7 - /* * Descriptor sizes per descriptor type */ @@ -258,6 +254,8 @@ void *private_data; }; #define to_usb_interface(d) container_of(d, struct usb_interface, dev) +#define interface_to_usbdev(intf) \ + container_of(intf->dev.parent, struct usb_device, dev) /* USB_DT_CONFIG: Configuration descriptor information. * @@ -303,10 +301,8 @@ __u8 bRESERVED; } __attribute__ ((packed)); -/* helpers for driver access to descriptors */ -extern int usb_ifnum_to_ifpos(struct usb_device *dev, unsigned ifnum); -extern struct usb_interface * - usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum); +// FIXME remove; exported only for drivers/usb/misc/auserwald.c +// prefer usb_device->epnum[0..31] extern struct usb_endpoint_descriptor * usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum); @@ -435,10 +431,6 @@ /* for when layers above USB add new non-USB drivers */ extern void usb_scan_devices(void); -/* for probe/disconnect with correct module usage counting */ -void *usb_bind_driver(struct usb_driver *driver, struct usb_device *dev, unsigned int ifnum); -void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf); - /* mostly for devices emulating SCSI over USB */ extern int usb_reset_device(struct usb_device *dev); @@ -446,7 +438,6 @@ extern int usb_get_current_frame_number (struct usb_device *usb_dev); /* used these for multi-interface device registration */ -extern int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned int ifnum); extern void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv); extern int usb_interface_claimed(struct usb_interface *iface);