diff options
author | Stefan Achatz <erazor_de@users.sourceforge.net> | 2011-01-30 07:38:25 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-02-03 10:37:28 -0500 |
commit | 8211e46004518c977f70f2661da961d5ba617399 (patch) | |
tree | b2ae1cdc75fad9dbdece7b1dd5fc23ce0624f3c2 /drivers/hid | |
parent | 432762e28b8146d0feff61cc8063b26c517acf26 (diff) |
HID: roccat: Add ioctl command to retreive report size from chardev
Roccat chardev was reworked to support only a defined report size per
device and this can be retreived by an ioctl now to enable future changes
in report definitions.
Header was moved/renamed from drivers/hid to include/linux for accessibility.
Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-roccat-arvo.c | 9 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-kone.c | 11 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-koneplus.c | 8 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-kovaplus.c | 8 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-pyra.c | 11 | ||||
-rw-r--r-- | drivers/hid/hid-roccat.c | 48 | ||||
-rw-r--r-- | drivers/hid/hid-roccat.h | 22 |
7 files changed, 61 insertions, 56 deletions
diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c index d72ee4186d11..7b9a992611bc 100644 --- a/drivers/hid/hid-roccat-arvo.c +++ b/drivers/hid/hid-roccat-arvo.c | |||
@@ -21,8 +21,8 @@ | |||
21 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/roccat.h> | ||
24 | #include "hid-ids.h" | 25 | #include "hid-ids.h" |
25 | #include "hid-roccat.h" | ||
26 | #include "hid-roccat-common.h" | 26 | #include "hid-roccat-common.h" |
27 | #include "hid-roccat-arvo.h" | 27 | #include "hid-roccat-arvo.h" |
28 | 28 | ||
@@ -303,7 +303,8 @@ static int arvo_init_specials(struct hid_device *hdev) | |||
303 | goto exit_free; | 303 | goto exit_free; |
304 | } | 304 | } |
305 | 305 | ||
306 | retval = roccat_connect(arvo_class, hdev); | 306 | retval = roccat_connect(arvo_class, hdev, |
307 | sizeof(struct arvo_roccat_report)); | ||
307 | if (retval < 0) { | 308 | if (retval < 0) { |
308 | hid_err(hdev, "couldn't init char dev\n"); | 309 | hid_err(hdev, "couldn't init char dev\n"); |
309 | } else { | 310 | } else { |
@@ -386,8 +387,8 @@ static void arvo_report_to_chrdev(struct arvo_device const *arvo, | |||
386 | else | 387 | else |
387 | roccat_report.action = ARVO_ROCCAT_REPORT_ACTION_RELEASE; | 388 | roccat_report.action = ARVO_ROCCAT_REPORT_ACTION_RELEASE; |
388 | 389 | ||
389 | roccat_report_event(arvo->chrdev_minor, (uint8_t const *)&roccat_report, | 390 | roccat_report_event(arvo->chrdev_minor, |
390 | sizeof(struct arvo_roccat_report)); | 391 | (uint8_t const *)&roccat_report); |
391 | } | 392 | } |
392 | 393 | ||
393 | static int arvo_raw_event(struct hid_device *hdev, | 394 | static int arvo_raw_event(struct hid_device *hdev, |
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 551665359eba..5cdb282dad11 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c | |||
@@ -30,8 +30,8 @@ | |||
30 | #include <linux/hid.h> | 30 | #include <linux/hid.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/roccat.h> | ||
33 | #include "hid-ids.h" | 34 | #include "hid-ids.h" |
34 | #include "hid-roccat.h" | ||
35 | #include "hid-roccat-common.h" | 35 | #include "hid-roccat-common.h" |
36 | #include "hid-roccat-kone.h" | 36 | #include "hid-roccat-kone.h" |
37 | 37 | ||
@@ -660,7 +660,8 @@ static int kone_init_specials(struct hid_device *hdev) | |||
660 | goto exit_free; | 660 | goto exit_free; |
661 | } | 661 | } |
662 | 662 | ||
663 | retval = roccat_connect(kone_class, hdev); | 663 | retval = roccat_connect(kone_class, hdev, |
664 | sizeof(struct kone_roccat_report)); | ||
664 | if (retval < 0) { | 665 | if (retval < 0) { |
665 | hid_err(hdev, "couldn't init char dev\n"); | 666 | hid_err(hdev, "couldn't init char dev\n"); |
666 | /* be tolerant about not getting chrdev */ | 667 | /* be tolerant about not getting chrdev */ |
@@ -760,8 +761,7 @@ static void kone_report_to_chrdev(struct kone_device const *kone, | |||
760 | roccat_report.value = event->value; | 761 | roccat_report.value = event->value; |
761 | roccat_report.key = 0; | 762 | roccat_report.key = 0; |
762 | roccat_report_event(kone->chrdev_minor, | 763 | roccat_report_event(kone->chrdev_minor, |
763 | (uint8_t *)&roccat_report, | 764 | (uint8_t *)&roccat_report); |
764 | sizeof(struct kone_roccat_report)); | ||
765 | break; | 765 | break; |
766 | case kone_mouse_event_call_overlong_macro: | 766 | case kone_mouse_event_call_overlong_macro: |
767 | if (event->value == kone_keystroke_action_press) { | 767 | if (event->value == kone_keystroke_action_press) { |
@@ -769,8 +769,7 @@ static void kone_report_to_chrdev(struct kone_device const *kone, | |||
769 | roccat_report.value = kone->actual_profile; | 769 | roccat_report.value = kone->actual_profile; |
770 | roccat_report.key = event->macro_key; | 770 | roccat_report.key = event->macro_key; |
771 | roccat_report_event(kone->chrdev_minor, | 771 | roccat_report_event(kone->chrdev_minor, |
772 | (uint8_t *)&roccat_report, | 772 | (uint8_t *)&roccat_report); |
773 | sizeof(struct kone_roccat_report)); | ||
774 | } | 773 | } |
775 | break; | 774 | break; |
776 | } | 775 | } |
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index df85ed8a3397..7367e4edfa6c 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c | |||
@@ -21,8 +21,8 @@ | |||
21 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/roccat.h> | ||
24 | #include "hid-ids.h" | 25 | #include "hid-ids.h" |
25 | #include "hid-roccat.h" | ||
26 | #include "hid-roccat-common.h" | 26 | #include "hid-roccat-common.h" |
27 | #include "hid-roccat-koneplus.h" | 27 | #include "hid-roccat-koneplus.h" |
28 | 28 | ||
@@ -612,7 +612,8 @@ static int koneplus_init_specials(struct hid_device *hdev) | |||
612 | goto exit_free; | 612 | goto exit_free; |
613 | } | 613 | } |
614 | 614 | ||
615 | retval = roccat_connect(koneplus_class, hdev); | 615 | retval = roccat_connect(koneplus_class, hdev, |
616 | sizeof(struct koneplus_roccat_report)); | ||
616 | if (retval < 0) { | 617 | if (retval < 0) { |
617 | hid_err(hdev, "couldn't init char dev\n"); | 618 | hid_err(hdev, "couldn't init char dev\n"); |
618 | } else { | 619 | } else { |
@@ -718,8 +719,7 @@ static void koneplus_report_to_chrdev(struct koneplus_device const *koneplus, | |||
718 | roccat_report.data2 = button_report->data2; | 719 | roccat_report.data2 = button_report->data2; |
719 | roccat_report.profile = koneplus->actual_profile + 1; | 720 | roccat_report.profile = koneplus->actual_profile + 1; |
720 | roccat_report_event(koneplus->chrdev_minor, | 721 | roccat_report_event(koneplus->chrdev_minor, |
721 | (uint8_t const *)&roccat_report, | 722 | (uint8_t const *)&roccat_report); |
722 | sizeof(struct koneplus_roccat_report)); | ||
723 | } | 723 | } |
724 | 724 | ||
725 | static int koneplus_raw_event(struct hid_device *hdev, | 725 | static int koneplus_raw_event(struct hid_device *hdev, |
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index 1f547a2b39de..7664e2ce2886 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c | |||
@@ -20,8 +20,8 @@ | |||
20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/roccat.h> | ||
23 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
24 | #include "hid-roccat.h" | ||
25 | #include "hid-roccat-common.h" | 25 | #include "hid-roccat-common.h" |
26 | #include "hid-roccat-kovaplus.h" | 26 | #include "hid-roccat-kovaplus.h" |
27 | 27 | ||
@@ -524,7 +524,8 @@ static int kovaplus_init_specials(struct hid_device *hdev) | |||
524 | goto exit_free; | 524 | goto exit_free; |
525 | } | 525 | } |
526 | 526 | ||
527 | retval = roccat_connect(kovaplus_class, hdev); | 527 | retval = roccat_connect(kovaplus_class, hdev, |
528 | sizeof(struct kovaplus_roccat_report)); | ||
528 | if (retval < 0) { | 529 | if (retval < 0) { |
529 | hid_err(hdev, "couldn't init char dev\n"); | 530 | hid_err(hdev, "couldn't init char dev\n"); |
530 | } else { | 531 | } else { |
@@ -648,8 +649,7 @@ static void kovaplus_report_to_chrdev(struct kovaplus_device const *kovaplus, | |||
648 | roccat_report.data2 = button_report->data2; | 649 | roccat_report.data2 = button_report->data2; |
649 | 650 | ||
650 | roccat_report_event(kovaplus->chrdev_minor, | 651 | roccat_report_event(kovaplus->chrdev_minor, |
651 | (uint8_t const *)&roccat_report, | 652 | (uint8_t const *)&roccat_report); |
652 | sizeof(struct kovaplus_roccat_report)); | ||
653 | } | 653 | } |
654 | 654 | ||
655 | static int kovaplus_raw_event(struct hid_device *hdev, | 655 | static int kovaplus_raw_event(struct hid_device *hdev, |
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index abe77d3e6d8b..be4daa96f7c2 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c | |||
@@ -22,8 +22,8 @@ | |||
22 | #include <linux/hid.h> | 22 | #include <linux/hid.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/roccat.h> | ||
25 | #include "hid-ids.h" | 26 | #include "hid-ids.h" |
26 | #include "hid-roccat.h" | ||
27 | #include "hid-roccat-common.h" | 27 | #include "hid-roccat-common.h" |
28 | #include "hid-roccat-pyra.h" | 28 | #include "hid-roccat-pyra.h" |
29 | 29 | ||
@@ -506,7 +506,8 @@ static int pyra_init_specials(struct hid_device *hdev) | |||
506 | goto exit_free; | 506 | goto exit_free; |
507 | } | 507 | } |
508 | 508 | ||
509 | retval = roccat_connect(pyra_class, hdev); | 509 | retval = roccat_connect(pyra_class, hdev, |
510 | sizeof(struct pyra_roccat_report)); | ||
510 | if (retval < 0) { | 511 | if (retval < 0) { |
511 | hid_err(hdev, "couldn't init char dev\n"); | 512 | hid_err(hdev, "couldn't init char dev\n"); |
512 | } else { | 513 | } else { |
@@ -610,8 +611,7 @@ static void pyra_report_to_chrdev(struct pyra_device const *pyra, | |||
610 | roccat_report.value = button_event->data1; | 611 | roccat_report.value = button_event->data1; |
611 | roccat_report.key = 0; | 612 | roccat_report.key = 0; |
612 | roccat_report_event(pyra->chrdev_minor, | 613 | roccat_report_event(pyra->chrdev_minor, |
613 | (uint8_t const *)&roccat_report, | 614 | (uint8_t const *)&roccat_report); |
614 | sizeof(struct pyra_roccat_report)); | ||
615 | break; | 615 | break; |
616 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO: | 616 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO: |
617 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT: | 617 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT: |
@@ -625,8 +625,7 @@ static void pyra_report_to_chrdev(struct pyra_device const *pyra, | |||
625 | */ | 625 | */ |
626 | roccat_report.value = pyra->actual_profile + 1; | 626 | roccat_report.value = pyra->actual_profile + 1; |
627 | roccat_report_event(pyra->chrdev_minor, | 627 | roccat_report_event(pyra->chrdev_minor, |
628 | (uint8_t const *)&roccat_report, | 628 | (uint8_t const *)&roccat_report); |
629 | sizeof(struct pyra_roccat_report)); | ||
630 | } | 629 | } |
631 | break; | 630 | break; |
632 | } | 631 | } |
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index a14c579ea781..0fa23dead5e1 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c | |||
@@ -26,8 +26,7 @@ | |||
26 | #include <linux/cdev.h> | 26 | #include <linux/cdev.h> |
27 | #include <linux/poll.h> | 27 | #include <linux/poll.h> |
28 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
29 | 29 | #include <linux/roccat.h> | |
30 | #include "hid-roccat.h" | ||
31 | 30 | ||
32 | #define ROCCAT_FIRST_MINOR 0 | 31 | #define ROCCAT_FIRST_MINOR 0 |
33 | #define ROCCAT_MAX_DEVICES 8 | 32 | #define ROCCAT_MAX_DEVICES 8 |
@@ -37,11 +36,11 @@ | |||
37 | 36 | ||
38 | struct roccat_report { | 37 | struct roccat_report { |
39 | uint8_t *value; | 38 | uint8_t *value; |
40 | int len; | ||
41 | }; | 39 | }; |
42 | 40 | ||
43 | struct roccat_device { | 41 | struct roccat_device { |
44 | unsigned int minor; | 42 | unsigned int minor; |
43 | int report_size; | ||
45 | int open; | 44 | int open; |
46 | int exist; | 45 | int exist; |
47 | wait_queue_head_t wait; | 46 | wait_queue_head_t wait; |
@@ -123,7 +122,7 @@ static ssize_t roccat_read(struct file *file, char __user *buffer, | |||
123 | * If report is larger than requested amount of data, rest of report | 122 | * If report is larger than requested amount of data, rest of report |
124 | * is lost! | 123 | * is lost! |
125 | */ | 124 | */ |
126 | len = report->len > count ? count : report->len; | 125 | len = device->report_size > count ? count : device->report_size; |
127 | 126 | ||
128 | if (copy_to_user(buffer, report->value, len)) { | 127 | if (copy_to_user(buffer, report->value, len)) { |
129 | retval = -EFAULT; | 128 | retval = -EFAULT; |
@@ -248,26 +247,25 @@ static int roccat_release(struct inode *inode, struct file *file) | |||
248 | * | 247 | * |
249 | * This is called from interrupt handler. | 248 | * This is called from interrupt handler. |
250 | */ | 249 | */ |
251 | int roccat_report_event(int minor, u8 const *data, int len) | 250 | int roccat_report_event(int minor, u8 const *data) |
252 | { | 251 | { |
253 | struct roccat_device *device; | 252 | struct roccat_device *device; |
254 | struct roccat_reader *reader; | 253 | struct roccat_reader *reader; |
255 | struct roccat_report *report; | 254 | struct roccat_report *report; |
256 | uint8_t *new_value; | 255 | uint8_t *new_value; |
257 | 256 | ||
258 | new_value = kmemdup(data, len, GFP_ATOMIC); | 257 | device = devices[minor]; |
258 | |||
259 | new_value = kmemdup(data, device->report_size, GFP_ATOMIC); | ||
259 | if (!new_value) | 260 | if (!new_value) |
260 | return -ENOMEM; | 261 | return -ENOMEM; |
261 | 262 | ||
262 | device = devices[minor]; | ||
263 | |||
264 | report = &device->cbuf[device->cbuf_end]; | 263 | report = &device->cbuf[device->cbuf_end]; |
265 | 264 | ||
266 | /* passing NULL is safe */ | 265 | /* passing NULL is safe */ |
267 | kfree(report->value); | 266 | kfree(report->value); |
268 | 267 | ||
269 | report->value = new_value; | 268 | report->value = new_value; |
270 | report->len = len; | ||
271 | device->cbuf_end = (device->cbuf_end + 1) % ROCCAT_CBUF_SIZE; | 269 | device->cbuf_end = (device->cbuf_end + 1) % ROCCAT_CBUF_SIZE; |
272 | 270 | ||
273 | list_for_each_entry(reader, &device->readers, node) { | 271 | list_for_each_entry(reader, &device->readers, node) { |
@@ -295,7 +293,7 @@ EXPORT_SYMBOL_GPL(roccat_report_event); | |||
295 | * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on | 293 | * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on |
296 | * success, a negative error code on failure. | 294 | * success, a negative error code on failure. |
297 | */ | 295 | */ |
298 | int roccat_connect(struct class *klass, struct hid_device *hid) | 296 | int roccat_connect(struct class *klass, struct hid_device *hid, int report_size) |
299 | { | 297 | { |
300 | unsigned int minor; | 298 | unsigned int minor; |
301 | struct roccat_device *device; | 299 | struct roccat_device *device; |
@@ -343,6 +341,7 @@ int roccat_connect(struct class *klass, struct hid_device *hid) | |||
343 | device->hid = hid; | 341 | device->hid = hid; |
344 | device->exist = 1; | 342 | device->exist = 1; |
345 | device->cbuf_end = 0; | 343 | device->cbuf_end = 0; |
344 | device->report_size = report_size; | ||
346 | 345 | ||
347 | return minor; | 346 | return minor; |
348 | } | 347 | } |
@@ -373,6 +372,34 @@ void roccat_disconnect(int minor) | |||
373 | } | 372 | } |
374 | EXPORT_SYMBOL_GPL(roccat_disconnect); | 373 | EXPORT_SYMBOL_GPL(roccat_disconnect); |
375 | 374 | ||
375 | static long roccat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
376 | { | ||
377 | struct inode *inode = file->f_path.dentry->d_inode; | ||
378 | struct roccat_device *device; | ||
379 | unsigned int minor = iminor(inode); | ||
380 | long retval = 0; | ||
381 | |||
382 | mutex_lock(&devices_lock); | ||
383 | |||
384 | device = devices[minor]; | ||
385 | if (!device) { | ||
386 | retval = -ENODEV; | ||
387 | goto out; | ||
388 | } | ||
389 | |||
390 | switch (cmd) { | ||
391 | case ROCCATIOCGREPSIZE: | ||
392 | if (put_user(device->report_size, (int __user *)arg)) | ||
393 | retval = -EFAULT; | ||
394 | break; | ||
395 | default: | ||
396 | retval = -ENOTTY; | ||
397 | } | ||
398 | out: | ||
399 | mutex_unlock(&devices_lock); | ||
400 | return retval; | ||
401 | } | ||
402 | |||
376 | static const struct file_operations roccat_ops = { | 403 | static const struct file_operations roccat_ops = { |
377 | .owner = THIS_MODULE, | 404 | .owner = THIS_MODULE, |
378 | .read = roccat_read, | 405 | .read = roccat_read, |
@@ -380,6 +407,7 @@ static const struct file_operations roccat_ops = { | |||
380 | .open = roccat_open, | 407 | .open = roccat_open, |
381 | .release = roccat_release, | 408 | .release = roccat_release, |
382 | .llseek = noop_llseek, | 409 | .llseek = noop_llseek, |
410 | .unlocked_ioctl = roccat_ioctl, | ||
383 | }; | 411 | }; |
384 | 412 | ||
385 | static int __init roccat_init(void) | 413 | static int __init roccat_init(void) |
diff --git a/drivers/hid/hid-roccat.h b/drivers/hid/hid-roccat.h deleted file mode 100644 index c7393372df7c..000000000000 --- a/drivers/hid/hid-roccat.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #ifndef __HID_ROCCAT_H | ||
2 | #define __HID_ROCCAT_H | ||
3 | |||
4 | /* | ||
5 | * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the Free | ||
11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
12 | * any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/hid.h> | ||
16 | #include <linux/types.h> | ||
17 | |||
18 | int roccat_connect(struct class *klass, struct hid_device *hid); | ||
19 | void roccat_disconnect(int minor); | ||
20 | int roccat_report_event(int minor, u8 const *data, int len); | ||
21 | |||
22 | #endif | ||