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