X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fcore%2Ffile.c;fp=drivers%2Fusb%2Fcore%2Ffile.c;h=37b13368c8145c9ca8522aab5d074d30dc3eb42f;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=8de4f8c99d61f3a7cb01696bde29202ed814b160;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 8de4f8c99..37b13368c 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -15,6 +15,7 @@ * */ +#include #include #include #include @@ -23,15 +24,15 @@ #include "usb.h" #define MAX_USB_MINORS 256 -static const struct file_operations *usb_minors[MAX_USB_MINORS]; +static struct file_operations *usb_minors[MAX_USB_MINORS]; static DEFINE_SPINLOCK(minor_lock); static int usb_open(struct inode * inode, struct file * file) { int minor = iminor(inode); - const struct file_operations *c; + struct file_operations *c; int err = -ENODEV; - const struct file_operations *old_fops, *new_fops = NULL; + struct file_operations *old_fops, *new_fops = NULL; spin_lock (&minor_lock); c = usb_minors[minor]; @@ -60,66 +61,33 @@ static struct file_operations usb_fops = { .open = usb_open, }; -static struct usb_class { - struct kref kref; - struct class *class; -} *usb_class; - -static int init_usb_class(void) -{ - int result = 0; - - if (usb_class != NULL) { - kref_get(&usb_class->kref); - goto exit; - } - - usb_class = kmalloc(sizeof(*usb_class), GFP_KERNEL); - if (!usb_class) { - result = -ENOMEM; - goto exit; - } - - kref_init(&usb_class->kref); - usb_class->class = class_create(THIS_MODULE, "usb"); - if (IS_ERR(usb_class->class)) { - result = IS_ERR(usb_class->class); - err("class_create failed for usb devices"); - kfree(usb_class); - usb_class = NULL; - } - -exit: - return result; -} - -static void release_usb_class(struct kref *kref) -{ - /* Ok, we cheat as we know we only have one usb_class */ - class_destroy(usb_class->class); - kfree(usb_class); - usb_class = NULL; -} - -static void destroy_usb_class(void) -{ - if (usb_class) - kref_put(&usb_class->kref, release_usb_class); -} +static struct class *usb_class; int usb_major_init(void) { int error; error = register_chrdev(USB_MAJOR, "usb", &usb_fops); - if (error) + if (error) { err("unable to get major %d for usb devices", USB_MAJOR); + goto out; + } + usb_class = class_create(THIS_MODULE, "usb"); + if (IS_ERR(usb_class)) { + error = PTR_ERR(usb_class); + err("class_create failed for usb devices"); + unregister_chrdev(USB_MAJOR, "usb"); + goto out; + } + +out: return error; } void usb_major_cleanup(void) { + class_destroy(usb_class); unregister_chrdev(USB_MAJOR, "usb"); } @@ -178,10 +146,6 @@ int usb_register_dev(struct usb_interface *intf, } spin_unlock (&minor_lock); - if (retval) - goto exit; - - retval = init_usb_class(); if (retval) goto exit; @@ -194,7 +158,7 @@ int usb_register_dev(struct usb_interface *intf, ++temp; else temp = name; - intf->class_dev = class_device_create(usb_class->class, NULL, + intf->class_dev = class_device_create(usb_class, NULL, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp); if (IS_ERR(intf->class_dev)) { @@ -242,10 +206,9 @@ void usb_deregister_dev(struct usb_interface *intf, spin_unlock (&minor_lock); snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); - class_device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); + class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); intf->class_dev = NULL; intf->minor = -1; - destroy_usb_class(); } EXPORT_SYMBOL(usb_deregister_dev);