aboutsummaryrefslogtreecommitdiffstats
path: root/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-06-20 15:28:29 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-20 15:28:29 -0700
commit47fc8ed39343700b4bedc64121982f217695a5f6 (patch)
treeaaa7726ea41ddf358935f844eb9ea4e46e9d9398 /usb
parentf3fac81def54871901b5760452e2e08b39139d16 (diff)
downloadpatches-47fc8ed39343700b4bedc64121982f217695a5f6.tar.gz
add dynamice usb class patch
Diffstat (limited to 'usb')
-rw-r--r--usb/usb-dynamic-usb-class.patch133
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);
+