Commit ea027460 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

[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.
parent 9fdd2c89
...@@ -66,8 +66,15 @@ static struct file_operations usb_fops = { ...@@ -66,8 +66,15 @@ static struct file_operations usb_fops = {
.open = usb_open, .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 = { static struct class usb_class = {
.name = "usb", .name = "usb",
.release = &release_usb_class_dev,
}; };
int usb_major_init(void) int usb_major_init(void)
...@@ -91,9 +98,8 @@ void usb_major_cleanup(void) ...@@ -91,9 +98,8 @@ void usb_major_cleanup(void)
static ssize_t show_dev(struct class_device *class_dev, char *buf) static ssize_t show_dev(struct class_device *class_dev, char *buf)
{ {
struct usb_interface *intf = class_dev_to_usb_interface(class_dev); int minor = (int)class_get_devdata(class_dev);
dev_t dev = MKDEV(USB_MAJOR, intf->minor); return print_dev_t(buf, MKDEV(USB_MAJOR, minor));
return print_dev_t(buf, dev);
} }
static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
...@@ -124,6 +130,7 @@ int usb_register_dev(struct usb_interface *intf, ...@@ -124,6 +130,7 @@ int usb_register_dev(struct usb_interface *intf,
int minor_base = class_driver->minor_base; int minor_base = class_driver->minor_base;
int minor = 0; int minor = 0;
char name[DEVICE_ID_SIZE]; char name[DEVICE_ID_SIZE];
struct class_device *class_dev;
char *temp; char *temp;
#ifdef CONFIG_USB_DYNAMIC_MINORS #ifdef CONFIG_USB_DYNAMIC_MINORS
...@@ -163,18 +170,23 @@ int usb_register_dev(struct usb_interface *intf, ...@@ -163,18 +170,23 @@ int usb_register_dev(struct usb_interface *intf,
devfs_mk_cdev(MKDEV(USB_MAJOR, minor), class_driver->mode, name); devfs_mk_cdev(MKDEV(USB_MAJOR, minor), class_driver->mode, name);
/* create a usb class device for this usb interface */ /* create a usb class device for this usb interface */
memset(&intf->class_dev, 0x00, sizeof(struct class_device)); class_dev = kmalloc(sizeof(*class_dev), GFP_KERNEL);
intf->class_dev.class = &usb_class; if (class_dev) {
intf->class_dev.dev = &intf->dev; memset(class_dev, 0x00, sizeof(struct class_device));
class_dev->class = &usb_class;
class_dev->dev = &intf->dev;
temp = strrchr(name, '/'); temp = strrchr(name, '/');
if (temp && (temp[1] != 0x00)) if (temp && (temp[1] != 0x00))
++temp; ++temp;
else else
temp = name; temp = name;
snprintf(intf->class_dev.class_id, BUS_ID_SIZE, "%s", temp); snprintf(class_dev->class_id, BUS_ID_SIZE, "%s", temp);
class_device_register(&intf->class_dev); class_set_devdata(class_dev, (void *)intf->minor);
class_device_create_file (&intf->class_dev, &class_device_attr_dev); class_device_register(class_dev);
class_device_create_file(class_dev, &class_device_attr_dev);
intf->class_dev = class_dev;
}
exit: exit:
return retval; return retval;
} }
...@@ -217,7 +229,10 @@ void usb_deregister_dev(struct usb_interface *intf, ...@@ -217,7 +229,10 @@ void usb_deregister_dev(struct usb_interface *intf,
snprintf(name, DEVICE_ID_SIZE, class_driver->name, intf->minor - minor_base); snprintf(name, DEVICE_ID_SIZE, class_driver->name, intf->minor - minor_base);
devfs_remove (name); 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; intf->minor = -1;
} }
EXPORT_SYMBOL(usb_deregister_dev); EXPORT_SYMBOL(usb_deregister_dev);
......
...@@ -123,10 +123,9 @@ struct usb_interface { ...@@ -123,10 +123,9 @@ struct usb_interface {
struct usb_driver *driver; /* driver */ struct usb_driver *driver; /* driver */
int minor; /* minor number this interface is bound to */ int minor; /* minor number this interface is bound to */
struct device dev; /* interface specific device info */ 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 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) \ #define interface_to_usbdev(intf) \
container_of(intf->dev.parent, struct usb_device, dev) container_of(intf->dev.parent, struct usb_device, dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment