ChangeSet 1.1123.18.11, 2003/08/13 13:36:06-07:00, greg@kroah.com

[PATCH] USB: fix usb class device sysfs representation.

Again, I messed up the usage, now we are safe from devices being removed.
This fixes a number of error reports from users.


 drivers/usb/core/file.c |   49 +++++++++++++++++++++++++++++++-----------------
 include/linux/usb.h     |    3 --
 2 files changed, 33 insertions(+), 19 deletions(-)


diff -Nru a/drivers/usb/core/file.c b/drivers/usb/core/file.c
--- a/drivers/usb/core/file.c	Fri Aug 15 10:46:31 2003
+++ b/drivers/usb/core/file.c	Fri Aug 15 10:46:31 2003
@@ -66,8 +66,15 @@
 	.open =		usb_open,
 };
 
+static void release_usb_class_dev(struct class_device *class_dev)
+{
+	dbg("%s - %s", __FUNCTION__, class_dev->class_id);
+	kfree(class_dev);
+}
+
 static struct class usb_class = {
-	.name	= "usb",
+	.name		= "usb",
+	.release	= &release_usb_class_dev,
 };
 
 int usb_major_init(void)
@@ -91,9 +98,8 @@
 
 static ssize_t show_dev(struct class_device *class_dev, char *buf)
 {
-	struct usb_interface *intf = class_dev_to_usb_interface(class_dev);
-	dev_t dev = MKDEV(USB_MAJOR, intf->minor);
-	return print_dev_t(buf, dev);
+	int minor = (int)class_get_devdata(class_dev);
+	return print_dev_t(buf, MKDEV(USB_MAJOR, minor));
 }
 static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
 
@@ -124,6 +130,7 @@
 	int minor_base = class_driver->minor_base;
 	int minor = 0;
 	char name[DEVICE_ID_SIZE];
+	struct class_device *class_dev;
 	char *temp;
 
 #ifdef CONFIG_USB_DYNAMIC_MINORS
@@ -163,18 +170,23 @@
 	devfs_mk_cdev(MKDEV(USB_MAJOR, minor), class_driver->mode, name);
 
 	/* create a usb class device for this usb interface */
-	memset(&intf->class_dev, 0x00, sizeof(struct class_device));
-	intf->class_dev.class = &usb_class;
-	intf->class_dev.dev = &intf->dev;
-
-	temp = strrchr(name, '/');
-	if (temp && (temp[1] != 0x00))
-		++temp;
-	else
-		temp = name;
-	snprintf(intf->class_dev.class_id, BUS_ID_SIZE, "%s", temp);
-	class_device_register(&intf->class_dev);
-	class_device_create_file (&intf->class_dev, &class_device_attr_dev);
+	class_dev = kmalloc(sizeof(*class_dev), GFP_KERNEL);
+	if (class_dev) {
+		memset(class_dev, 0x00, sizeof(struct class_device));
+		class_dev->class = &usb_class;
+		class_dev->dev = &intf->dev;
+
+		temp = strrchr(name, '/');
+		if (temp && (temp[1] != 0x00))
+			++temp;
+		else
+			temp = name;
+		snprintf(class_dev->class_id, BUS_ID_SIZE, "%s", temp);
+		class_set_devdata(class_dev, (void *)intf->minor);
+		class_device_register(class_dev);
+		class_device_create_file(class_dev, &class_device_attr_dev);
+		intf->class_dev = class_dev;
+	}
 exit:
 	return retval;
 }
@@ -217,7 +229,10 @@
 	snprintf(name, DEVICE_ID_SIZE, class_driver->name, intf->minor - minor_base);
 	devfs_remove (name);
 
-	class_device_unregister(&intf->class_dev);
+	if (intf->class_dev) {
+		class_device_unregister(intf->class_dev);
+		intf->class_dev = NULL;
+	}
 	intf->minor = -1;
 }
 EXPORT_SYMBOL(usb_deregister_dev);
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Fri Aug 15 10:46:31 2003
+++ b/include/linux/usb.h	Fri Aug 15 10:46:31 2003
@@ -123,10 +123,9 @@
 	struct usb_driver *driver;	/* driver */
 	int minor;			/* minor number this interface is bound to */
 	struct device dev;		/* interface specific device info */
-	struct class_device class_dev;
+	struct class_device *class_dev;
 };
 #define	to_usb_interface(d) container_of(d, struct usb_interface, dev)
-#define class_dev_to_usb_interface(d) container_of(d, struct usb_interface, class_dev)
 #define	interface_to_usbdev(intf) \
 	container_of(intf->dev.parent, struct usb_device, dev)
 
