2 * HID raw devices, giving access to raw HID events.
4 * In comparison to hiddev, this device does not process the
5 * hid events at all (no parsing, no lookups). This lets applications
6 * to work on raw hid events as they want to, and avoids a need to
7 * use a transport-specific userspace libhid/libusb libraries.
9 * Copyright (c) 2007 Jiri Kosina
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms and conditions of the GNU General Public License,
15 * version 2, as published by the Free Software Foundation.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25 #include <linux/module.h>
26 #include <linux/errno.h>
27 #include <linux/kernel.h>
28 #include <linux/init.h>
29 #include <linux/cdev.h>
30 #include <linux/poll.h>
31 #include <linux/device.h>
32 #include <linux/major.h>
33 #include <linux/slab.h>
34 #include <linux/hid.h>
35 #include <linux/mutex.h>
36 #include <linux/sched.h>
38 #include <linux/hidraw.h>
40 static int hidraw_major
;
41 static struct cdev hidraw_cdev
;
42 static struct class *hidraw_class
;
43 static struct hidraw
*hidraw_table
[HIDRAW_MAX_DEVICES
];
44 static DEFINE_MUTEX(minors_lock
);
46 static ssize_t
hidraw_read(struct file
*file
, char __user
*buffer
, size_t count
, loff_t
*ppos
)
48 struct hidraw_list
*list
= file
->private_data
;
50 DECLARE_WAITQUEUE(wait
, current
);
52 mutex_lock(&list
->read_mutex
);
55 if (list
->head
== list
->tail
) {
56 add_wait_queue(&list
->hidraw
->wait
, &wait
);
57 set_current_state(TASK_INTERRUPTIBLE
);
59 while (list
->head
== list
->tail
) {
60 if (file
->f_flags
& O_NONBLOCK
) {
64 if (signal_pending(current
)) {
68 if (!list
->hidraw
->exist
) {
73 /* allow O_NONBLOCK to work well from other threads */
74 mutex_unlock(&list
->read_mutex
);
76 mutex_lock(&list
->read_mutex
);
77 set_current_state(TASK_INTERRUPTIBLE
);
80 set_current_state(TASK_RUNNING
);
81 remove_wait_queue(&list
->hidraw
->wait
, &wait
);
87 len
= list
->buffer
[list
->tail
].len
> count
?
88 count
: list
->buffer
[list
->tail
].len
;
90 if (copy_to_user(buffer
, list
->buffer
[list
->tail
].value
, len
)) {
96 kfree(list
->buffer
[list
->tail
].value
);
97 list
->tail
= (list
->tail
+ 1) & (HIDRAW_BUFFER_SIZE
- 1);
100 mutex_unlock(&list
->read_mutex
);
104 /* the first byte is expected to be a report number */
105 /* This function is to be called with the minors_lock mutex held */
106 static ssize_t
hidraw_send_report(struct file
*file
, const char __user
*buffer
, size_t count
, unsigned char report_type
)
108 unsigned int minor
= iminor(file
->f_path
.dentry
->d_inode
);
109 struct hid_device
*dev
;
113 if (!hidraw_table
[minor
]) {
118 dev
= hidraw_table
[minor
]->hid
;
120 if (!dev
->hid_output_raw_report
) {
125 if (count
> HID_MAX_BUFFER_SIZE
) {
126 hid_warn(dev
, "pid %d passed too large report\n",
127 task_pid_nr(current
));
133 hid_warn(dev
, "pid %d passed too short report\n",
134 task_pid_nr(current
));
139 buf
= kmalloc(count
* sizeof(__u8
), GFP_KERNEL
);
145 if (copy_from_user(buf
, buffer
, count
)) {
150 ret
= dev
->hid_output_raw_report(dev
, buf
, count
, report_type
);
157 /* the first byte is expected to be a report number */
158 static ssize_t
hidraw_write(struct file
*file
, const char __user
*buffer
, size_t count
, loff_t
*ppos
)
161 mutex_lock(&minors_lock
);
162 ret
= hidraw_send_report(file
, buffer
, count
, HID_OUTPUT_REPORT
);
163 mutex_unlock(&minors_lock
);
168 /* This function performs a Get_Report transfer over the control endpoint
169 per section 7.2.1 of the HID specification, version 1.1. The first byte
170 of buffer is the report number to request, or 0x0 if the defice does not
171 use numbered reports. The report_type parameter can be HID_FEATURE_REPORT
172 or HID_INPUT_REPORT. This function is to be called with the minors_lock
174 static ssize_t
hidraw_get_report(struct file
*file
, char __user
*buffer
, size_t count
, unsigned char report_type
)
176 unsigned int minor
= iminor(file
->f_path
.dentry
->d_inode
);
177 struct hid_device
*dev
;
180 unsigned char report_number
;
182 dev
= hidraw_table
[minor
]->hid
;
184 if (!dev
->hid_get_raw_report
) {
189 if (count
> HID_MAX_BUFFER_SIZE
) {
190 printk(KERN_WARNING
"hidraw: pid %d passed too large report\n",
191 task_pid_nr(current
));
197 printk(KERN_WARNING
"hidraw: pid %d passed too short report\n",
198 task_pid_nr(current
));
203 buf
= kmalloc(count
* sizeof(__u8
), GFP_KERNEL
);
209 /* Read the first byte from the user. This is the report number,
210 which is passed to dev->hid_get_raw_report(). */
211 if (copy_from_user(&report_number
, buffer
, 1)) {
216 ret
= dev
->hid_get_raw_report(dev
, report_number
, buf
, count
, report_type
);
221 len
= (ret
< count
) ? ret
: count
;
223 if (copy_to_user(buffer
, buf
, len
)) {
236 static unsigned int hidraw_poll(struct file
*file
, poll_table
*wait
)
238 struct hidraw_list
*list
= file
->private_data
;
240 poll_wait(file
, &list
->hidraw
->wait
, wait
);
241 if (list
->head
!= list
->tail
)
242 return POLLIN
| POLLRDNORM
;
243 if (!list
->hidraw
->exist
)
244 return POLLERR
| POLLHUP
;
248 static int hidraw_open(struct inode
*inode
, struct file
*file
)
250 unsigned int minor
= iminor(inode
);
252 struct hidraw_list
*list
;
255 if (!(list
= kzalloc(sizeof(struct hidraw_list
), GFP_KERNEL
))) {
260 mutex_lock(&minors_lock
);
261 if (!hidraw_table
[minor
]) {
267 list
->hidraw
= hidraw_table
[minor
];
268 mutex_init(&list
->read_mutex
);
269 list_add_tail(&list
->node
, &hidraw_table
[minor
]->list
);
270 file
->private_data
= list
;
272 dev
= hidraw_table
[minor
];
274 err
= hid_hw_power(dev
->hid
, PM_HINT_FULLON
);
278 err
= hid_hw_open(dev
->hid
);
280 hid_hw_power(dev
->hid
, PM_HINT_NORMAL
);
286 mutex_unlock(&minors_lock
);
292 static int hidraw_release(struct inode
* inode
, struct file
* file
)
294 unsigned int minor
= iminor(inode
);
296 struct hidraw_list
*list
= file
->private_data
;
299 mutex_lock(&minors_lock
);
300 if (!hidraw_table
[minor
]) {
305 list_del(&list
->node
);
306 dev
= hidraw_table
[minor
];
308 if (list
->hidraw
->exist
) {
309 hid_hw_power(dev
->hid
, PM_HINT_NORMAL
);
310 hid_hw_close(dev
->hid
);
318 mutex_unlock(&minors_lock
);
323 static long hidraw_ioctl(struct file
*file
, unsigned int cmd
,
326 struct inode
*inode
= file
->f_path
.dentry
->d_inode
;
327 unsigned int minor
= iminor(inode
);
330 void __user
*user_arg
= (void __user
*) arg
;
332 mutex_lock(&minors_lock
);
333 dev
= hidraw_table
[minor
];
340 case HIDIOCGRDESCSIZE
:
341 if (put_user(dev
->hid
->rsize
, (int __user
*)arg
))
349 if (get_user(len
, (int __user
*)arg
))
351 else if (len
> HID_MAX_DESCRIPTOR_SIZE
- 1)
353 else if (copy_to_user(user_arg
+ offsetof(
354 struct hidraw_report_descriptor
,
357 min(dev
->hid
->rsize
, len
)))
363 struct hidraw_devinfo dinfo
;
365 dinfo
.bustype
= dev
->hid
->bus
;
366 dinfo
.vendor
= dev
->hid
->vendor
;
367 dinfo
.product
= dev
->hid
->product
;
368 if (copy_to_user(user_arg
, &dinfo
, sizeof(dinfo
)))
374 struct hid_device
*hid
= dev
->hid
;
375 if (_IOC_TYPE(cmd
) != 'H') {
380 if (_IOC_NR(cmd
) == _IOC_NR(HIDIOCSFEATURE(0))) {
381 int len
= _IOC_SIZE(cmd
);
382 ret
= hidraw_send_report(file
, user_arg
, len
, HID_FEATURE_REPORT
);
385 if (_IOC_NR(cmd
) == _IOC_NR(HIDIOCGFEATURE(0))) {
386 int len
= _IOC_SIZE(cmd
);
387 ret
= hidraw_get_report(file
, user_arg
, len
, HID_FEATURE_REPORT
);
391 /* Begin Read-only ioctls. */
392 if (_IOC_DIR(cmd
) != _IOC_READ
) {
397 if (_IOC_NR(cmd
) == _IOC_NR(HIDIOCGRAWNAME(0))) {
403 len
= strlen(hid
->name
) + 1;
404 if (len
> _IOC_SIZE(cmd
))
405 len
= _IOC_SIZE(cmd
);
406 ret
= copy_to_user(user_arg
, hid
->name
, len
) ?
411 if (_IOC_NR(cmd
) == _IOC_NR(HIDIOCGRAWPHYS(0))) {
417 len
= strlen(hid
->phys
) + 1;
418 if (len
> _IOC_SIZE(cmd
))
419 len
= _IOC_SIZE(cmd
);
420 ret
= copy_to_user(user_arg
, hid
->phys
, len
) ?
429 mutex_unlock(&minors_lock
);
433 static const struct file_operations hidraw_ops
= {
434 .owner
= THIS_MODULE
,
436 .write
= hidraw_write
,
439 .release
= hidraw_release
,
440 .unlocked_ioctl
= hidraw_ioctl
,
442 .compat_ioctl
= hidraw_ioctl
,
444 .llseek
= noop_llseek
,
447 void hidraw_report_event(struct hid_device
*hid
, u8
*data
, int len
)
449 struct hidraw
*dev
= hid
->hidraw
;
450 struct hidraw_list
*list
;
452 list_for_each_entry(list
, &dev
->list
, node
) {
453 list
->buffer
[list
->head
].value
= kmemdup(data
, len
, GFP_ATOMIC
);
454 list
->buffer
[list
->head
].len
= len
;
455 list
->head
= (list
->head
+ 1) & (HIDRAW_BUFFER_SIZE
- 1);
456 kill_fasync(&list
->fasync
, SIGIO
, POLL_IN
);
459 wake_up_interruptible(&dev
->wait
);
461 EXPORT_SYMBOL_GPL(hidraw_report_event
);
463 int hidraw_connect(struct hid_device
*hid
)
468 /* we accept any HID device, no matter the applications */
470 dev
= kzalloc(sizeof(struct hidraw
), GFP_KERNEL
);
476 mutex_lock(&minors_lock
);
478 for (minor
= 0; minor
< HIDRAW_MAX_DEVICES
; minor
++) {
479 if (hidraw_table
[minor
])
481 hidraw_table
[minor
] = dev
;
487 mutex_unlock(&minors_lock
);
492 dev
->dev
= device_create(hidraw_class
, &hid
->dev
, MKDEV(hidraw_major
, minor
),
493 NULL
, "%s%d", "hidraw", minor
);
495 if (IS_ERR(dev
->dev
)) {
496 hidraw_table
[minor
] = NULL
;
497 mutex_unlock(&minors_lock
);
498 result
= PTR_ERR(dev
->dev
);
503 mutex_unlock(&minors_lock
);
504 init_waitqueue_head(&dev
->wait
);
505 INIT_LIST_HEAD(&dev
->list
);
517 EXPORT_SYMBOL_GPL(hidraw_connect
);
519 void hidraw_disconnect(struct hid_device
*hid
)
521 struct hidraw
*hidraw
= hid
->hidraw
;
525 device_destroy(hidraw_class
, MKDEV(hidraw_major
, hidraw
->minor
));
527 mutex_lock(&minors_lock
);
528 hidraw_table
[hidraw
->minor
] = NULL
;
529 mutex_unlock(&minors_lock
);
533 wake_up_interruptible(&hidraw
->wait
);
538 EXPORT_SYMBOL_GPL(hidraw_disconnect
);
540 int __init
hidraw_init(void)
545 result
= alloc_chrdev_region(&dev_id
, HIDRAW_FIRST_MINOR
,
546 HIDRAW_MAX_DEVICES
, "hidraw");
548 hidraw_major
= MAJOR(dev_id
);
551 pr_warn("can't get major number\n");
556 hidraw_class
= class_create(THIS_MODULE
, "hidraw");
557 if (IS_ERR(hidraw_class
)) {
558 result
= PTR_ERR(hidraw_class
);
559 unregister_chrdev(hidraw_major
, "hidraw");
563 cdev_init(&hidraw_cdev
, &hidraw_ops
);
564 cdev_add(&hidraw_cdev
, dev_id
, HIDRAW_MAX_DEVICES
);
569 void hidraw_exit(void)
571 dev_t dev_id
= MKDEV(hidraw_major
, 0);
573 cdev_del(&hidraw_cdev
);
574 class_destroy(hidraw_class
);
575 unregister_chrdev_region(dev_id
, HIDRAW_MAX_DEVICES
);