HID: hid-example: fix some build issues
[pandora-kernel.git] / drivers / hid / hidraw.c
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 }