]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/core/devio.c
device create: usb: convert device_create to device_create_drvdata
[linux-2.6-omap-h63xx.git] / drivers / usb / core / devio.c
index 57bedcebf96c07884eeace55603e6784ff85d525..20290c5b15625c3b4272765ff95eefa3feb07b88 100644 (file)
@@ -552,17 +552,17 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
 
 static int match_devt(struct device *dev, void *data)
 {
-       return (dev->devt == (dev_t) data);
+       return dev->devt == (dev_t) (unsigned long) data;
 }
 
 static struct usb_device *usbdev_lookup_by_devt(dev_t devt)
 {
        struct device *dev;
 
-       dev = bus_find_device(&usb_bus_type, NULL, (void *) devt, match_devt);
+       dev = bus_find_device(&usb_bus_type, NULL,
+                             (void *) (unsigned long) devt, match_devt);
        if (!dev)
                return NULL;
-       put_device(dev);
        return container_of(dev, struct usb_device, dev);
 }
 
@@ -591,16 +591,21 @@ static int usbdev_open(struct inode *inode, struct file *file)
                dev = usbdev_lookup_by_devt(inode->i_rdev);
 #ifdef CONFIG_USB_DEVICEFS
        /* procfs file */
-       if (!dev)
+       if (!dev) {
                dev = inode->i_private;
+               if (dev && dev->usbfs_dentry &&
+                                       dev->usbfs_dentry->d_inode == inode)
+                       usb_get_dev(dev);
+               else
+                       dev = NULL;
+       }
 #endif
-       if (!dev)
+       if (!dev || dev->state == USB_STATE_NOTATTACHED)
                goto out;
        ret = usb_autoresume_device(dev);
        if (ret)
                goto out;
 
-       usb_get_dev(dev);
        ret = 0;
        ps->dev = dev;
        ps->file = file;
@@ -620,8 +625,10 @@ static int usbdev_open(struct inode *inode, struct file *file)
        list_add_tail(&ps->list, &dev->filelist);
        file->private_data = ps;
  out:
-       if (ret)
+       if (ret) {
                kfree(ps);
+               usb_put_dev(dev);
+       }
        mutex_unlock(&usbfs_mutex);
        unlock_kernel();
        return ret;
@@ -1720,20 +1727,21 @@ static struct class *usb_classdev_class;
 
 static int usb_classdev_add(struct usb_device *dev)
 {
-       int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
-
-       dev->usb_classdev = device_create(usb_classdev_class, &dev->dev,
-                               MKDEV(USB_DEVICE_MAJOR, minor),
-                               "usbdev%d.%d", dev->bus->busnum, dev->devnum);
-       if (IS_ERR(dev->usb_classdev))
-               return PTR_ERR(dev->usb_classdev);
-
+       struct device *cldev;
+
+       cldev = device_create_drvdata(usb_classdev_class, &dev->dev,
+                                     dev->dev.devt, NULL, "usbdev%d.%d",
+                                     dev->bus->busnum, dev->devnum);
+       if (IS_ERR(cldev))
+               return PTR_ERR(cldev);
+       dev->usb_classdev = cldev;
        return 0;
 }
 
 static void usb_classdev_remove(struct usb_device *dev)
 {
-       device_unregister(dev->usb_classdev);
+       if (dev->usb_classdev)
+               device_unregister(dev->usb_classdev);
        usb_fs_classdev_common_remove(dev);
 }
 
@@ -1784,6 +1792,11 @@ int __init usb_devio_init(void)
                usb_classdev_class = NULL;
                goto out;
        }
+       /* devices of this class shadow the major:minor of their parent
+        * device, so clear ->dev_kobj to prevent adding duplicate entries
+        * to /sys/dev
+        */
+       usb_classdev_class->dev_kobj = NULL;
 
        usb_register_notify(&usbdev_nb);
 #endif