diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-15 08:58:13 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-15 08:58:13 -0800 |
commit | 7f6cd5408a8ace522ca7f15893243e94ccc913e0 (patch) | |
tree | aa84ba9df6b7f9af26c84162a455f9010bd8d285 /drivers/usb | |
parent | e956e6b77054f91580deb81ba6389cc8c8ce67ef (diff) | |
parent | c2d284ee04ab6f6718de2ddcf1b43160e046c41d (diff) | |
download | linux-7f6cd5408a8ace522ca7f15893243e94ccc913e0.tar.bz2 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
USB: Close usb_find_interface race v3
Revert "USB: Close usb_find_interface race"
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/usb.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 043fa833eeca..2fb42043b305 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -167,18 +167,23 @@ struct usb_host_interface *usb_altnum_to_altsetting( } EXPORT_SYMBOL_GPL(usb_altnum_to_altsetting); +struct find_interface_arg { + int minor; + struct device_driver *drv; +}; + static int __find_interface(struct device *dev, void *data) { - int *minor = data; + struct find_interface_arg *arg = data; struct usb_interface *intf; if (!is_usb_interface(dev)) return 0; + if (dev->driver != arg->drv) + return 0; intf = to_usb_interface(dev); - if (intf->minor != -1 && intf->minor == *minor) - return 1; - return 0; + return intf->minor == arg->minor; } /** @@ -187,14 +192,18 @@ static int __find_interface(struct device *dev, void *data) * @minor: the minor number of the desired device * * This walks the bus device list and returns a pointer to the interface - * with the matching minor. Note, this only works for devices that share the - * USB major number. + * with the matching minor and driver. Note, this only works for devices + * that share the USB major number. */ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) { + struct find_interface_arg argb; struct device *dev; - dev = bus_find_device(&usb_bus_type, NULL, &minor, __find_interface); + argb.minor = minor; + argb.drv = &drv->drvwrap.driver; + + dev = bus_find_device(&usb_bus_type, NULL, &argb, __find_interface); /* Drop reference count from bus_find_device */ put_device(dev); |