xref: /linux/drivers/hid/hidraw.c (revision 9d9659b6c0ebf7dde65ebada4c67980818245913)
1 /*
2  * HID raw devices, giving access to raw HID events.
3  *
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.
8  *
9  *  Copyright (c) 2007 Jiri Kosina
10  */
11 
12 /*
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.
16  *
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.
20  */
21 
22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 
24 #include <linux/fs.h>
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>
37 
38 #include <linux/hidraw.h>
39 
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);
45 
46 static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
47 {
48 	struct hidraw_list *list = file->private_data;
49 	int ret = 0, len;
50 	DECLARE_WAITQUEUE(wait, current);
51 
52 	mutex_lock(&list->read_mutex);
53 
54 	while (ret == 0) {
55 		if (list->head == list->tail) {
56 			add_wait_queue(&list->hidraw->wait, &wait);
57 			set_current_state(TASK_INTERRUPTIBLE);
58 
59 			while (list->head == list->tail) {
60 				if (file->f_flags & O_NONBLOCK) {
61 					ret = -EAGAIN;
62 					break;
63 				}
64 				if (signal_pending(current)) {
65 					ret = -ERESTARTSYS;
66 					break;
67 				}
68 				if (!list->hidraw->exist) {
69 					ret = -EIO;
70 					break;
71 				}
72 
73 				/* allow O_NONBLOCK to work well from other threads */
74 				mutex_unlock(&list->read_mutex);
75 				schedule();
76 				mutex_lock(&list->read_mutex);
77 				set_current_state(TASK_INTERRUPTIBLE);
78 			}
79 
80 			set_current_state(TASK_RUNNING);
81 			remove_wait_queue(&list->hidraw->wait, &wait);
82 		}
83 
84 		if (ret)
85 			goto out;
86 
87 		len = list->buffer[list->tail].len > count ?
88 			count : list->buffer[list->tail].len;
89 
90 		if (copy_to_user(buffer, list->buffer[list->tail].value, len)) {
91 			ret = -EFAULT;
92 			goto out;
93 		}
94 		ret = len;
95 
96 		kfree(list->buffer[list->tail].value);
97 		list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1);
98 	}
99 out:
100 	mutex_unlock(&list->read_mutex);
101 	return ret;
102 }
103 
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)
107 {
108 	unsigned int minor = iminor(file->f_path.dentry->d_inode);
109 	struct hid_device *dev;
110 	__u8 *buf;
111 	int ret = 0;
112 
113 	if (!hidraw_table[minor]) {
114 		ret = -ENODEV;
115 		goto out;
116 	}
117 
118 	dev = hidraw_table[minor]->hid;
119 
120 	if (!dev->hid_output_raw_report) {
121 		ret = -ENODEV;
122 		goto out;
123 	}
124 
125 	if (count > HID_MAX_BUFFER_SIZE) {
126 		hid_warn(dev, "pid %d passed too large report\n",
127 			 task_pid_nr(current));
128 		ret = -EINVAL;
129 		goto out;
130 	}
131 
132 	if (count < 2) {
133 		hid_warn(dev, "pid %d passed too short report\n",
134 			 task_pid_nr(current));
135 		ret = -EINVAL;
136 		goto out;
137 	}
138 
139 	buf = kmalloc(count * sizeof(__u8), GFP_KERNEL);
140 	if (!buf) {
141 		ret = -ENOMEM;
142 		goto out;
143 	}
144 
145 	if (copy_from_user(buf, buffer, count)) {
146 		ret = -EFAULT;
147 		goto out_free;
148 	}
149 
150 	ret = dev->hid_output_raw_report(dev, buf, count, report_type);
151 out_free:
152 	kfree(buf);
153 out:
154 	return ret;
155 }
156 
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)
159 {
160 	ssize_t ret;
161 	mutex_lock(&minors_lock);
162 	ret = hidraw_send_report(file, buffer, count, HID_OUTPUT_REPORT);
163 	mutex_unlock(&minors_lock);
164 	return ret;
165 }
166 
167 
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
173    mutex held.  */
174 static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type)
175 {
176 	unsigned int minor = iminor(file->f_path.dentry->d_inode);
177 	struct hid_device *dev;
178 	__u8 *buf;
179 	int ret = 0, len;
180 	unsigned char report_number;
181 
182 	dev = hidraw_table[minor]->hid;
183 
184 	if (!dev->hid_get_raw_report) {
185 		ret = -ENODEV;
186 		goto out;
187 	}
188 
189 	if (count > HID_MAX_BUFFER_SIZE) {
190 		printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
191 				task_pid_nr(current));
192 		ret = -EINVAL;
193 		goto out;
194 	}
195 
196 	if (count < 2) {
197 		printk(KERN_WARNING "hidraw: pid %d passed too short report\n",
198 				task_pid_nr(current));
199 		ret = -EINVAL;
200 		goto out;
201 	}
202 
203 	buf = kmalloc(count * sizeof(__u8), GFP_KERNEL);
204 	if (!buf) {
205 		ret = -ENOMEM;
206 		goto out;
207 	}
208 
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)) {
212 		ret = -EFAULT;
213 		goto out_free;
214 	}
215 
216 	ret = dev->hid_get_raw_report(dev, report_number, buf, count, report_type);
217 
218 	if (ret < 0)
219 		goto out_free;
220 
221 	len = (ret < count) ? ret : count;
222 
223 	if (copy_to_user(buffer, buf, len)) {
224 		ret = -EFAULT;
225 		goto out_free;
226 	}
227 
228 	ret = len;
229 
230 out_free:
231 	kfree(buf);
232 out:
233 	return ret;
234 }
235 
236 static unsigned int hidraw_poll(struct file *file, poll_table *wait)
237 {
238 	struct hidraw_list *list = file->private_data;
239 
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;
245 	return 0;
246 }
247 
248 static int hidraw_open(struct inode *inode, struct file *file)
249 {
250 	unsigned int minor = iminor(inode);
251 	struct hidraw *dev;
252 	struct hidraw_list *list;
253 	int err = 0;
254 
255 	if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) {
256 		err = -ENOMEM;
257 		goto out;
258 	}
259 
260 	mutex_lock(&minors_lock);
261 	if (!hidraw_table[minor]) {
262 		kfree(list);
263 		err = -ENODEV;
264 		goto out_unlock;
265 	}
266 
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;
271 
272 	dev = hidraw_table[minor];
273 	if (!dev->open++) {
274 		err = hid_hw_power(dev->hid, PM_HINT_FULLON);
275 		if (err < 0)
276 			goto out_unlock;
277 
278 		err = hid_hw_open(dev->hid);
279 		if (err < 0) {
280 			hid_hw_power(dev->hid, PM_HINT_NORMAL);
281 			dev->open--;
282 		}
283 	}
284 
285 out_unlock:
286 	mutex_unlock(&minors_lock);
287 out:
288 	return err;
289 
290 }
291 
292 static int hidraw_release(struct inode * inode, struct file * file)
293 {
294 	unsigned int minor = iminor(inode);
295 	struct hidraw *dev;
296 	struct hidraw_list *list = file->private_data;
297 	int ret;
298 
299 	mutex_lock(&minors_lock);
300 	if (!hidraw_table[minor]) {
301 		ret = -ENODEV;
302 		goto unlock;
303 	}
304 
305 	list_del(&list->node);
306 	dev = hidraw_table[minor];
307 	if (!--dev->open) {
308 		if (list->hidraw->exist) {
309 			hid_hw_power(dev->hid, PM_HINT_NORMAL);
310 			hid_hw_close(dev->hid);
311 		} else {
312 			kfree(list->hidraw);
313 		}
314 	}
315 	kfree(list);
316 	ret = 0;
317 unlock:
318 	mutex_unlock(&minors_lock);
319 
320 	return ret;
321 }
322 
323 static long hidraw_ioctl(struct file *file, unsigned int cmd,
324 							unsigned long arg)
325 {
326 	struct inode *inode = file->f_path.dentry->d_inode;
327 	unsigned int minor = iminor(inode);
328 	long ret = 0;
329 	struct hidraw *dev;
330 	void __user *user_arg = (void __user*) arg;
331 
332 	mutex_lock(&minors_lock);
333 	dev = hidraw_table[minor];
334 	if (!dev) {
335 		ret = -ENODEV;
336 		goto out;
337 	}
338 
339 	switch (cmd) {
340 		case HIDIOCGRDESCSIZE:
341 			if (put_user(dev->hid->rsize, (int __user *)arg))
342 				ret = -EFAULT;
343 			break;
344 
345 		case HIDIOCGRDESC:
346 			{
347 				__u32 len;
348 
349 				if (get_user(len, (int __user *)arg))
350 					ret = -EFAULT;
351 				else if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
352 					ret = -EINVAL;
353 				else if (copy_to_user(user_arg + offsetof(
354 					struct hidraw_report_descriptor,
355 					value[0]),
356 					dev->hid->rdesc,
357 					min(dev->hid->rsize, len)))
358 					ret = -EFAULT;
359 				break;
360 			}
361 		case HIDIOCGRAWINFO:
362 			{
363 				struct hidraw_devinfo dinfo;
364 
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)))
369 					ret = -EFAULT;
370 				break;
371 			}
372 		default:
373 			{
374 				struct hid_device *hid = dev->hid;
375 				if (_IOC_TYPE(cmd) != 'H') {
376 					ret = -EINVAL;
377 					break;
378 				}
379 
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);
383 					break;
384 				}
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);
388 					break;
389 				}
390 
391 				/* Begin Read-only ioctls. */
392 				if (_IOC_DIR(cmd) != _IOC_READ) {
393 					ret = -EINVAL;
394 					break;
395 				}
396 
397 				if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) {
398 					int len;
399 					if (!hid->name) {
400 						ret = 0;
401 						break;
402 					}
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) ?
407 						-EFAULT : len;
408 					break;
409 				}
410 
411 				if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) {
412 					int len;
413 					if (!hid->phys) {
414 						ret = 0;
415 						break;
416 					}
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) ?
421 						-EFAULT : len;
422 					break;
423 				}
424 			}
425 
426 		ret = -ENOTTY;
427 	}
428 out:
429 	mutex_unlock(&minors_lock);
430 	return ret;
431 }
432 
433 static const struct file_operations hidraw_ops = {
434 	.owner =        THIS_MODULE,
435 	.read =         hidraw_read,
436 	.write =        hidraw_write,
437 	.poll =         hidraw_poll,
438 	.open =         hidraw_open,
439 	.release =      hidraw_release,
440 	.unlocked_ioctl = hidraw_ioctl,
441 #ifdef CONFIG_COMPAT
442 	.compat_ioctl   = hidraw_ioctl,
443 #endif
444 	.llseek =	noop_llseek,
445 };
446 
447 void hidraw_report_event(struct hid_device *hid, u8 *data, int len)
448 {
449 	struct hidraw *dev = hid->hidraw;
450 	struct hidraw_list *list;
451 
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);
457 	}
458 
459 	wake_up_interruptible(&dev->wait);
460 }
461 EXPORT_SYMBOL_GPL(hidraw_report_event);
462 
463 int hidraw_connect(struct hid_device *hid)
464 {
465 	int minor, result;
466 	struct hidraw *dev;
467 
468 	/* we accept any HID device, no matter the applications */
469 
470 	dev = kzalloc(sizeof(struct hidraw), GFP_KERNEL);
471 	if (!dev)
472 		return -ENOMEM;
473 
474 	result = -EINVAL;
475 
476 	mutex_lock(&minors_lock);
477 
478 	for (minor = 0; minor < HIDRAW_MAX_DEVICES; minor++) {
479 		if (hidraw_table[minor])
480 			continue;
481 		hidraw_table[minor] = dev;
482 		result = 0;
483 		break;
484 	}
485 
486 	if (result) {
487 		mutex_unlock(&minors_lock);
488 		kfree(dev);
489 		goto out;
490 	}
491 
492 	dev->dev = device_create(hidraw_class, &hid->dev, MKDEV(hidraw_major, minor),
493 				 NULL, "%s%d", "hidraw", minor);
494 
495 	if (IS_ERR(dev->dev)) {
496 		hidraw_table[minor] = NULL;
497 		mutex_unlock(&minors_lock);
498 		result = PTR_ERR(dev->dev);
499 		kfree(dev);
500 		goto out;
501 	}
502 
503 	mutex_unlock(&minors_lock);
504 	init_waitqueue_head(&dev->wait);
505 	INIT_LIST_HEAD(&dev->list);
506 
507 	dev->hid = hid;
508 	dev->minor = minor;
509 
510 	dev->exist = 1;
511 	hid->hidraw = dev;
512 
513 out:
514 	return result;
515 
516 }
517 EXPORT_SYMBOL_GPL(hidraw_connect);
518 
519 void hidraw_disconnect(struct hid_device *hid)
520 {
521 	struct hidraw *hidraw = hid->hidraw;
522 
523 	hidraw->exist = 0;
524 
525 	device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
526 
527 	mutex_lock(&minors_lock);
528 	hidraw_table[hidraw->minor] = NULL;
529 	mutex_unlock(&minors_lock);
530 
531 	if (hidraw->open) {
532 		hid_hw_close(hid);
533 		wake_up_interruptible(&hidraw->wait);
534 	} else {
535 		kfree(hidraw);
536 	}
537 }
538 EXPORT_SYMBOL_GPL(hidraw_disconnect);
539 
540 int __init hidraw_init(void)
541 {
542 	int result;
543 	dev_t dev_id;
544 
545 	result = alloc_chrdev_region(&dev_id, HIDRAW_FIRST_MINOR,
546 			HIDRAW_MAX_DEVICES, "hidraw");
547 
548 	hidraw_major = MAJOR(dev_id);
549 
550 	if (result < 0) {
551 		pr_warn("can't get major number\n");
552 		result = 0;
553 		goto out;
554 	}
555 
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");
560 		goto out;
561 	}
562 
563         cdev_init(&hidraw_cdev, &hidraw_ops);
564         cdev_add(&hidraw_cdev, dev_id, HIDRAW_MAX_DEVICES);
565 out:
566 	return result;
567 }
568 
569 void hidraw_exit(void)
570 {
571 	dev_t dev_id = MKDEV(hidraw_major, 0);
572 
573 	cdev_del(&hidraw_cdev);
574 	class_destroy(hidraw_class);
575 	unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES);
576 
577 }
578