diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 10:35:30 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 10:35:30 -0700 |
| commit | 7fd23a24717a327a66f3c32d11a20a2f169c824f (patch) | |
| tree | 62a731f3edac9e58427fc27396ad5da8804fa579 /drivers/hid/hid-roccat.c | |
| parent | 0a95d92c0054e74fb79607ac2df958b7bf295706 (diff) | |
| parent | 65b06194c9c9f41bc07ac6a6d42edb4b9e43fea4 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (48 commits)
HID: add support for Logitech Driving Force Pro wheel
HID: hid-ortek: remove spurious reference
HID: add support for Ortek PKB-1700
HID: roccat-koneplus: vorrect mode of sysfs attr 'sensor'
HID: hid-ntrig: init settle and mode check
HID: merge hid-egalax into hid-multitouch
HID: hid-multitouch: Send events per slot if CONTACTCOUNT is missing
HID: ntrig remove if and drop an indent
HID: ACRUX - activate the device immediately after binding
HID: ntrig: apply NO_INIT_REPORTS quirk
HID: hid-magicmouse: Correct touch orientation direction
HID: ntrig don't dereference unclaimed hidinput
HID: Do not create input devices for feature reports
HID: bt hidp: send Output reports using SET_REPORT on the Control channel
HID: hid-sony.c: Fix sending Output reports to the Sixaxis
HID: add support for Keytouch IEC 60945
HID: Add HID Report Descriptor to sysfs
HID: add IRTOUCH infrared USB to hid_have_special_driver
HID: kernel oops in out_cleanup in function hidinput_connect
HID: Add teletext/color keys - gyration remote - EU version (GYAR3101CKDE)
...
Diffstat (limited to 'drivers/hid/hid-roccat.c')
| -rw-r--r-- | drivers/hid/hid-roccat.c | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index a14c579ea78..5666e7587b1 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -26,8 +26,7 @@ #include <linux/cdev.h> #include <linux/poll.h> #include <linux/sched.h> - -#include "hid-roccat.h" +#include <linux/hid-roccat.h> #define ROCCAT_FIRST_MINOR 0 #define ROCCAT_MAX_DEVICES 8 @@ -37,11 +36,11 @@ struct roccat_report { uint8_t *value; - int len; }; struct roccat_device { unsigned int minor; + int report_size; int open; int exist; wait_queue_head_t wait; @@ -123,7 +122,7 @@ static ssize_t roccat_read(struct file *file, char __user *buffer, * If report is larger than requested amount of data, rest of report * is lost! */ - len = report->len > count ? count : report->len; + len = device->report_size > count ? count : device->report_size; if (copy_to_user(buffer, report->value, len)) { retval = -EFAULT; @@ -248,26 +247,25 @@ static int roccat_release(struct inode *inode, struct file *file) * * This is called from interrupt handler. */ -int roccat_report_event(int minor, u8 const *data, int len) +int roccat_report_event(int minor, u8 const *data) { struct roccat_device *device; struct roccat_reader *reader; struct roccat_report *report; uint8_t *new_value; - new_value = kmemdup(data, len, GFP_ATOMIC); + device = devices[minor]; + + new_value = kmemdup(data, device->report_size, GFP_ATOMIC); if (!new_value) return -ENOMEM; - device = devices[minor]; - report = &device->cbuf[device->cbuf_end]; /* passing NULL is safe */ kfree(report->value); report->value = new_value; - report->len = len; device->cbuf_end = (device->cbuf_end + 1) % ROCCAT_CBUF_SIZE; list_for_each_entry(reader, &device->readers, node) { @@ -295,7 +293,7 @@ EXPORT_SYMBOL_GPL(roccat_report_event); * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on * success, a negative error code on failure. */ -int roccat_connect(struct class *klass, struct hid_device *hid) +int roccat_connect(struct class *klass, struct hid_device *hid, int report_size) { unsigned int minor; struct roccat_device *device; @@ -343,6 +341,7 @@ int roccat_connect(struct class *klass, struct hid_device *hid) device->hid = hid; device->exist = 1; device->cbuf_end = 0; + device->report_size = report_size; return minor; } @@ -357,13 +356,16 @@ void roccat_disconnect(int minor) mutex_lock(&devices_lock); device = devices[minor]; - devices[minor] = NULL; mutex_unlock(&devices_lock); device->exist = 0; /* TODO exist maybe not needed */ device_destroy(device->dev->class, MKDEV(roccat_major, 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); @@ -373,6 +375,34 @@ void roccat_disconnect(int minor) } 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 roccat_device *device; + unsigned int minor = iminor(inode); + long retval = 0; + + mutex_lock(&devices_lock); + + device = devices[minor]; + if (!device) { + retval = -ENODEV; + goto out; + } + + switch (cmd) { + case ROCCATIOCGREPSIZE: + if (put_user(device->report_size, (int __user *)arg)) + retval = -EFAULT; + break; + default: + retval = -ENOTTY; + } +out: + mutex_unlock(&devices_lock); + return retval; +} + static const struct file_operations roccat_ops = { .owner = THIS_MODULE, .read = roccat_read, @@ -380,6 +410,7 @@ static const struct file_operations roccat_ops = { .open = roccat_open, .release = roccat_release, .llseek = noop_llseek, + .unlocked_ioctl = roccat_ioctl, }; static int __init roccat_init(void) |
