linux/drivers/hid/usbhid/hiddev.c
<<
>>
Prefs
   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
  38struct 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 */
  55static struct hid_report *
  56hiddev_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 */
 108static struct hid_field *
 109hiddev_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
 140static 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 */
 166void 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}
 184EXPORT_SYMBOL_GPL(hiddev_hid_event);
 185
 186void 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 */
 205static 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 */
 216static 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/*
 245 * open file op
 246 */
 247static int hiddev_open(struct inode *inode, struct file *file)
 248{
 249        struct hiddev_list *list;
 250        struct usb_interface *intf;
 251        struct hid_device *hid;
 252        struct hiddev *hiddev;
 253        int res;
 254
 255        intf = usbhid_find_interface(iminor(inode));
 256        if (!intf)
 257                return -ENODEV;
 258        hid = usb_get_intfdata(intf);
 259        hiddev = hid->hiddev;
 260
 261        if (!(list = vzalloc(sizeof(struct hiddev_list))))
 262                return -ENOMEM;
 263        mutex_init(&list->thread_lock);
 264        list->hiddev = hiddev;
 265        file->private_data = list;
 266
 267        /*
 268         * no need for locking because the USB major number
 269         * is shared which usbcore guards against disconnect
 270         */
 271        if (list->hiddev->exist) {
 272                if (!list->hiddev->open++) {
 273                        res = hid_hw_open(hiddev->hid);
 274                        if (res < 0)
 275                                goto bail;
 276                }
 277        } else {
 278                res = -ENODEV;
 279                goto bail;
 280        }
 281
 282        spin_lock_irq(&list->hiddev->list_lock);
 283        list_add_tail(&list->node, &hiddev->list);
 284        spin_unlock_irq(&list->hiddev->list_lock);
 285
 286        mutex_lock(&hiddev->existancelock);
 287        /*
 288         * recheck exist with existance lock held to
 289         * avoid opening a disconnected device
 290         */
 291        if (!list->hiddev->exist) {
 292                res = -ENODEV;
 293                goto bail_unlock;
 294        }
 295        if (!list->hiddev->open++)
 296                if (list->hiddev->exist) {
 297                        struct hid_device *hid = hiddev->hid;
 298                        res = hid_hw_power(hid, PM_HINT_FULLON);
 299                        if (res < 0)
 300                                goto bail_unlock;
 301                        res = hid_hw_open(hid);
 302                        if (res < 0)
 303                                goto bail_normal_power;
 304                }
 305        mutex_unlock(&hiddev->existancelock);
 306        return 0;
 307bail_normal_power:
 308        hid_hw_power(hid, PM_HINT_NORMAL);
 309bail_unlock:
 310        mutex_unlock(&hiddev->existancelock);
 311
 312        spin_lock_irq(&list->hiddev->list_lock);
 313        list_del(&list->node);
 314        spin_unlock_irq(&list->hiddev->list_lock);
 315bail:
 316        file->private_data = NULL;
 317        vfree(list);
 318        return res;
 319}
 320
 321/*
 322 * "write" file op
 323 */
 324static ssize_t hiddev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
 325{
 326        return -EINVAL;
 327}
 328
 329/*
 330 * "read" file op
 331 */
 332static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
 333{
 334        DEFINE_WAIT(wait);
 335        struct hiddev_list *list = file->private_data;
 336        int event_size;
 337        int retval;
 338
 339        event_size = ((list->flags & HIDDEV_FLAG_UREF) != 0) ?
 340                sizeof(struct hiddev_usage_ref) : sizeof(struct hiddev_event);
 341
 342        if (count < event_size)
 343                return 0;
 344
 345        /* lock against other threads */
 346        retval = mutex_lock_interruptible(&list->thread_lock);
 347        if (retval)
 348                return -ERESTARTSYS;
 349
 350        while (retval == 0) {
 351                if (list->head == list->tail) {
 352                        prepare_to_wait(&list->hiddev->wait, &wait, TASK_INTERRUPTIBLE);
 353
 354                        while (list->head == list->tail) {
 355                                if (signal_pending(current)) {
 356                                        retval = -ERESTARTSYS;
 357                                        break;
 358                                }
 359                                if (!list->hiddev->exist) {
 360                                        retval = -EIO;
 361                                        break;
 362                                }
 363                                if (file->f_flags & O_NONBLOCK) {
 364                                        retval = -EAGAIN;
 365                                        break;
 366                                }
 367
 368                                /* let O_NONBLOCK tasks run */
 369                                mutex_unlock(&list->thread_lock);
 370                                schedule();
 371                                if (mutex_lock_interruptible(&list->thread_lock)) {
 372                                        finish_wait(&list->hiddev->wait, &wait);
 373                                        return -EINTR;
 374                                }
 375                                set_current_state(TASK_INTERRUPTIBLE);
 376                        }
 377                        finish_wait(&list->hiddev->wait, &wait);
 378
 379                }
 380
 381                if (retval) {
 382                        mutex_unlock(&list->thread_lock);
 383                        return retval;
 384                }
 385
 386
 387                while (list->head != list->tail &&
 388                       retval + event_size <= count) {
 389                        if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
 390                                if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE) {
 391                                        struct hiddev_event event;
 392
 393                                        event.hid = list->buffer[list->tail].usage_code;
 394                                        event.value = list->buffer[list->tail].value;
 395                                        if (copy_to_user(buffer + retval, &event, sizeof(struct hiddev_event))) {
 396                                                mutex_unlock(&list->thread_lock);
 397                                                return -EFAULT;
 398                                        }
 399                                        retval += sizeof(struct hiddev_event);
 400                                }
 401                        } else {
 402                                if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE ||
 403                                    (list->flags & HIDDEV_FLAG_REPORT) != 0) {
 404
 405                                        if (copy_to_user(buffer + retval, list->buffer + list->tail, sizeof(struct hiddev_usage_ref))) {
 406                                                mutex_unlock(&list->thread_lock);
 407                                                return -EFAULT;
 408                                        }
 409                                        retval += sizeof(struct hiddev_usage_ref);
 410                                }
 411                        }
 412                        list->tail = (list->tail + 1) & (HIDDEV_BUFFER_SIZE - 1);
 413                }
 414
 415        }
 416        mutex_unlock(&list->thread_lock);
 417
 418        return retval;
 419}
 420
 421/*
 422 * "poll" file op
 423 * No kernel lock - fine
 424 */
 425static __poll_t hiddev_poll(struct file *file, poll_table *wait)
 426{
 427        struct hiddev_list *list = file->private_data;
 428
 429        poll_wait(file, &list->hiddev->wait, wait);
 430        if (list->head != list->tail)
 431                return EPOLLIN | EPOLLRDNORM;
 432        if (!list->hiddev->exist)
 433                return EPOLLERR | EPOLLHUP;
 434        return 0;
 435}
 436
 437/*
 438 * "ioctl" file op
 439 */
 440static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
 441{
 442        struct hid_device *hid = hiddev->hid;
 443        struct hiddev_report_info rinfo;
 444        struct hiddev_usage_ref_multi *uref_multi = NULL;
 445        struct hiddev_usage_ref *uref;
 446        struct hid_report *report;
 447        struct hid_field *field;
 448        int i;
 449
 450        uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
 451        if (!uref_multi)
 452                return -ENOMEM;
 453        uref = &uref_multi->uref;
 454        if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
 455                if (copy_from_user(uref_multi, user_arg,
 456                                   sizeof(*uref_multi)))
 457                        goto fault;
 458        } else {
 459                if (copy_from_user(uref, user_arg, sizeof(*uref)))
 460                        goto fault;
 461        }
 462
 463        switch (cmd) {
 464        case HIDIOCGUCODE:
 465                rinfo.report_type = uref->report_type;
 466                rinfo.report_id = uref->report_id;
 467                if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
 468                        goto inval;
 469
 470                if (uref->field_index >= report->maxfield)
 471                        goto inval;
 472                uref->field_index = array_index_nospec(uref->field_index,
 473                                                       report->maxfield);
 474
 475                field = report->field[uref->field_index];
 476                if (uref->usage_index >= field->maxusage)
 477                        goto inval;
 478                uref->usage_index = array_index_nospec(uref->usage_index,
 479                                                       field->maxusage);
 480
 481                uref->usage_code = field->usage[uref->usage_index].hid;
 482
 483                if (copy_to_user(user_arg, uref, sizeof(*uref)))
 484                        goto fault;
 485
 486                goto goodreturn;
 487
 488        default:
 489                if (cmd != HIDIOCGUSAGE &&
 490                    cmd != HIDIOCGUSAGES &&
 491                    uref->report_type == HID_REPORT_TYPE_INPUT)
 492                        goto inval;
 493
 494                if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
 495                        field = hiddev_lookup_usage(hid, uref);
 496                        if (field == NULL)
 497                                goto inval;
 498                } else {
 499                        rinfo.report_type = uref->report_type;
 500                        rinfo.report_id = uref->report_id;
 501                        if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
 502                                goto inval;
 503
 504                        if (uref->field_index >= report->maxfield)
 505                                goto inval;
 506                        uref->field_index = array_index_nospec(uref->field_index,
 507                                                               report->maxfield);
 508
 509                        field = report->field[uref->field_index];
 510
 511                        if (cmd == HIDIOCGCOLLECTIONINDEX) {
 512                                if (uref->usage_index >= field->maxusage)
 513                                        goto inval;
 514                                uref->usage_index =
 515                                        array_index_nospec(uref->usage_index,
 516                                                           field->maxusage);
 517                        } else if (uref->usage_index >= field->report_count)
 518                                goto inval;
 519                }
 520
 521                if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
 522                        if (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
 523                            uref->usage_index + uref_multi->num_values >
 524                            field->report_count)
 525                                goto inval;
 526
 527                        uref->usage_index =
 528                                array_index_nospec(uref->usage_index,
 529                                                   field->report_count -
 530                                                   uref_multi->num_values);
 531                }
 532
 533                switch (cmd) {
 534                case HIDIOCGUSAGE:
 535                        uref->value = field->value[uref->usage_index];
 536                        if (copy_to_user(user_arg, uref, sizeof(*uref)))
 537                                goto fault;
 538                        goto goodreturn;
 539
 540                case HIDIOCSUSAGE:
 541                        field->value[uref->usage_index] = uref->value;
 542                        goto goodreturn;
 543
 544                case HIDIOCGCOLLECTIONINDEX:
 545                        i = field->usage[uref->usage_index].collection_index;
 546                        kfree(uref_multi);
 547                        return i;
 548                case HIDIOCGUSAGES:
 549                        for (i = 0; i < uref_multi->num_values; i++)
 550                                uref_multi->values[i] =
 551                                    field->value[uref->usage_index + i];
 552                        if (copy_to_user(user_arg, uref_multi,
 553                                         sizeof(*uref_multi)))
 554                                goto fault;
 555                        goto goodreturn;
 556                case HIDIOCSUSAGES:
 557                        for (i = 0; i < uref_multi->num_values; i++)
 558                                field->value[uref->usage_index + i] =
 559                                    uref_multi->values[i];
 560                        goto goodreturn;
 561                }
 562
 563goodreturn:
 564                kfree(uref_multi);
 565                return 0;
 566fault:
 567                kfree(uref_multi);
 568                return -EFAULT;
 569inval:
 570                kfree(uref_multi);
 571                return -EINVAL;
 572        }
 573}
 574
 575static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
 576{
 577        struct hid_device *hid = hiddev->hid;
 578        struct usb_device *dev = hid_to_usb_dev(hid);
 579        int idx, len;
 580        char *buf;
 581
 582        if (get_user(idx, (int __user *)user_arg))
 583                return -EFAULT;
 584
 585        if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
 586                return -ENOMEM;
 587
 588        if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
 589                kfree(buf);
 590                return -EINVAL;
 591        }
 592
 593        if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
 594                kfree(buf);
 595                return -EFAULT;
 596        }
 597
 598        kfree(buf);
 599
 600        return len;
 601}
 602
 603static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 604{
 605        struct hiddev_list *list = file->private_data;
 606        struct hiddev *hiddev = list->hiddev;
 607        struct hid_device *hid;
 608        struct hiddev_collection_info cinfo;
 609        struct hiddev_report_info rinfo;
 610        struct hiddev_field_info finfo;
 611        struct hiddev_devinfo dinfo;
 612        struct hid_report *report;
 613        struct hid_field *field;
 614        void __user *user_arg = (void __user *)arg;
 615        int i, r = -EINVAL;
 616
 617        /* Called without BKL by compat methods so no BKL taken */
 618
 619        mutex_lock(&hiddev->existancelock);
 620        if (!hiddev->exist) {
 621                r = -ENODEV;
 622                goto ret_unlock;
 623        }
 624
 625        hid = hiddev->hid;
 626
 627        switch (cmd) {
 628
 629        case HIDIOCGVERSION:
 630                r = put_user(HID_VERSION, (int __user *)arg) ?
 631                        -EFAULT : 0;
 632                break;
 633
 634        case HIDIOCAPPLICATION:
 635                if (arg >= hid->maxapplication)
 636                        break;
 637
 638                for (i = 0; i < hid->maxcollection; i++)
 639                        if (hid->collection[i].type ==
 640                            HID_COLLECTION_APPLICATION && arg-- == 0)
 641                                break;
 642
 643                if (i < hid->maxcollection)
 644                        r = hid->collection[i].usage;
 645                break;
 646
 647        case HIDIOCGDEVINFO:
 648                {
 649                        struct usb_device *dev = hid_to_usb_dev(hid);
 650                        struct usbhid_device *usbhid = hid->driver_data;
 651
 652                        memset(&dinfo, 0, sizeof(dinfo));
 653
 654                        dinfo.bustype = BUS_USB;
 655                        dinfo.busnum = dev->bus->busnum;
 656                        dinfo.devnum = dev->devnum;
 657                        dinfo.ifnum = usbhid->ifnum;
 658                        dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
 659                        dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
 660                        dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
 661                        dinfo.num_applications = hid->maxapplication;
 662
 663                        r = copy_to_user(user_arg, &dinfo, sizeof(dinfo)) ?
 664                                -EFAULT : 0;
 665                        break;
 666                }
 667
 668        case HIDIOCGFLAG:
 669                r = put_user(list->flags, (int __user *)arg) ?
 670                        -EFAULT : 0;
 671                break;
 672
 673        case HIDIOCSFLAG:
 674                {
 675                        int newflags;
 676
 677                        if (get_user(newflags, (int __user *)arg)) {
 678                                r = -EFAULT;
 679                                break;
 680                        }
 681
 682                        if ((newflags & ~HIDDEV_FLAGS) != 0 ||
 683                            ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
 684                             (newflags & HIDDEV_FLAG_UREF) == 0))
 685                                break;
 686
 687                        list->flags = newflags;
 688
 689                        r = 0;
 690                        break;
 691                }
 692
 693        case HIDIOCGSTRING:
 694                r = hiddev_ioctl_string(hiddev, cmd, user_arg);
 695                break;
 696
 697        case HIDIOCINITREPORT:
 698                usbhid_init_reports(hid);
 699                hiddev->initialized = true;
 700                r = 0;
 701                break;
 702
 703        case HIDIOCGREPORT:
 704                if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
 705                        r = -EFAULT;
 706                        break;
 707                }
 708
 709                if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
 710                        break;
 711
 712                report = hiddev_lookup_report(hid, &rinfo);
 713                if (report == NULL)
 714                        break;
 715
 716                hid_hw_request(hid, report, HID_REQ_GET_REPORT);
 717                hid_hw_wait(hid);
 718
 719                r = 0;
 720                break;
 721
 722        case HIDIOCSREPORT:
 723                if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
 724                        r = -EFAULT;
 725                        break;
 726                }
 727
 728                if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
 729                        break;
 730
 731                report = hiddev_lookup_report(hid, &rinfo);
 732                if (report == NULL)
 733                        break;
 734
 735                hid_hw_request(hid, report, HID_REQ_SET_REPORT);
 736                hid_hw_wait(hid);
 737
 738                r = 0;
 739                break;
 740
 741        case HIDIOCGREPORTINFO:
 742                if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
 743                        r = -EFAULT;
 744                        break;
 745                }
 746
 747                report = hiddev_lookup_report(hid, &rinfo);
 748                if (report == NULL)
 749                        break;
 750
 751                rinfo.num_fields = report->maxfield;
 752
 753                r = copy_to_user(user_arg, &rinfo, sizeof(rinfo)) ?
 754                        -EFAULT : 0;
 755                break;
 756
 757        case HIDIOCGFIELDINFO:
 758                if (copy_from_user(&finfo, user_arg, sizeof(finfo))) {
 759                        r = -EFAULT;
 760                        break;
 761                }
 762
 763                rinfo.report_type = finfo.report_type;
 764                rinfo.report_id = finfo.report_id;
 765
 766                report = hiddev_lookup_report(hid, &rinfo);
 767                if (report == NULL)
 768                        break;
 769
 770                if (finfo.field_index >= report->maxfield)
 771                        break;
 772                finfo.field_index = array_index_nospec(finfo.field_index,
 773                                                       report->maxfield);
 774
 775                field = report->field[finfo.field_index];
 776                memset(&finfo, 0, sizeof(finfo));
 777                finfo.report_type = rinfo.report_type;
 778                finfo.report_id = rinfo.report_id;
 779                finfo.field_index = field->report_count - 1;
 780                finfo.maxusage = field->maxusage;
 781                finfo.flags = field->flags;
 782                finfo.physical = field->physical;
 783                finfo.logical = field->logical;
 784                finfo.application = field->application;
 785                finfo.logical_minimum = field->logical_minimum;
 786                finfo.logical_maximum = field->logical_maximum;
 787                finfo.physical_minimum = field->physical_minimum;
 788                finfo.physical_maximum = field->physical_maximum;
 789                finfo.unit_exponent = field->unit_exponent;
 790                finfo.unit = field->unit;
 791
 792                r = copy_to_user(user_arg, &finfo, sizeof(finfo)) ?
 793                        -EFAULT : 0;
 794                break;
 795
 796        case HIDIOCGUCODE:
 797                /* fall through */
 798        case HIDIOCGUSAGE:
 799        case HIDIOCSUSAGE:
 800        case HIDIOCGUSAGES:
 801        case HIDIOCSUSAGES:
 802        case HIDIOCGCOLLECTIONINDEX:
 803                if (!hiddev->initialized) {
 804                        usbhid_init_reports(hid);
 805                        hiddev->initialized = true;
 806                }
 807                r = hiddev_ioctl_usage(hiddev, cmd, user_arg);
 808                break;
 809
 810        case HIDIOCGCOLLECTIONINFO:
 811                if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) {
 812                        r = -EFAULT;
 813                        break;
 814                }
 815
 816                if (cinfo.index >= hid->maxcollection)
 817                        break;
 818                cinfo.index = array_index_nospec(cinfo.index,
 819                                                 hid->maxcollection);
 820
 821                cinfo.type = hid->collection[cinfo.index].type;
 822                cinfo.usage = hid->collection[cinfo.index].usage;
 823                cinfo.level = hid->collection[cinfo.index].level;
 824
 825                r = copy_to_user(user_arg, &cinfo, sizeof(cinfo)) ?
 826                        -EFAULT : 0;
 827                break;
 828
 829        default:
 830                if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
 831                        break;
 832
 833                if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
 834                        int len = strlen(hid->name) + 1;
 835                        if (len > _IOC_SIZE(cmd))
 836                                 len = _IOC_SIZE(cmd);
 837                        r = copy_to_user(user_arg, hid->name, len) ?
 838                                -EFAULT : len;
 839                        break;
 840                }
 841
 842                if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) {
 843                        int len = strlen(hid->phys) + 1;
 844                        if (len > _IOC_SIZE(cmd))
 845                                len = _IOC_SIZE(cmd);
 846                        r = copy_to_user(user_arg, hid->phys, len) ?
 847                                -EFAULT : len;
 848                        break;
 849                }
 850        }
 851
 852ret_unlock:
 853        mutex_unlock(&hiddev->existancelock);
 854        return r;
 855}
 856
 857#ifdef CONFIG_COMPAT
 858static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 859{
 860        return hiddev_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
 861}
 862#endif
 863
 864static const struct file_operations hiddev_fops = {
 865        .owner =        THIS_MODULE,
 866        .read =         hiddev_read,
 867        .write =        hiddev_write,
 868        .poll =         hiddev_poll,
 869        .open =         hiddev_open,
 870        .release =      hiddev_release,
 871        .unlocked_ioctl =       hiddev_ioctl,
 872        .fasync =       hiddev_fasync,
 873#ifdef CONFIG_COMPAT
 874        .compat_ioctl   = hiddev_compat_ioctl,
 875#endif
 876        .llseek         = noop_llseek,
 877};
 878
 879static char *hiddev_devnode(struct device *dev, umode_t *mode)
 880{
 881        return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
 882}
 883
 884static struct usb_class_driver hiddev_class = {
 885        .name =         "hiddev%d",
 886        .devnode =      hiddev_devnode,
 887        .fops =         &hiddev_fops,
 888        .minor_base =   HIDDEV_MINOR_BASE,
 889};
 890
 891/*
 892 * This is where hid.c calls us to connect a hid device to the hiddev driver
 893 */
 894int hiddev_connect(struct hid_device *hid, unsigned int force)
 895{
 896        struct hiddev *hiddev;
 897        struct usbhid_device *usbhid = hid->driver_data;
 898        int retval;
 899
 900        if (!force) {
 901                unsigned int i;
 902                for (i = 0; i < hid->maxcollection; i++)
 903                        if (hid->collection[i].type ==
 904                            HID_COLLECTION_APPLICATION &&
 905                            !IS_INPUT_APPLICATION(hid->collection[i].usage))
 906                                break;
 907
 908                if (i == hid->maxcollection)
 909                        return -1;
 910        }
 911
 912        if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
 913                return -1;
 914
 915        init_waitqueue_head(&hiddev->wait);
 916        INIT_LIST_HEAD(&hiddev->list);
 917        spin_lock_init(&hiddev->list_lock);
 918        mutex_init(&hiddev->existancelock);
 919        hid->hiddev = hiddev;
 920        hiddev->hid = hid;
 921        hiddev->exist = 1;
 922        retval = usb_register_dev(usbhid->intf, &hiddev_class);
 923        if (retval) {
 924                hid_err(hid, "Not able to get a minor for this device\n");
 925                hid->hiddev = NULL;
 926                kfree(hiddev);
 927                return -1;
 928        }
 929
 930        /*
 931         * If HID_QUIRK_NO_INIT_REPORTS is set, make sure we don't initialize
 932         * the reports.
 933         */
 934        hiddev->initialized = hid->quirks & HID_QUIRK_NO_INIT_REPORTS;
 935
 936        hiddev->minor = usbhid->intf->minor;
 937
 938        return 0;
 939}
 940
 941/*
 942 * This is where hid.c calls us to disconnect a hiddev device from the
 943 * corresponding hid device (usually because the usb device has disconnected)
 944 */
 945static struct usb_class_driver hiddev_class;
 946void hiddev_disconnect(struct hid_device *hid)
 947{
 948        struct hiddev *hiddev = hid->hiddev;
 949        struct usbhid_device *usbhid = hid->driver_data;
 950
 951        usb_deregister_dev(usbhid->intf, &hiddev_class);
 952
 953        mutex_lock(&hiddev->existancelock);
 954        hiddev->exist = 0;
 955
 956        if (hiddev->open) {
 957                mutex_unlock(&hiddev->existancelock);
 958                hid_hw_close(hiddev->hid);
 959                wake_up_interruptible(&hiddev->wait);
 960        } else {
 961                mutex_unlock(&hiddev->existancelock);
 962                kfree(hiddev);
 963        }
 964}
 965