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 = {
.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",
.release = &release_usb_class_dev,
};
int usb_major_init(void)
......@@ -91,9 +98,8 @@ void usb_major_cleanup(void)
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 usb_register_dev(struct usb_interface *intf,
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 @@ int usb_register_dev(struct usb_interface *intf,
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;
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(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);
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 @@ void usb_deregister_dev(struct usb_interface *intf,
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);
......
......@@ -123,10 +123,9 @@ struct usb_interface {
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)
......
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