Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Copyright (c) 2001 Paul Stewart
0004  *  Copyright (c) 2001 Vojtech Pavlik
0005  *
0006  *  HID char devices, giving access to raw HID device events.
0007  */
0008 
0009 /*
0010  *
0011  * Should you need to contact me, the author, you can do so either by
0012  * e-mail - mail your message to Paul Stewart <stewart@wetlogic.net>
0013  */
0014 
0015 #include <linux/poll.h>
0016 #include <linux/slab.h>
0017 #include <linux/sched/signal.h>
0018 #include <linux/module.h>
0019 #include <linux/init.h>
0020 #include <linux/input.h>
0021 #include <linux/usb.h>
0022 #include <linux/hid.h>
0023 #include <linux/hiddev.h>
0024 #include <linux/compat.h>
0025 #include <linux/vmalloc.h>
0026 #include <linux/nospec.h>
0027 #include "usbhid.h"
0028 
0029 #ifdef CONFIG_USB_DYNAMIC_MINORS
0030 #define HIDDEV_MINOR_BASE   0
0031 #define HIDDEV_MINORS       256
0032 #else
0033 #define HIDDEV_MINOR_BASE   96
0034 #define HIDDEV_MINORS       16
0035 #endif
0036 #define HIDDEV_BUFFER_SIZE  2048
0037 
0038 struct hiddev_list {
0039     struct hiddev_usage_ref buffer[HIDDEV_BUFFER_SIZE];
0040     int head;
0041     int tail;
0042     unsigned flags;
0043     struct fasync_struct *fasync;
0044     struct hiddev *hiddev;
0045     struct list_head node;
0046     struct mutex thread_lock;
0047 };
0048 
0049 /*
0050  * Find a report, given the report's type and ID.  The ID can be specified
0051  * indirectly by REPORT_ID_FIRST (which returns the first report of the given
0052  * type) or by (REPORT_ID_NEXT | old_id), which returns the next report of the
0053  * given type which follows old_id.
0054  */
0055 static struct hid_report *
0056 hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
0057 {
0058     unsigned int flags = rinfo->report_id & ~HID_REPORT_ID_MASK;
0059     unsigned int rid = rinfo->report_id & HID_REPORT_ID_MASK;
0060     struct hid_report_enum *report_enum;
0061     struct hid_report *report;
0062     struct list_head *list;
0063 
0064     if (rinfo->report_type < HID_REPORT_TYPE_MIN ||
0065         rinfo->report_type > HID_REPORT_TYPE_MAX)
0066         return NULL;
0067 
0068     report_enum = hid->report_enum +
0069         (rinfo->report_type - HID_REPORT_TYPE_MIN);
0070 
0071     switch (flags) {
0072     case 0: /* Nothing to do -- report_id is already set correctly */
0073         break;
0074 
0075     case HID_REPORT_ID_FIRST:
0076         if (list_empty(&report_enum->report_list))
0077             return NULL;
0078 
0079         list = report_enum->report_list.next;
0080         report = list_entry(list, struct hid_report, list);
0081         rinfo->report_id = report->id;
0082         break;
0083 
0084     case HID_REPORT_ID_NEXT:
0085         report = report_enum->report_id_hash[rid];
0086         if (!report)
0087             return NULL;
0088 
0089         list = report->list.next;
0090         if (list == &report_enum->report_list)
0091             return NULL;
0092 
0093         report = list_entry(list, struct hid_report, list);
0094         rinfo->report_id = report->id;
0095         break;
0096 
0097     default:
0098         return NULL;
0099     }
0100 
0101     return report_enum->report_id_hash[rinfo->report_id];
0102 }
0103 
0104 /*
0105  * Perform an exhaustive search of the report table for a usage, given its
0106  * type and usage id.
0107  */
0108 static struct hid_field *
0109 hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
0110 {
0111     int i, j;
0112     struct hid_report *report;
0113     struct hid_report_enum *report_enum;
0114     struct hid_field *field;
0115 
0116     if (uref->report_type < HID_REPORT_TYPE_MIN ||
0117         uref->report_type > HID_REPORT_TYPE_MAX)
0118         return NULL;
0119 
0120     report_enum = hid->report_enum +
0121         (uref->report_type - HID_REPORT_TYPE_MIN);
0122 
0123     list_for_each_entry(report, &report_enum->report_list, list) {
0124         for (i = 0; i < report->maxfield; i++) {
0125             field = report->field[i];
0126             for (j = 0; j < field->maxusage; j++) {
0127                 if (field->usage[j].hid == uref->usage_code) {
0128                     uref->report_id = report->id;
0129                     uref->field_index = i;
0130                     uref->usage_index = j;
0131                     return field;
0132                 }
0133             }
0134         }
0135     }
0136 
0137     return NULL;
0138 }
0139 
0140 static void hiddev_send_event(struct hid_device *hid,
0141                   struct hiddev_usage_ref *uref)
0142 {
0143     struct hiddev *hiddev = hid->hiddev;
0144     struct hiddev_list *list;
0145     unsigned long flags;
0146 
0147     spin_lock_irqsave(&hiddev->list_lock, flags);
0148     list_for_each_entry(list, &hiddev->list, node) {
0149         if (uref->field_index != HID_FIELD_INDEX_NONE ||
0150             (list->flags & HIDDEV_FLAG_REPORT) != 0) {
0151             list->buffer[list->head] = *uref;
0152             list->head = (list->head + 1) &
0153                 (HIDDEV_BUFFER_SIZE - 1);
0154             kill_fasync(&list->fasync, SIGIO, POLL_IN);
0155         }
0156     }
0157     spin_unlock_irqrestore(&hiddev->list_lock, flags);
0158 
0159     wake_up_interruptible(&hiddev->wait);
0160 }
0161 
0162 /*
0163  * This is where hid.c calls into hiddev to pass an event that occurred over
0164  * the interrupt pipe
0165  */
0166 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
0167               struct hid_usage *usage, __s32 value)
0168 {
0169     unsigned type = field->report_type;
0170     struct hiddev_usage_ref uref;
0171 
0172     uref.report_type =
0173       (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
0174       ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
0175        ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
0176     uref.report_id = field->report->id;
0177     uref.field_index = field->index;
0178     uref.usage_index = (usage - field->usage);
0179     uref.usage_code = usage->hid;
0180     uref.value = value;
0181 
0182     hiddev_send_event(hid, &uref);
0183 }
0184 EXPORT_SYMBOL_GPL(hiddev_hid_event);
0185 
0186 void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
0187 {
0188     unsigned type = report->type;
0189     struct hiddev_usage_ref uref;
0190 
0191     memset(&uref, 0, sizeof(uref));
0192     uref.report_type =
0193       (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
0194       ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
0195        ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
0196     uref.report_id = report->id;
0197     uref.field_index = HID_FIELD_INDEX_NONE;
0198 
0199     hiddev_send_event(hid, &uref);
0200 }
0201 
0202 /*
0203  * fasync file op
0204  */
0205 static int hiddev_fasync(int fd, struct file *file, int on)
0206 {
0207     struct hiddev_list *list = file->private_data;
0208 
0209     return fasync_helper(fd, file, on, &list->fasync);
0210 }
0211 
0212 
0213 /*
0214  * release file op
0215  */
0216 static int hiddev_release(struct inode * inode, struct file * file)
0217 {
0218     struct hiddev_list *list = file->private_data;
0219     unsigned long flags;
0220 
0221     spin_lock_irqsave(&list->hiddev->list_lock, flags);
0222     list_del(&list->node);
0223     spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
0224 
0225     mutex_lock(&list->hiddev->existancelock);
0226     if (!--list->hiddev->open) {
0227         if (list->hiddev->exist) {
0228             hid_hw_close(list->hiddev->hid);
0229             hid_hw_power(list->hiddev->hid, PM_HINT_NORMAL);
0230         } else {
0231             mutex_unlock(&list->hiddev->existancelock);
0232             kfree(list->hiddev);
0233             vfree(list);
0234             return 0;
0235         }
0236     }
0237 
0238     mutex_unlock(&list->hiddev->existancelock);
0239     vfree(list);
0240 
0241     return 0;
0242 }
0243 
0244 static int __hiddev_open(struct hiddev *hiddev, struct file *file)
0245 {
0246     struct hiddev_list *list;
0247     int error;
0248 
0249     lockdep_assert_held(&hiddev->existancelock);
0250 
0251     list = vzalloc(sizeof(*list));
0252     if (!list)
0253         return -ENOMEM;
0254 
0255     mutex_init(&list->thread_lock);
0256     list->hiddev = hiddev;
0257 
0258     if (!hiddev->open++) {
0259         error = hid_hw_power(hiddev->hid, PM_HINT_FULLON);
0260         if (error < 0)
0261             goto err_drop_count;
0262 
0263         error = hid_hw_open(hiddev->hid);
0264         if (error < 0)
0265             goto err_normal_power;
0266     }
0267 
0268     spin_lock_irq(&hiddev->list_lock);
0269     list_add_tail(&list->node, &hiddev->list);
0270     spin_unlock_irq(&hiddev->list_lock);
0271 
0272     file->private_data = list;
0273 
0274     return 0;
0275 
0276 err_normal_power:
0277     hid_hw_power(hiddev->hid, PM_HINT_NORMAL);
0278 err_drop_count:
0279     hiddev->open--;
0280     vfree(list);
0281     return error;
0282 }
0283 
0284 /*
0285  * open file op
0286  */
0287 static int hiddev_open(struct inode *inode, struct file *file)
0288 {
0289     struct usb_interface *intf;
0290     struct hid_device *hid;
0291     struct hiddev *hiddev;
0292     int res;
0293 
0294     intf = usbhid_find_interface(iminor(inode));
0295     if (!intf)
0296         return -ENODEV;
0297 
0298     hid = usb_get_intfdata(intf);
0299     hiddev = hid->hiddev;
0300 
0301     mutex_lock(&hiddev->existancelock);
0302     res = hiddev->exist ? __hiddev_open(hiddev, file) : -ENODEV;
0303     mutex_unlock(&hiddev->existancelock);
0304 
0305     return res;
0306 }
0307 
0308 /*
0309  * "write" file op
0310  */
0311 static ssize_t hiddev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
0312 {
0313     return -EINVAL;
0314 }
0315 
0316 /*
0317  * "read" file op
0318  */
0319 static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
0320 {
0321     DEFINE_WAIT(wait);
0322     struct hiddev_list *list = file->private_data;
0323     int event_size;
0324     int retval;
0325 
0326     event_size = ((list->flags & HIDDEV_FLAG_UREF) != 0) ?
0327         sizeof(struct hiddev_usage_ref) : sizeof(struct hiddev_event);
0328 
0329     if (count < event_size)
0330         return 0;
0331 
0332     /* lock against other threads */
0333     retval = mutex_lock_interruptible(&list->thread_lock);
0334     if (retval)
0335         return -ERESTARTSYS;
0336 
0337     while (retval == 0) {
0338         if (list->head == list->tail) {
0339             prepare_to_wait(&list->hiddev->wait, &wait, TASK_INTERRUPTIBLE);
0340 
0341             while (list->head == list->tail) {
0342                 if (signal_pending(current)) {
0343                     retval = -ERESTARTSYS;
0344                     break;
0345                 }
0346                 if (!list->hiddev->exist) {
0347                     retval = -EIO;
0348                     break;
0349                 }
0350                 if (file->f_flags & O_NONBLOCK) {
0351                     retval = -EAGAIN;
0352                     break;
0353                 }
0354 
0355                 /* let O_NONBLOCK tasks run */
0356                 mutex_unlock(&list->thread_lock);
0357                 schedule();
0358                 if (mutex_lock_interruptible(&list->thread_lock)) {
0359                     finish_wait(&list->hiddev->wait, &wait);
0360                     return -EINTR;
0361                 }
0362                 set_current_state(TASK_INTERRUPTIBLE);
0363             }
0364             finish_wait(&list->hiddev->wait, &wait);
0365 
0366         }
0367 
0368         if (retval) {
0369             mutex_unlock(&list->thread_lock);
0370             return retval;
0371         }
0372 
0373 
0374         while (list->head != list->tail &&
0375                retval + event_size <= count) {
0376             if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
0377                 if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE) {
0378                     struct hiddev_event event;
0379 
0380                     event.hid = list->buffer[list->tail].usage_code;
0381                     event.value = list->buffer[list->tail].value;
0382                     if (copy_to_user(buffer + retval, &event, sizeof(struct hiddev_event))) {
0383                         mutex_unlock(&list->thread_lock);
0384                         return -EFAULT;
0385                     }
0386                     retval += sizeof(struct hiddev_event);
0387                 }
0388             } else {
0389                 if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE ||
0390                     (list->flags & HIDDEV_FLAG_REPORT) != 0) {
0391 
0392                     if (copy_to_user(buffer + retval, list->buffer + list->tail, sizeof(struct hiddev_usage_ref))) {
0393                         mutex_unlock(&list->thread_lock);
0394                         return -EFAULT;
0395                     }
0396                     retval += sizeof(struct hiddev_usage_ref);
0397                 }
0398             }
0399             list->tail = (list->tail + 1) & (HIDDEV_BUFFER_SIZE - 1);
0400         }
0401 
0402     }
0403     mutex_unlock(&list->thread_lock);
0404 
0405     return retval;
0406 }
0407 
0408 /*
0409  * "poll" file op
0410  * No kernel lock - fine
0411  */
0412 static __poll_t hiddev_poll(struct file *file, poll_table *wait)
0413 {
0414     struct hiddev_list *list = file->private_data;
0415 
0416     poll_wait(file, &list->hiddev->wait, wait);
0417     if (list->head != list->tail)
0418         return EPOLLIN | EPOLLRDNORM | EPOLLOUT;
0419     if (!list->hiddev->exist)
0420         return EPOLLERR | EPOLLHUP;
0421     return 0;
0422 }
0423 
0424 /*
0425  * "ioctl" file op
0426  */
0427 static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
0428 {
0429     struct hid_device *hid = hiddev->hid;
0430     struct hiddev_report_info rinfo;
0431     struct hiddev_usage_ref_multi *uref_multi = NULL;
0432     struct hiddev_usage_ref *uref;
0433     struct hid_report *report;
0434     struct hid_field *field;
0435     int i;
0436 
0437     uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
0438     if (!uref_multi)
0439         return -ENOMEM;
0440     uref = &uref_multi->uref;
0441     if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
0442         if (copy_from_user(uref_multi, user_arg,
0443                    sizeof(*uref_multi)))
0444             goto fault;
0445     } else {
0446         if (copy_from_user(uref, user_arg, sizeof(*uref)))
0447             goto fault;
0448     }
0449 
0450     switch (cmd) {
0451     case HIDIOCGUCODE:
0452         rinfo.report_type = uref->report_type;
0453         rinfo.report_id = uref->report_id;
0454         if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
0455             goto inval;
0456 
0457         if (uref->field_index >= report->maxfield)
0458             goto inval;
0459         uref->field_index = array_index_nospec(uref->field_index,
0460                                report->maxfield);
0461 
0462         field = report->field[uref->field_index];
0463         if (uref->usage_index >= field->maxusage)
0464             goto inval;
0465         uref->usage_index = array_index_nospec(uref->usage_index,
0466                                field->maxusage);
0467 
0468         uref->usage_code = field->usage[uref->usage_index].hid;
0469 
0470         if (copy_to_user(user_arg, uref, sizeof(*uref)))
0471             goto fault;
0472 
0473         goto goodreturn;
0474 
0475     default:
0476         if (cmd != HIDIOCGUSAGE &&
0477             cmd != HIDIOCGUSAGES &&
0478             uref->report_type == HID_REPORT_TYPE_INPUT)
0479             goto inval;
0480 
0481         if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
0482             field = hiddev_lookup_usage(hid, uref);
0483             if (field == NULL)
0484                 goto inval;
0485         } else {
0486             rinfo.report_type = uref->report_type;
0487             rinfo.report_id = uref->report_id;
0488             if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
0489                 goto inval;
0490 
0491             if (uref->field_index >= report->maxfield)
0492                 goto inval;
0493             uref->field_index = array_index_nospec(uref->field_index,
0494                                    report->maxfield);
0495 
0496             field = report->field[uref->field_index];
0497 
0498             if (cmd == HIDIOCGCOLLECTIONINDEX) {
0499                 if (uref->usage_index >= field->maxusage)
0500                     goto inval;
0501                 uref->usage_index =
0502                     array_index_nospec(uref->usage_index,
0503                                field->maxusage);
0504             } else if (uref->usage_index >= field->report_count)
0505                 goto inval;
0506         }
0507 
0508         if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
0509             if (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
0510                 uref->usage_index + uref_multi->num_values >
0511                 field->report_count)
0512                 goto inval;
0513 
0514             uref->usage_index =
0515                 array_index_nospec(uref->usage_index,
0516                            field->report_count -
0517                            uref_multi->num_values);
0518         }
0519 
0520         switch (cmd) {
0521         case HIDIOCGUSAGE:
0522             if (uref->usage_index >= field->report_count)
0523                 goto inval;
0524             uref->value = field->value[uref->usage_index];
0525             if (copy_to_user(user_arg, uref, sizeof(*uref)))
0526                 goto fault;
0527             goto goodreturn;
0528 
0529         case HIDIOCSUSAGE:
0530             if (uref->usage_index >= field->report_count)
0531                 goto inval;
0532             field->value[uref->usage_index] = uref->value;
0533             goto goodreturn;
0534 
0535         case HIDIOCGCOLLECTIONINDEX:
0536             i = field->usage[uref->usage_index].collection_index;
0537             kfree(uref_multi);
0538             return i;
0539         case HIDIOCGUSAGES:
0540             for (i = 0; i < uref_multi->num_values; i++)
0541                 uref_multi->values[i] =
0542                     field->value[uref->usage_index + i];
0543             if (copy_to_user(user_arg, uref_multi,
0544                      sizeof(*uref_multi)))
0545                 goto fault;
0546             goto goodreturn;
0547         case HIDIOCSUSAGES:
0548             for (i = 0; i < uref_multi->num_values; i++)
0549                 field->value[uref->usage_index + i] =
0550                     uref_multi->values[i];
0551             goto goodreturn;
0552         }
0553 
0554 goodreturn:
0555         kfree(uref_multi);
0556         return 0;
0557 fault:
0558         kfree(uref_multi);
0559         return -EFAULT;
0560 inval:
0561         kfree(uref_multi);
0562         return -EINVAL;
0563     }
0564 }
0565 
0566 static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
0567 {
0568     struct hid_device *hid = hiddev->hid;
0569     struct usb_device *dev = hid_to_usb_dev(hid);
0570     int idx, len;
0571     char *buf;
0572 
0573     if (get_user(idx, (int __user *)user_arg))
0574         return -EFAULT;
0575 
0576     if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
0577         return -ENOMEM;
0578 
0579     if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
0580         kfree(buf);
0581         return -EINVAL;
0582     }
0583 
0584     if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
0585         kfree(buf);
0586         return -EFAULT;
0587     }
0588 
0589     kfree(buf);
0590 
0591     return len;
0592 }
0593 
0594 static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0595 {
0596     struct hiddev_list *list = file->private_data;
0597     struct hiddev *hiddev = list->hiddev;
0598     struct hid_device *hid;
0599     struct hiddev_collection_info cinfo;
0600     struct hiddev_report_info rinfo;
0601     struct hiddev_field_info finfo;
0602     struct hiddev_devinfo dinfo;
0603     struct hid_report *report;
0604     struct hid_field *field;
0605     void __user *user_arg = (void __user *)arg;
0606     int i, r = -EINVAL;
0607 
0608     /* Called without BKL by compat methods so no BKL taken */
0609 
0610     mutex_lock(&hiddev->existancelock);
0611     if (!hiddev->exist) {
0612         r = -ENODEV;
0613         goto ret_unlock;
0614     }
0615 
0616     hid = hiddev->hid;
0617 
0618     switch (cmd) {
0619 
0620     case HIDIOCGVERSION:
0621         r = put_user(HID_VERSION, (int __user *)arg) ?
0622             -EFAULT : 0;
0623         break;
0624 
0625     case HIDIOCAPPLICATION:
0626         if (arg >= hid->maxapplication)
0627             break;
0628 
0629         for (i = 0; i < hid->maxcollection; i++)
0630             if (hid->collection[i].type ==
0631                 HID_COLLECTION_APPLICATION && arg-- == 0)
0632                 break;
0633 
0634         if (i < hid->maxcollection)
0635             r = hid->collection[i].usage;
0636         break;
0637 
0638     case HIDIOCGDEVINFO:
0639         {
0640             struct usb_device *dev = hid_to_usb_dev(hid);
0641             struct usbhid_device *usbhid = hid->driver_data;
0642 
0643             memset(&dinfo, 0, sizeof(dinfo));
0644 
0645             dinfo.bustype = BUS_USB;
0646             dinfo.busnum = dev->bus->busnum;
0647             dinfo.devnum = dev->devnum;
0648             dinfo.ifnum = usbhid->ifnum;
0649             dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
0650             dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
0651             dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
0652             dinfo.num_applications = hid->maxapplication;
0653 
0654             r = copy_to_user(user_arg, &dinfo, sizeof(dinfo)) ?
0655                 -EFAULT : 0;
0656             break;
0657         }
0658 
0659     case HIDIOCGFLAG:
0660         r = put_user(list->flags, (int __user *)arg) ?
0661             -EFAULT : 0;
0662         break;
0663 
0664     case HIDIOCSFLAG:
0665         {
0666             int newflags;
0667 
0668             if (get_user(newflags, (int __user *)arg)) {
0669                 r = -EFAULT;
0670                 break;
0671             }
0672 
0673             if ((newflags & ~HIDDEV_FLAGS) != 0 ||
0674                 ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
0675                  (newflags & HIDDEV_FLAG_UREF) == 0))
0676                 break;
0677 
0678             list->flags = newflags;
0679 
0680             r = 0;
0681             break;
0682         }
0683 
0684     case HIDIOCGSTRING:
0685         r = hiddev_ioctl_string(hiddev, cmd, user_arg);
0686         break;
0687 
0688     case HIDIOCINITREPORT:
0689         usbhid_init_reports(hid);
0690         hiddev->initialized = true;
0691         r = 0;
0692         break;
0693 
0694     case HIDIOCGREPORT:
0695         if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
0696             r = -EFAULT;
0697             break;
0698         }
0699 
0700         if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
0701             break;
0702 
0703         report = hiddev_lookup_report(hid, &rinfo);
0704         if (report == NULL)
0705             break;
0706 
0707         hid_hw_request(hid, report, HID_REQ_GET_REPORT);
0708         hid_hw_wait(hid);
0709 
0710         r = 0;
0711         break;
0712 
0713     case HIDIOCSREPORT:
0714         if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
0715             r = -EFAULT;
0716             break;
0717         }
0718 
0719         if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
0720             break;
0721 
0722         report = hiddev_lookup_report(hid, &rinfo);
0723         if (report == NULL)
0724             break;
0725 
0726         hid_hw_request(hid, report, HID_REQ_SET_REPORT);
0727         hid_hw_wait(hid);
0728 
0729         r = 0;
0730         break;
0731 
0732     case HIDIOCGREPORTINFO:
0733         if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
0734             r = -EFAULT;
0735             break;
0736         }
0737 
0738         report = hiddev_lookup_report(hid, &rinfo);
0739         if (report == NULL)
0740             break;
0741 
0742         rinfo.num_fields = report->maxfield;
0743 
0744         r = copy_to_user(user_arg, &rinfo, sizeof(rinfo)) ?
0745             -EFAULT : 0;
0746         break;
0747 
0748     case HIDIOCGFIELDINFO:
0749         if (copy_from_user(&finfo, user_arg, sizeof(finfo))) {
0750             r = -EFAULT;
0751             break;
0752         }
0753 
0754         rinfo.report_type = finfo.report_type;
0755         rinfo.report_id = finfo.report_id;
0756 
0757         report = hiddev_lookup_report(hid, &rinfo);
0758         if (report == NULL)
0759             break;
0760 
0761         if (finfo.field_index >= report->maxfield)
0762             break;
0763         finfo.field_index = array_index_nospec(finfo.field_index,
0764                                report->maxfield);
0765 
0766         field = report->field[finfo.field_index];
0767         memset(&finfo, 0, sizeof(finfo));
0768         finfo.report_type = rinfo.report_type;
0769         finfo.report_id = rinfo.report_id;
0770         finfo.field_index = field->report_count - 1;
0771         finfo.maxusage = field->maxusage;
0772         finfo.flags = field->flags;
0773         finfo.physical = field->physical;
0774         finfo.logical = field->logical;
0775         finfo.application = field->application;
0776         finfo.logical_minimum = field->logical_minimum;
0777         finfo.logical_maximum = field->logical_maximum;
0778         finfo.physical_minimum = field->physical_minimum;
0779         finfo.physical_maximum = field->physical_maximum;
0780         finfo.unit_exponent = field->unit_exponent;
0781         finfo.unit = field->unit;
0782 
0783         r = copy_to_user(user_arg, &finfo, sizeof(finfo)) ?
0784             -EFAULT : 0;
0785         break;
0786 
0787     case HIDIOCGUCODE:
0788     case HIDIOCGUSAGE:
0789     case HIDIOCSUSAGE:
0790     case HIDIOCGUSAGES:
0791     case HIDIOCSUSAGES:
0792     case HIDIOCGCOLLECTIONINDEX:
0793         if (!hiddev->initialized) {
0794             usbhid_init_reports(hid);
0795             hiddev->initialized = true;
0796         }
0797         r = hiddev_ioctl_usage(hiddev, cmd, user_arg);
0798         break;
0799 
0800     case HIDIOCGCOLLECTIONINFO:
0801         if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) {
0802             r = -EFAULT;
0803             break;
0804         }
0805 
0806         if (cinfo.index >= hid->maxcollection)
0807             break;
0808         cinfo.index = array_index_nospec(cinfo.index,
0809                          hid->maxcollection);
0810 
0811         cinfo.type = hid->collection[cinfo.index].type;
0812         cinfo.usage = hid->collection[cinfo.index].usage;
0813         cinfo.level = hid->collection[cinfo.index].level;
0814 
0815         r = copy_to_user(user_arg, &cinfo, sizeof(cinfo)) ?
0816             -EFAULT : 0;
0817         break;
0818 
0819     default:
0820         if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
0821             break;
0822 
0823         if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
0824             int len = strlen(hid->name) + 1;
0825             if (len > _IOC_SIZE(cmd))
0826                  len = _IOC_SIZE(cmd);
0827             r = copy_to_user(user_arg, hid->name, len) ?
0828                 -EFAULT : len;
0829             break;
0830         }
0831 
0832         if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) {
0833             int len = strlen(hid->phys) + 1;
0834             if (len > _IOC_SIZE(cmd))
0835                 len = _IOC_SIZE(cmd);
0836             r = copy_to_user(user_arg, hid->phys, len) ?
0837                 -EFAULT : len;
0838             break;
0839         }
0840     }
0841 
0842 ret_unlock:
0843     mutex_unlock(&hiddev->existancelock);
0844     return r;
0845 }
0846 
0847 static const struct file_operations hiddev_fops = {
0848     .owner =    THIS_MODULE,
0849     .read =     hiddev_read,
0850     .write =    hiddev_write,
0851     .poll =     hiddev_poll,
0852     .open =     hiddev_open,
0853     .release =  hiddev_release,
0854     .unlocked_ioctl =   hiddev_ioctl,
0855     .fasync =   hiddev_fasync,
0856     .compat_ioctl   = compat_ptr_ioctl,
0857     .llseek     = noop_llseek,
0858 };
0859 
0860 static char *hiddev_devnode(struct device *dev, umode_t *mode)
0861 {
0862     return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
0863 }
0864 
0865 static struct usb_class_driver hiddev_class = {
0866     .name =     "hiddev%d",
0867     .devnode =  hiddev_devnode,
0868     .fops =     &hiddev_fops,
0869     .minor_base =   HIDDEV_MINOR_BASE,
0870 };
0871 
0872 /*
0873  * This is where hid.c calls us to connect a hid device to the hiddev driver
0874  */
0875 int hiddev_connect(struct hid_device *hid, unsigned int force)
0876 {
0877     struct hiddev *hiddev;
0878     struct usbhid_device *usbhid = hid->driver_data;
0879     int retval;
0880 
0881     if (!force) {
0882         unsigned int i;
0883         for (i = 0; i < hid->maxcollection; i++)
0884             if (hid->collection[i].type ==
0885                 HID_COLLECTION_APPLICATION &&
0886                 !IS_INPUT_APPLICATION(hid->collection[i].usage))
0887                 break;
0888 
0889         if (i == hid->maxcollection)
0890             return -EINVAL;
0891     }
0892 
0893     if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
0894         return -ENOMEM;
0895 
0896     init_waitqueue_head(&hiddev->wait);
0897     INIT_LIST_HEAD(&hiddev->list);
0898     spin_lock_init(&hiddev->list_lock);
0899     mutex_init(&hiddev->existancelock);
0900     hid->hiddev = hiddev;
0901     hiddev->hid = hid;
0902     hiddev->exist = 1;
0903     retval = usb_register_dev(usbhid->intf, &hiddev_class);
0904     if (retval) {
0905         hid_err(hid, "Not able to get a minor for this device\n");
0906         hid->hiddev = NULL;
0907         kfree(hiddev);
0908         return retval;
0909     }
0910 
0911     /*
0912      * If HID_QUIRK_NO_INIT_REPORTS is set, make sure we don't initialize
0913      * the reports.
0914      */
0915     hiddev->initialized = hid->quirks & HID_QUIRK_NO_INIT_REPORTS;
0916 
0917     hiddev->minor = usbhid->intf->minor;
0918 
0919     return 0;
0920 }
0921 
0922 /*
0923  * This is where hid.c calls us to disconnect a hiddev device from the
0924  * corresponding hid device (usually because the usb device has disconnected)
0925  */
0926 static struct usb_class_driver hiddev_class;
0927 void hiddev_disconnect(struct hid_device *hid)
0928 {
0929     struct hiddev *hiddev = hid->hiddev;
0930     struct usbhid_device *usbhid = hid->driver_data;
0931 
0932     usb_deregister_dev(usbhid->intf, &hiddev_class);
0933 
0934     mutex_lock(&hiddev->existancelock);
0935     hiddev->exist = 0;
0936 
0937     if (hiddev->open) {
0938         hid_hw_close(hiddev->hid);
0939         wake_up_interruptible(&hiddev->wait);
0940         mutex_unlock(&hiddev->existancelock);
0941     } else {
0942         mutex_unlock(&hiddev->existancelock);
0943         kfree(hiddev);
0944     }
0945 }