root/drivers/hid/usbhid/hiddev.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hiddev_lookup_report
  2. hiddev_lookup_usage
  3. hiddev_send_event
  4. hiddev_hid_event
  5. hiddev_report_event
  6. hiddev_fasync
  7. hiddev_release
  8. __hiddev_open
  9. hiddev_open
  10. hiddev_write
  11. hiddev_read
  12. hiddev_poll
  13. hiddev_ioctl_usage
  14. hiddev_ioctl_string
  15. hiddev_ioctl
  16. hiddev_compat_ioctl
  17. hiddev_devnode
  18. hiddev_connect
  19. hiddev_disconnect

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

/* [<][>][^][v][top][bottom][index][help] */