X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fusb%2Fcore%2Ffile.c;h=5d860bc9b42143f6729a9df40521ec42943b21b1;hb=7071a3ce0ca058ad2a9e3e8c33f30fb0bce62005;hp=01c857ac27afc09eed98c1a190d794073b73c470;hpb=64106104dd2d4a6280777e88c1cbf9f7a52c30bd;p=linux-2.6-omap-h63xx.git diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 01c857ac27a..913fb866789 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -16,15 +16,16 @@ */ #include -#include #include +#include +#include #include #include "usb.h" #define MAX_USB_MINORS 256 static const struct file_operations *usb_minors[MAX_USB_MINORS]; -static DEFINE_SPINLOCK(minor_lock); +static DECLARE_RWSEM(minor_rwsem); static int usb_open(struct inode * inode, struct file * file) { @@ -33,14 +34,12 @@ static int usb_open(struct inode * inode, struct file * file) int err = -ENODEV; const struct file_operations *old_fops, *new_fops = NULL; - spin_lock (&minor_lock); + lock_kernel(); + down_read(&minor_rwsem); c = usb_minors[minor]; - if (!c || !(new_fops = fops_get(c))) { - spin_unlock(&minor_lock); - return err; - } - spin_unlock(&minor_lock); + if (!c || !(new_fops = fops_get(c))) + goto done; old_fops = file->f_op; file->f_op = new_fops; @@ -52,6 +51,9 @@ static int usb_open(struct inode * inode, struct file * file) file->f_op = fops_get(old_fops); } fops_put(old_fops); + done: + up_read(&minor_rwsem); + unlock_kernel(); return err; } @@ -148,7 +150,7 @@ int usb_register_dev(struct usb_interface *intf, int retval = -EINVAL; int minor_base = class_driver->minor_base; int minor = 0; - char name[BUS_ID_SIZE]; + char name[20]; char *temp; #ifdef CONFIG_USB_DYNAMIC_MINORS @@ -166,7 +168,7 @@ int usb_register_dev(struct usb_interface *intf, if (class_driver->fops == NULL) goto exit; - spin_lock (&minor_lock); + down_write(&minor_rwsem); for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) { if (usb_minors[minor]) continue; @@ -176,7 +178,7 @@ int usb_register_dev(struct usb_interface *intf, retval = 0; break; } - spin_unlock (&minor_lock); + up_write(&minor_rwsem); if (retval) goto exit; @@ -188,24 +190,24 @@ int usb_register_dev(struct usb_interface *intf, intf->minor = minor; /* create a usb class device for this usb interface */ - snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base); + snprintf(name, sizeof(name), class_driver->name, minor - minor_base); temp = strrchr(name, '/'); - if (temp && (temp[1] != 0x00)) + if (temp && (temp[1] != '\0')) ++temp; else temp = name; intf->usb_dev = device_create(usb_class->class, &intf->dev, MKDEV(USB_MAJOR, minor), "%s", temp); if (IS_ERR(intf->usb_dev)) { - spin_lock (&minor_lock); + down_write(&minor_rwsem); usb_minors[intf->minor] = NULL; - spin_unlock (&minor_lock); + up_write(&minor_rwsem); retval = PTR_ERR(intf->usb_dev); } exit: return retval; } -EXPORT_SYMBOL(usb_register_dev); +EXPORT_SYMBOL_GPL(usb_register_dev); /** * usb_deregister_dev - deregister a USB device's dynamic minor. @@ -225,7 +227,7 @@ void usb_deregister_dev(struct usb_interface *intf, struct usb_class_driver *class_driver) { int minor_base = class_driver->minor_base; - char name[BUS_ID_SIZE]; + char name[20]; #ifdef CONFIG_USB_DYNAMIC_MINORS minor_base = 0; @@ -236,16 +238,14 @@ void usb_deregister_dev(struct usb_interface *intf, dbg ("removing %d minor", intf->minor); - spin_lock (&minor_lock); + down_write(&minor_rwsem); usb_minors[intf->minor] = NULL; - spin_unlock (&minor_lock); + up_write(&minor_rwsem); - snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); + snprintf(name, sizeof(name), class_driver->name, intf->minor - minor_base); device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); intf->usb_dev = NULL; intf->minor = -1; destroy_usb_class(); } -EXPORT_SYMBOL(usb_deregister_dev); - - +EXPORT_SYMBOL_GPL(usb_deregister_dev);