diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-20 15:28:29 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-20 15:28:29 -0700 |
commit | 47fc8ed39343700b4bedc64121982f217695a5f6 (patch) | |
tree | aaa7726ea41ddf358935f844eb9ea4e46e9d9398 /usb | |
parent | f3fac81def54871901b5760452e2e08b39139d16 (diff) | |
download | patches-47fc8ed39343700b4bedc64121982f217695a5f6.tar.gz |
add dynamice usb class patch
Diffstat (limited to 'usb')
-rw-r--r-- | usb/usb-dynamic-usb-class.patch | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/usb/usb-dynamic-usb-class.patch b/usb/usb-dynamic-usb-class.patch new file mode 100644 index 0000000000000..c80097a44f264 --- /dev/null +++ b/usb/usb-dynamic-usb-class.patch @@ -0,0 +1,133 @@ +From foo@baz Tue Apr 9 12:12:43 2002 +Date: Tue, 20 Jun 2006 15:14:07 -0700 +To: Greg KH <greg@kroah.com> +From: Greg Kroah-Hartman <gregkh@suse.de> +Subject: USB: only make /sys/class/usb show up when there is something in it + +Now /sys/class/usb is dynamically created when we have something to put +in it, and removed when all devices go away. + +Just trying to cut down on the clutter in sysfs... + + +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/core/file.c | 70 +++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 54 insertions(+), 16 deletions(-) + +--- gregkh-2.6.orig/drivers/usb/core/file.c ++++ gregkh-2.6/drivers/usb/core/file.c +@@ -61,33 +61,66 @@ static struct file_operations usb_fops = + .open = usb_open, + }; + +-static struct class *usb_class; ++static struct usb_class { ++ struct kref kref; ++ struct class *class; ++} *usb_class; + +-int usb_major_init(void) ++static int init_usb_class(void) + { +- int error; ++ int result = 0; + +- error = register_chrdev(USB_MAJOR, "usb", &usb_fops); +- if (error) { +- err("unable to get major %d for usb devices", USB_MAJOR); +- goto out; ++ 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; + } + +- usb_class = class_create(THIS_MODULE, "usb"); +- if (IS_ERR(usb_class)) { +- error = PTR_ERR(usb_class); ++ 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"); +- unregister_chrdev(USB_MAJOR, "usb"); +- goto out; ++ kfree(usb_class); ++ usb_class = NULL; + } + +-out: ++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); ++} ++ ++int usb_major_init(void) ++{ ++ int error; ++ ++ error = register_chrdev(USB_MAJOR, "usb", &usb_fops); ++ if (error) ++ err("unable to get major %d for usb devices", USB_MAJOR); ++ + return error; + } + + void usb_major_cleanup(void) + { +- class_destroy(usb_class); + unregister_chrdev(USB_MAJOR, "usb"); + } + +@@ -149,6 +182,10 @@ int usb_register_dev(struct usb_interfac + if (retval) + goto exit; + ++ retval = init_usb_class(); ++ if (retval) ++ goto exit; ++ + intf->minor = minor; + + /* create a usb class device for this usb interface */ +@@ -158,7 +195,7 @@ int usb_register_dev(struct usb_interfac + ++temp; + else + temp = name; +- intf->usb_dev = device_create(usb_class, &intf->dev, ++ 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); +@@ -205,9 +242,10 @@ void usb_deregister_dev(struct usb_inter + spin_unlock (&minor_lock); + + snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); +- device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); ++ 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); + |