diff options
Diffstat (limited to 'drivers/hid/hid-roccat.c')
| -rw-r--r-- | drivers/hid/hid-roccat.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index 5666e7587b1..65c4ccfcbd2 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -27,6 +27,7 @@ #include <linux/poll.h> #include <linux/sched.h> #include <linux/hid-roccat.h> +#include <linux/module.h> #define ROCCAT_FIRST_MINOR 0 #define ROCCAT_MAX_DEVICES 8 @@ -162,27 +163,27 @@ static int roccat_open(struct inode *inode, struct file *file) device = devices[minor]; - mutex_lock(&device->readers_lock); - if (!device) { pr_emerg("roccat device with minor %d doesn't exist\n", minor); error = -ENODEV; - goto exit_err; + goto exit_err_devices; } + mutex_lock(&device->readers_lock); + if (!device->open++) { /* power on device on adding first reader */ error = hid_hw_power(device->hid, PM_HINT_FULLON); if (error < 0) { --device->open; - goto exit_err; + goto exit_err_readers; } error = hid_hw_open(device->hid); if (error < 0) { hid_hw_power(device->hid, PM_HINT_NORMAL); --device->open; - goto exit_err; + goto exit_err_readers; } } @@ -193,13 +194,13 @@ static int roccat_open(struct inode *inode, struct file *file) list_add_tail(&reader->node, &device->readers); file->private_data = reader; -exit_unlock: +exit_err_readers: mutex_unlock(&device->readers_lock); +exit_err_devices: mutex_unlock(&devices_lock); + if (error) + kfree(reader); return error; -exit_err: - kfree(reader); - goto exit_unlock; } static int roccat_release(struct inode *inode, struct file *file) @@ -241,7 +242,6 @@ static int roccat_release(struct inode *inode, struct file *file) * roccat_report_event() - output data to readers * @minor: minor device number returned by roccat_connect() * @data: pointer to data - * @len: size of data * * Return value is zero on success, a negative error code on failure. * @@ -289,6 +289,7 @@ EXPORT_SYMBOL_GPL(roccat_report_event); * @class: the class thats used to create the device. Meant to hold device * specific sysfs attributes. * @hid: the hid device the char device should be connected to. + * @report_size: size of reports * * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on * success, a negative error code on failure. @@ -365,7 +366,7 @@ void roccat_disconnect(int minor) mutex_lock(&devices_lock); devices[minor] = NULL; mutex_unlock(&devices_lock); - + if (device->open) { hid_hw_close(device->hid); wake_up_interruptible(&device->wait); @@ -377,7 +378,7 @@ EXPORT_SYMBOL_GPL(roccat_disconnect); static long roccat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; + struct inode *inode = file_inode(file); struct roccat_device *device; unsigned int minor = iminor(inode); long retval = 0; @@ -425,13 +426,23 @@ static int __init roccat_init(void) if (retval < 0) { pr_warn("can't get major number\n"); - return retval; + goto error; } cdev_init(&roccat_cdev, &roccat_ops); - cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES); + retval = cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES); + if (retval < 0) { + pr_warn("cannot add cdev\n"); + goto cleanup_alloc_chrdev_region; + } return 0; + + + cleanup_alloc_chrdev_region: + unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES); + error: + return retval; } static void __exit roccat_exit(void) |
