0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <linux/module.h>
0021 #include <linux/errno.h>
0022 #include <linux/rwsem.h>
0023 #include <linux/slab.h>
0024 #include <linux/string.h>
0025 #include <linux/usb.h>
0026
0027 #include "usb.h"
0028
0029 #define MAX_USB_MINORS 256
0030 static const struct file_operations *usb_minors[MAX_USB_MINORS];
0031 static DECLARE_RWSEM(minor_rwsem);
0032 static DEFINE_MUTEX(init_usb_class_mutex);
0033
0034 static int usb_open(struct inode *inode, struct file *file)
0035 {
0036 int err = -ENODEV;
0037 const struct file_operations *new_fops;
0038
0039 down_read(&minor_rwsem);
0040 new_fops = fops_get(usb_minors[iminor(inode)]);
0041
0042 if (!new_fops)
0043 goto done;
0044
0045 replace_fops(file, new_fops);
0046
0047 if (file->f_op->open)
0048 err = file->f_op->open(inode, file);
0049 done:
0050 up_read(&minor_rwsem);
0051 return err;
0052 }
0053
0054 static const struct file_operations usb_fops = {
0055 .owner = THIS_MODULE,
0056 .open = usb_open,
0057 .llseek = noop_llseek,
0058 };
0059
0060 static struct usb_class {
0061 struct kref kref;
0062 struct class *class;
0063 } *usb_class;
0064
0065 static char *usb_devnode(struct device *dev, umode_t *mode)
0066 {
0067 struct usb_class_driver *drv;
0068
0069 drv = dev_get_drvdata(dev);
0070 if (!drv || !drv->devnode)
0071 return NULL;
0072 return drv->devnode(dev, mode);
0073 }
0074
0075 static int init_usb_class(void)
0076 {
0077 int result = 0;
0078
0079 if (usb_class != NULL) {
0080 kref_get(&usb_class->kref);
0081 goto exit;
0082 }
0083
0084 usb_class = kmalloc(sizeof(*usb_class), GFP_KERNEL);
0085 if (!usb_class) {
0086 result = -ENOMEM;
0087 goto exit;
0088 }
0089
0090 kref_init(&usb_class->kref);
0091 usb_class->class = class_create(THIS_MODULE, "usbmisc");
0092 if (IS_ERR(usb_class->class)) {
0093 result = PTR_ERR(usb_class->class);
0094 printk(KERN_ERR "class_create failed for usb devices\n");
0095 kfree(usb_class);
0096 usb_class = NULL;
0097 goto exit;
0098 }
0099 usb_class->class->devnode = usb_devnode;
0100
0101 exit:
0102 return result;
0103 }
0104
0105 static void release_usb_class(struct kref *kref)
0106 {
0107
0108 class_destroy(usb_class->class);
0109 kfree(usb_class);
0110 usb_class = NULL;
0111 }
0112
0113 static void destroy_usb_class(void)
0114 {
0115 mutex_lock(&init_usb_class_mutex);
0116 kref_put(&usb_class->kref, release_usb_class);
0117 mutex_unlock(&init_usb_class_mutex);
0118 }
0119
0120 int usb_major_init(void)
0121 {
0122 int error;
0123
0124 error = register_chrdev(USB_MAJOR, "usb", &usb_fops);
0125 if (error)
0126 printk(KERN_ERR "Unable to get major %d for usb devices\n",
0127 USB_MAJOR);
0128
0129 return error;
0130 }
0131
0132 void usb_major_cleanup(void)
0133 {
0134 unregister_chrdev(USB_MAJOR, "usb");
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 int usb_register_dev(struct usb_interface *intf,
0157 struct usb_class_driver *class_driver)
0158 {
0159 int retval;
0160 int minor_base = class_driver->minor_base;
0161 int minor;
0162 char name[20];
0163
0164 #ifdef CONFIG_USB_DYNAMIC_MINORS
0165
0166
0167
0168
0169
0170 minor_base = 0;
0171 #endif
0172
0173 if (class_driver->fops == NULL)
0174 return -EINVAL;
0175 if (intf->minor >= 0)
0176 return -EADDRINUSE;
0177
0178 mutex_lock(&init_usb_class_mutex);
0179 retval = init_usb_class();
0180 mutex_unlock(&init_usb_class_mutex);
0181
0182 if (retval)
0183 return retval;
0184
0185 dev_dbg(&intf->dev, "looking for a minor, starting at %d\n", minor_base);
0186
0187 down_write(&minor_rwsem);
0188 for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {
0189 if (usb_minors[minor])
0190 continue;
0191
0192 usb_minors[minor] = class_driver->fops;
0193 intf->minor = minor;
0194 break;
0195 }
0196 if (intf->minor < 0) {
0197 up_write(&minor_rwsem);
0198 return -EXFULL;
0199 }
0200
0201
0202 snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
0203 intf->usb_dev = device_create(usb_class->class, &intf->dev,
0204 MKDEV(USB_MAJOR, minor), class_driver,
0205 "%s", kbasename(name));
0206 if (IS_ERR(intf->usb_dev)) {
0207 usb_minors[minor] = NULL;
0208 intf->minor = -1;
0209 retval = PTR_ERR(intf->usb_dev);
0210 }
0211 up_write(&minor_rwsem);
0212 return retval;
0213 }
0214 EXPORT_SYMBOL_GPL(usb_register_dev);
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 void usb_deregister_dev(struct usb_interface *intf,
0231 struct usb_class_driver *class_driver)
0232 {
0233 if (intf->minor == -1)
0234 return;
0235
0236 dev_dbg(&intf->dev, "removing %d minor\n", intf->minor);
0237 device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
0238
0239 down_write(&minor_rwsem);
0240 usb_minors[intf->minor] = NULL;
0241 up_write(&minor_rwsem);
0242
0243 intf->usb_dev = NULL;
0244 intf->minor = -1;
0245 destroy_usb_class();
0246 }
0247 EXPORT_SYMBOL_GPL(usb_deregister_dev);