aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorStefan Achatz <erazor_de@users.sourceforge.net>2011-01-30 07:38:25 -0500
committerJiri Kosina <jkosina@suse.cz>2011-02-03 10:37:28 -0500
commit8211e46004518c977f70f2661da961d5ba617399 (patch)
treeb2ae1cdc75fad9dbdece7b1dd5fc23ce0624f3c2 /drivers/hid
parent432762e28b8146d0feff61cc8063b26c517acf26 (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.c9
-rw-r--r--drivers/hid/hid-roccat-kone.c11
-rw-r--r--drivers/hid/hid-roccat-koneplus.c8
-rw-r--r--drivers/hid/hid-roccat-kovaplus.c8
-rw-r--r--drivers/hid/hid-roccat-pyra.c11
-rw-r--r--drivers/hid/hid-roccat.c48
-rw-r--r--drivers/hid/hid-roccat.h22
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
393static int arvo_raw_event(struct hid_device *hdev, 394static 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
725static int koneplus_raw_event(struct hid_device *hdev, 725static 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
655static int kovaplus_raw_event(struct hid_device *hdev, 655static 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
38struct roccat_report { 37struct roccat_report {
39 uint8_t *value; 38 uint8_t *value;
40 int len;
41}; 39};
42 40
43struct roccat_device { 41struct 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 */
251int roccat_report_event(int minor, u8 const *data, int len) 250int 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 */
298int roccat_connect(struct class *klass, struct hid_device *hid) 296int 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}
374EXPORT_SYMBOL_GPL(roccat_disconnect); 373EXPORT_SYMBOL_GPL(roccat_disconnect);
375 374
375static 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 }
398out:
399 mutex_unlock(&devices_lock);
400 return retval;
401}
402
376static const struct file_operations roccat_ops = { 403static 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
385static int __init roccat_init(void) 413static 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
18int roccat_connect(struct class *klass, struct hid_device *hid);
19void roccat_disconnect(int minor);
20int roccat_report_event(int minor, u8 const *data, int len);
21
22#endif