Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hiddev.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001 Paul Stewart
3  * Copyright (c) 2001 Vojtech Pavlik
4  *
5  * HID char devices, giving access to raw HID device events.
6  *
7  */
8 
9 /*
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  *
24  * Should you need to contact me, the author, you can do so either by
25  * e-mail - mail your message to Paul Stewart <[email protected]>
26  */
27 
28 #include <linux/poll.h>
29 #include <linux/slab.h>
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/input.h>
33 #include <linux/usb.h>
34 #include <linux/hid.h>
35 #include <linux/hiddev.h>
36 #include <linux/compat.h>
37 #include <linux/vmalloc.h>
38 #include "usbhid.h"
39 
40 #ifdef CONFIG_USB_DYNAMIC_MINORS
41 #define HIDDEV_MINOR_BASE 0
42 #define HIDDEV_MINORS 256
43 #else
44 #define HIDDEV_MINOR_BASE 96
45 #define HIDDEV_MINORS 16
46 #endif
47 #define HIDDEV_BUFFER_SIZE 2048
48 
49 struct hiddev {
50  int exist;
51  int open;
54  struct hid_device *hid;
55  struct list_head list;
57 };
58 
59 struct hiddev_list {
61  int head;
62  int tail;
63  unsigned flags;
65  struct hiddev *hiddev;
66  struct list_head node;
68 };
69 
70 /*
71  * Find a report, given the report's type and ID. The ID can be specified
72  * indirectly by REPORT_ID_FIRST (which returns the first report of the given
73  * type) or by (REPORT_ID_NEXT | old_id), which returns the next report of the
74  * given type which follows old_id.
75  */
76 static struct hid_report *
77 hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
78 {
79  unsigned int flags = rinfo->report_id & ~HID_REPORT_ID_MASK;
80  unsigned int rid = rinfo->report_id & HID_REPORT_ID_MASK;
81  struct hid_report_enum *report_enum;
82  struct hid_report *report;
83  struct list_head *list;
84 
85  if (rinfo->report_type < HID_REPORT_TYPE_MIN ||
87  return NULL;
88 
89  report_enum = hid->report_enum +
91 
92  switch (flags) {
93  case 0: /* Nothing to do -- report_id is already set correctly */
94  break;
95 
97  if (list_empty(&report_enum->report_list))
98  return NULL;
99 
100  list = report_enum->report_list.next;
101  report = list_entry(list, struct hid_report, list);
102  rinfo->report_id = report->id;
103  break;
104 
105  case HID_REPORT_ID_NEXT:
106  report = report_enum->report_id_hash[rid];
107  if (!report)
108  return NULL;
109 
110  list = report->list.next;
111  if (list == &report_enum->report_list)
112  return NULL;
113 
114  report = list_entry(list, struct hid_report, list);
115  rinfo->report_id = report->id;
116  break;
117 
118  default:
119  return NULL;
120  }
121 
122  return report_enum->report_id_hash[rinfo->report_id];
123 }
124 
125 /*
126  * Perform an exhaustive search of the report table for a usage, given its
127  * type and usage id.
128  */
129 static struct hid_field *
130 hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
131 {
132  int i, j;
133  struct hid_report *report;
134  struct hid_report_enum *report_enum;
135  struct hid_field *field;
136 
137  if (uref->report_type < HID_REPORT_TYPE_MIN ||
139  return NULL;
140 
141  report_enum = hid->report_enum +
143 
144  list_for_each_entry(report, &report_enum->report_list, list) {
145  for (i = 0; i < report->maxfield; i++) {
146  field = report->field[i];
147  for (j = 0; j < field->maxusage; j++) {
148  if (field->usage[j].hid == uref->usage_code) {
149  uref->report_id = report->id;
150  uref->field_index = i;
151  uref->usage_index = j;
152  return field;
153  }
154  }
155  }
156  }
157 
158  return NULL;
159 }
160 
161 static void hiddev_send_event(struct hid_device *hid,
162  struct hiddev_usage_ref *uref)
163 {
164  struct hiddev *hiddev = hid->hiddev;
165  struct hiddev_list *list;
166  unsigned long flags;
167 
168  spin_lock_irqsave(&hiddev->list_lock, flags);
169  list_for_each_entry(list, &hiddev->list, node) {
170  if (uref->field_index != HID_FIELD_INDEX_NONE ||
171  (list->flags & HIDDEV_FLAG_REPORT) != 0) {
172  list->buffer[list->head] = *uref;
173  list->head = (list->head + 1) &
174  (HIDDEV_BUFFER_SIZE - 1);
175  kill_fasync(&list->fasync, SIGIO, POLL_IN);
176  }
177  }
178  spin_unlock_irqrestore(&hiddev->list_lock, flags);
179 
180  wake_up_interruptible(&hiddev->wait);
181 }
182 
183 /*
184  * This is where hid.c calls into hiddev to pass an event that occurred over
185  * the interrupt pipe
186  */
187 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
188  struct hid_usage *usage, __s32 value)
189 {
190  unsigned type = field->report_type;
191  struct hiddev_usage_ref uref;
192 
193  uref.report_type =
196  ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
197  uref.report_id = field->report->id;
198  uref.field_index = field->index;
199  uref.usage_index = (usage - field->usage);
200  uref.usage_code = usage->hid;
201  uref.value = value;
202 
203  hiddev_send_event(hid, &uref);
204 }
206 
207 void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
208 {
209  unsigned type = report->type;
210  struct hiddev_usage_ref uref;
211 
212  memset(&uref, 0, sizeof(uref));
213  uref.report_type =
216  ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
217  uref.report_id = report->id;
219 
220  hiddev_send_event(hid, &uref);
221 }
222 
223 /*
224  * fasync file op
225  */
226 static int hiddev_fasync(int fd, struct file *file, int on)
227 {
228  struct hiddev_list *list = file->private_data;
229 
230  return fasync_helper(fd, file, on, &list->fasync);
231 }
232 
233 
234 /*
235  * release file op
236  */
237 static int hiddev_release(struct inode * inode, struct file * file)
238 {
239  struct hiddev_list *list = file->private_data;
240  unsigned long flags;
241 
242  spin_lock_irqsave(&list->hiddev->list_lock, flags);
243  list_del(&list->node);
244  spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
245 
246  mutex_lock(&list->hiddev->existancelock);
247  if (!--list->hiddev->open) {
248  if (list->hiddev->exist) {
249  usbhid_close(list->hiddev->hid);
250  usbhid_put_power(list->hiddev->hid);
251  } else {
252  mutex_unlock(&list->hiddev->existancelock);
253  kfree(list->hiddev);
254  vfree(list);
255  return 0;
256  }
257  }
258 
259  mutex_unlock(&list->hiddev->existancelock);
260  vfree(list);
261 
262  return 0;
263 }
264 
265 /*
266  * open file op
267  */
268 static int hiddev_open(struct inode *inode, struct file *file)
269 {
270  struct hiddev_list *list;
271  struct usb_interface *intf;
272  struct hid_device *hid;
273  struct hiddev *hiddev;
274  int res;
275 
276  intf = usbhid_find_interface(iminor(inode));
277  if (!intf)
278  return -ENODEV;
279  hid = usb_get_intfdata(intf);
280  hiddev = hid->hiddev;
281 
282  if (!(list = vzalloc(sizeof(struct hiddev_list))))
283  return -ENOMEM;
284  mutex_init(&list->thread_lock);
285  list->hiddev = hiddev;
286  file->private_data = list;
287 
288  /*
289  * no need for locking because the USB major number
290  * is shared which usbcore guards against disconnect
291  */
292  if (list->hiddev->exist) {
293  if (!list->hiddev->open++) {
294  res = usbhid_open(hiddev->hid);
295  if (res < 0) {
296  res = -EIO;
297  goto bail;
298  }
299  }
300  } else {
301  res = -ENODEV;
302  goto bail;
303  }
304 
305  spin_lock_irq(&list->hiddev->list_lock);
306  list_add_tail(&list->node, &hiddev->list);
307  spin_unlock_irq(&list->hiddev->list_lock);
308 
309  mutex_lock(&hiddev->existancelock);
310  if (!list->hiddev->open++)
311  if (list->hiddev->exist) {
312  struct hid_device *hid = hiddev->hid;
313  res = usbhid_get_power(hid);
314  if (res < 0) {
315  res = -EIO;
316  goto bail_unlock;
317  }
318  usbhid_open(hid);
319  }
320  mutex_unlock(&hiddev->existancelock);
321  return 0;
322 bail_unlock:
323  mutex_unlock(&hiddev->existancelock);
324 bail:
325  file->private_data = NULL;
326  vfree(list);
327  return res;
328 }
329 
330 /*
331  * "write" file op
332  */
333 static ssize_t hiddev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
334 {
335  return -EINVAL;
336 }
337 
338 /*
339  * "read" file op
340  */
341 static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
342 {
343  DEFINE_WAIT(wait);
344  struct hiddev_list *list = file->private_data;
345  int event_size;
346  int retval;
347 
348  event_size = ((list->flags & HIDDEV_FLAG_UREF) != 0) ?
349  sizeof(struct hiddev_usage_ref) : sizeof(struct hiddev_event);
350 
351  if (count < event_size)
352  return 0;
353 
354  /* lock against other threads */
355  retval = mutex_lock_interruptible(&list->thread_lock);
356  if (retval)
358 
359  while (retval == 0) {
360  if (list->head == list->tail) {
362 
363  while (list->head == list->tail) {
364  if (file->f_flags & O_NONBLOCK) {
365  retval = -EAGAIN;
366  break;
367  }
368  if (signal_pending(current)) {
369  retval = -ERESTARTSYS;
370  break;
371  }
372  if (!list->hiddev->exist) {
373  retval = -EIO;
374  break;
375  }
376 
377  /* let O_NONBLOCK tasks run */
378  mutex_unlock(&list->thread_lock);
379  schedule();
381  finish_wait(&list->hiddev->wait, &wait);
382  return -EINTR;
383  }
385  }
386  finish_wait(&list->hiddev->wait, &wait);
387 
388  }
389 
390  if (retval) {
391  mutex_unlock(&list->thread_lock);
392  return retval;
393  }
394 
395 
396  while (list->head != list->tail &&
397  retval + event_size <= count) {
398  if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
399  if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE) {
400  struct hiddev_event event;
401 
402  event.hid = list->buffer[list->tail].usage_code;
403  event.value = list->buffer[list->tail].value;
404  if (copy_to_user(buffer + retval, &event, sizeof(struct hiddev_event))) {
405  mutex_unlock(&list->thread_lock);
406  return -EFAULT;
407  }
408  retval += sizeof(struct hiddev_event);
409  }
410  } else {
411  if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE ||
412  (list->flags & HIDDEV_FLAG_REPORT) != 0) {
413 
414  if (copy_to_user(buffer + retval, list->buffer + list->tail, sizeof(struct hiddev_usage_ref))) {
415  mutex_unlock(&list->thread_lock);
416  return -EFAULT;
417  }
418  retval += sizeof(struct hiddev_usage_ref);
419  }
420  }
421  list->tail = (list->tail + 1) & (HIDDEV_BUFFER_SIZE - 1);
422  }
423 
424  }
425  mutex_unlock(&list->thread_lock);
426 
427  return retval;
428 }
429 
430 /*
431  * "poll" file op
432  * No kernel lock - fine
433  */
434 static unsigned int hiddev_poll(struct file *file, poll_table *wait)
435 {
436  struct hiddev_list *list = file->private_data;
437 
438  poll_wait(file, &list->hiddev->wait, wait);
439  if (list->head != list->tail)
440  return POLLIN | POLLRDNORM;
441  if (!list->hiddev->exist)
442  return POLLERR | POLLHUP;
443  return 0;
444 }
445 
446 /*
447  * "ioctl" file op
448  */
449 static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
450 {
451  struct hid_device *hid = hiddev->hid;
452  struct hiddev_report_info rinfo;
453  struct hiddev_usage_ref_multi *uref_multi = NULL;
454  struct hiddev_usage_ref *uref;
455  struct hid_report *report;
456  struct hid_field *field;
457  int i;
458 
459  uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
460  if (!uref_multi)
461  return -ENOMEM;
462  uref = &uref_multi->uref;
463  if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
464  if (copy_from_user(uref_multi, user_arg,
465  sizeof(*uref_multi)))
466  goto fault;
467  } else {
468  if (copy_from_user(uref, user_arg, sizeof(*uref)))
469  goto fault;
470  }
471 
472  switch (cmd) {
473  case HIDIOCGUCODE:
474  rinfo.report_type = uref->report_type;
475  rinfo.report_id = uref->report_id;
476  if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
477  goto inval;
478 
479  if (uref->field_index >= report->maxfield)
480  goto inval;
481 
482  field = report->field[uref->field_index];
483  if (uref->usage_index >= field->maxusage)
484  goto inval;
485 
486  uref->usage_code = field->usage[uref->usage_index].hid;
487 
488  if (copy_to_user(user_arg, uref, sizeof(*uref)))
489  goto fault;
490 
491  goto goodreturn;
492 
493  default:
494  if (cmd != HIDIOCGUSAGE &&
495  cmd != HIDIOCGUSAGES &&
497  goto inval;
498 
499  if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
500  field = hiddev_lookup_usage(hid, uref);
501  if (field == NULL)
502  goto inval;
503  } else {
504  rinfo.report_type = uref->report_type;
505  rinfo.report_id = uref->report_id;
506  if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
507  goto inval;
508 
509  if (uref->field_index >= report->maxfield)
510  goto inval;
511 
512  field = report->field[uref->field_index];
513 
514  if (cmd == HIDIOCGCOLLECTIONINDEX) {
515  if (uref->usage_index >= field->maxusage)
516  goto inval;
517  } else if (uref->usage_index >= field->report_count)
518  goto inval;
519 
520  else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
521  (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
522  uref->usage_index + uref_multi->num_values > field->report_count))
523  goto inval;
524  }
525 
526  switch (cmd) {
527  case HIDIOCGUSAGE:
528  uref->value = field->value[uref->usage_index];
529  if (copy_to_user(user_arg, uref, sizeof(*uref)))
530  goto fault;
531  goto goodreturn;
532 
533  case HIDIOCSUSAGE:
534  field->value[uref->usage_index] = uref->value;
535  goto goodreturn;
536 
538  i = field->usage[uref->usage_index].collection_index;
539  kfree(uref_multi);
540  return i;
541  case HIDIOCGUSAGES:
542  for (i = 0; i < uref_multi->num_values; i++)
543  uref_multi->values[i] =
544  field->value[uref->usage_index + i];
545  if (copy_to_user(user_arg, uref_multi,
546  sizeof(*uref_multi)))
547  goto fault;
548  goto goodreturn;
549  case HIDIOCSUSAGES:
550  for (i = 0; i < uref_multi->num_values; i++)
551  field->value[uref->usage_index + i] =
552  uref_multi->values[i];
553  goto goodreturn;
554  }
555 
556 goodreturn:
557  kfree(uref_multi);
558  return 0;
559 fault:
560  kfree(uref_multi);
561  return -EFAULT;
562 inval:
563  kfree(uref_multi);
564  return -EINVAL;
565  }
566 }
567 
568 static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
569 {
570  struct hid_device *hid = hiddev->hid;
571  struct usb_device *dev = hid_to_usb_dev(hid);
572  int idx, len;
573  char *buf;
574 
575  if (get_user(idx, (int __user *)user_arg))
576  return -EFAULT;
577 
578  if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
579  return -ENOMEM;
580 
581  if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
582  kfree(buf);
583  return -EINVAL;
584  }
585 
586  if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
587  kfree(buf);
588  return -EFAULT;
589  }
590 
591  kfree(buf);
592 
593  return len;
594 }
595 
596 static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
597 {
598  struct hiddev_list *list = file->private_data;
599  struct hiddev *hiddev = list->hiddev;
600  struct hid_device *hid;
601  struct hiddev_collection_info cinfo;
602  struct hiddev_report_info rinfo;
603  struct hiddev_field_info finfo;
604  struct hiddev_devinfo dinfo;
605  struct hid_report *report;
606  struct hid_field *field;
607  void __user *user_arg = (void __user *)arg;
608  int i, r = -EINVAL;
609 
610  /* Called without BKL by compat methods so no BKL taken */
611 
612  mutex_lock(&hiddev->existancelock);
613  if (!hiddev->exist) {
614  r = -ENODEV;
615  goto ret_unlock;
616  }
617 
618  hid = hiddev->hid;
619 
620  switch (cmd) {
621 
622  case HIDIOCGVERSION:
623  r = put_user(HID_VERSION, (int __user *)arg) ?
624  -EFAULT : 0;
625  break;
626 
627  case HIDIOCAPPLICATION:
628  if (arg < 0 || arg >= hid->maxapplication)
629  break;
630 
631  for (i = 0; i < hid->maxcollection; i++)
632  if (hid->collection[i].type ==
633  HID_COLLECTION_APPLICATION && arg-- == 0)
634  break;
635 
636  if (i < hid->maxcollection)
637  r = hid->collection[i].usage;
638  break;
639 
640  case HIDIOCGDEVINFO:
641  {
642  struct usb_device *dev = hid_to_usb_dev(hid);
643  struct usbhid_device *usbhid = hid->driver_data;
644 
645  memset(&dinfo, 0, sizeof(dinfo));
646 
647  dinfo.bustype = BUS_USB;
648  dinfo.busnum = dev->bus->busnum;
649  dinfo.devnum = dev->devnum;
650  dinfo.ifnum = usbhid->ifnum;
651  dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
652  dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
653  dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
654  dinfo.num_applications = hid->maxapplication;
655 
656  r = copy_to_user(user_arg, &dinfo, sizeof(dinfo)) ?
657  -EFAULT : 0;
658  break;
659  }
660 
661  case HIDIOCGFLAG:
662  r = put_user(list->flags, (int __user *)arg) ?
663  -EFAULT : 0;
664  break;
665 
666  case HIDIOCSFLAG:
667  {
668  int newflags;
669 
670  if (get_user(newflags, (int __user *)arg)) {
671  r = -EFAULT;
672  break;
673  }
674 
675  if ((newflags & ~HIDDEV_FLAGS) != 0 ||
676  ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
677  (newflags & HIDDEV_FLAG_UREF) == 0))
678  break;
679 
680  list->flags = newflags;
681 
682  r = 0;
683  break;
684  }
685 
686  case HIDIOCGSTRING:
687  r = hiddev_ioctl_string(hiddev, cmd, user_arg);
688  break;
689 
690  case HIDIOCINITREPORT:
691  usbhid_init_reports(hid);
692  r = 0;
693  break;
694 
695  case HIDIOCGREPORT:
696  if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
697  r = -EFAULT;
698  break;
699  }
700 
701  if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
702  break;
703 
704  report = hiddev_lookup_report(hid, &rinfo);
705  if (report == NULL)
706  break;
707 
708  usbhid_submit_report(hid, report, USB_DIR_IN);
709  usbhid_wait_io(hid);
710 
711  r = 0;
712  break;
713 
714  case HIDIOCSREPORT:
715  if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
716  r = -EFAULT;
717  break;
718  }
719 
720  if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
721  break;
722 
723  report = hiddev_lookup_report(hid, &rinfo);
724  if (report == NULL)
725  break;
726 
727  usbhid_submit_report(hid, report, USB_DIR_OUT);
728  usbhid_wait_io(hid);
729 
730  r = 0;
731  break;
732 
733  case HIDIOCGREPORTINFO:
734  if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
735  r = -EFAULT;
736  break;
737  }
738 
739  report = hiddev_lookup_report(hid, &rinfo);
740  if (report == NULL)
741  break;
742 
743  rinfo.num_fields = report->maxfield;
744 
745  r = copy_to_user(user_arg, &rinfo, sizeof(rinfo)) ?
746  -EFAULT : 0;
747  break;
748 
749  case HIDIOCGFIELDINFO:
750  if (copy_from_user(&finfo, user_arg, sizeof(finfo))) {
751  r = -EFAULT;
752  break;
753  }
754 
755  rinfo.report_type = finfo.report_type;
756  rinfo.report_id = finfo.report_id;
757 
758  report = hiddev_lookup_report(hid, &rinfo);
759  if (report == NULL)
760  break;
761 
762  if (finfo.field_index >= report->maxfield)
763  break;
764 
765  field = report->field[finfo.field_index];
766  memset(&finfo, 0, sizeof(finfo));
767  finfo.report_type = rinfo.report_type;
768  finfo.report_id = rinfo.report_id;
769  finfo.field_index = field->report_count - 1;
770  finfo.maxusage = field->maxusage;
771  finfo.flags = field->flags;
772  finfo.physical = field->physical;
773  finfo.logical = field->logical;
774  finfo.application = field->application;
775  finfo.logical_minimum = field->logical_minimum;
776  finfo.logical_maximum = field->logical_maximum;
777  finfo.physical_minimum = field->physical_minimum;
778  finfo.physical_maximum = field->physical_maximum;
779  finfo.unit_exponent = field->unit_exponent;
780  finfo.unit = field->unit;
781 
782  r = copy_to_user(user_arg, &finfo, sizeof(finfo)) ?
783  -EFAULT : 0;
784  break;
785 
786  case HIDIOCGUCODE:
787  /* fall through */
788  case HIDIOCGUSAGE:
789  case HIDIOCSUSAGE:
790  case HIDIOCGUSAGES:
791  case HIDIOCSUSAGES:
793  r = hiddev_ioctl_usage(hiddev, cmd, user_arg);
794  break;
795 
797  if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) {
798  r = -EFAULT;
799  break;
800  }
801 
802  if (cinfo.index >= hid->maxcollection)
803  break;
804 
805  cinfo.type = hid->collection[cinfo.index].type;
806  cinfo.usage = hid->collection[cinfo.index].usage;
807  cinfo.level = hid->collection[cinfo.index].level;
808 
809  r = copy_to_user(user_arg, &cinfo, sizeof(cinfo)) ?
810  -EFAULT : 0;
811  break;
812 
813  default:
814  if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
815  break;
816 
817  if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
818  int len = strlen(hid->name) + 1;
819  if (len > _IOC_SIZE(cmd))
820  len = _IOC_SIZE(cmd);
821  r = copy_to_user(user_arg, hid->name, len) ?
822  -EFAULT : len;
823  break;
824  }
825 
826  if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) {
827  int len = strlen(hid->phys) + 1;
828  if (len > _IOC_SIZE(cmd))
829  len = _IOC_SIZE(cmd);
830  r = copy_to_user(user_arg, hid->phys, len) ?
831  -EFAULT : len;
832  break;
833  }
834  }
835 
836 ret_unlock:
837  mutex_unlock(&hiddev->existancelock);
838  return r;
839 }
840 
841 #ifdef CONFIG_COMPAT
842 static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
843 {
844  return hiddev_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
845 }
846 #endif
847 
848 static const struct file_operations hiddev_fops = {
849  .owner = THIS_MODULE,
850  .read = hiddev_read,
851  .write = hiddev_write,
852  .poll = hiddev_poll,
853  .open = hiddev_open,
854  .release = hiddev_release,
855  .unlocked_ioctl = hiddev_ioctl,
856  .fasync = hiddev_fasync,
857 #ifdef CONFIG_COMPAT
858  .compat_ioctl = hiddev_compat_ioctl,
859 #endif
860  .llseek = noop_llseek,
861 };
862 
863 static char *hiddev_devnode(struct device *dev, umode_t *mode)
864 {
865  return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
866 }
867 
868 static struct usb_class_driver hiddev_class = {
869  .name = "hiddev%d",
870  .devnode = hiddev_devnode,
871  .fops = &hiddev_fops,
872  .minor_base = HIDDEV_MINOR_BASE,
873 };
874 
875 /*
876  * This is where hid.c calls us to connect a hid device to the hiddev driver
877  */
878 int hiddev_connect(struct hid_device *hid, unsigned int force)
879 {
880  struct hiddev *hiddev;
881  struct usbhid_device *usbhid = hid->driver_data;
882  int retval;
883 
884  if (!force) {
885  unsigned int i;
886  for (i = 0; i < hid->maxcollection; i++)
887  if (hid->collection[i].type ==
889  !IS_INPUT_APPLICATION(hid->collection[i].usage))
890  break;
891 
892  if (i == hid->maxcollection)
893  return -1;
894  }
895 
896  if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
897  return -1;
898 
899  init_waitqueue_head(&hiddev->wait);
900  INIT_LIST_HEAD(&hiddev->list);
901  spin_lock_init(&hiddev->list_lock);
902  mutex_init(&hiddev->existancelock);
903  hid->hiddev = hiddev;
904  hiddev->hid = hid;
905  hiddev->exist = 1;
906  retval = usb_register_dev(usbhid->intf, &hiddev_class);
907  if (retval) {
908  hid_err(hid, "Not able to get a minor for this device\n");
909  hid->hiddev = NULL;
910  kfree(hiddev);
911  return -1;
912  }
913  return 0;
914 }
915 
916 /*
917  * This is where hid.c calls us to disconnect a hiddev device from the
918  * corresponding hid device (usually because the usb device has disconnected)
919  */
920 static struct usb_class_driver hiddev_class;
921 void hiddev_disconnect(struct hid_device *hid)
922 {
923  struct hiddev *hiddev = hid->hiddev;
924  struct usbhid_device *usbhid = hid->driver_data;
925 
926  usb_deregister_dev(usbhid->intf, &hiddev_class);
927 
928  mutex_lock(&hiddev->existancelock);
929  hiddev->exist = 0;
930 
931  if (hiddev->open) {
932  mutex_unlock(&hiddev->existancelock);
933  usbhid_close(hiddev->hid);
934  wake_up_interruptible(&hiddev->wait);
935  } else {
936  mutex_unlock(&hiddev->existancelock);
937  kfree(hiddev);
938  }
939 }