linux/drivers/hid/uhid.c
<<
>>
Prefs
   1/*
   2 * User-space I/O driver support for HID subsystem
   3 * Copyright (c) 2012 David Herrmann
   4 */
   5
   6/*
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License as published by the Free
   9 * Software Foundation; either version 2 of the License, or (at your option)
  10 * any later version.
  11 */
  12
  13#include <linux/atomic.h>
  14#include <linux/compat.h>
  15#include <linux/device.h>
  16#include <linux/fs.h>
  17#include <linux/hid.h>
  18#include <linux/input.h>
  19#include <linux/miscdevice.h>
  20#include <linux/module.h>
  21#include <linux/mutex.h>
  22#include <linux/poll.h>
  23#include <linux/sched.h>
  24#include <linux/spinlock.h>
  25#include <linux/uhid.h>
  26#include <linux/wait.h>
  27
  28#define UHID_NAME       "uhid"
  29#define UHID_BUFSIZE    32
  30
  31struct uhid_device {
  32        struct mutex devlock;
  33        bool running;
  34
  35        __u8 *rd_data;
  36        uint rd_size;
  37
  38        struct hid_device *hid;
  39        struct uhid_event input_buf;
  40
  41        wait_queue_head_t waitq;
  42        spinlock_t qlock;
  43        __u8 head;
  44        __u8 tail;
  45        struct uhid_event *outq[UHID_BUFSIZE];
  46
  47        struct mutex report_lock;
  48        wait_queue_head_t report_wait;
  49        atomic_t report_done;
  50        atomic_t report_id;
  51        struct uhid_event report_buf;
  52};
  53
  54static struct miscdevice uhid_misc;
  55
  56static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev)
  57{
  58        __u8 newhead;
  59
  60        newhead = (uhid->head + 1) % UHID_BUFSIZE;
  61
  62        if (newhead != uhid->tail) {
  63                uhid->outq[uhid->head] = ev;
  64                uhid->head = newhead;
  65                wake_up_interruptible(&uhid->waitq);
  66        } else {
  67                hid_warn(uhid->hid, "Output queue is full\n");
  68                kfree(ev);
  69        }
  70}
  71
  72static int uhid_queue_event(struct uhid_device *uhid, __u32 event)
  73{
  74        unsigned long flags;
  75        struct uhid_event *ev;
  76
  77        ev = kzalloc(sizeof(*ev), GFP_KERNEL);
  78        if (!ev)
  79                return -ENOMEM;
  80
  81        ev->type = event;
  82
  83        spin_lock_irqsave(&uhid->qlock, flags);
  84        uhid_queue(uhid, ev);
  85        spin_unlock_irqrestore(&uhid->qlock, flags);
  86
  87        return 0;
  88}
  89
  90static int uhid_hid_start(struct hid_device *hid)
  91{
  92        struct uhid_device *uhid = hid->driver_data;
  93
  94        return uhid_queue_event(uhid, UHID_START);
  95}
  96
  97static void uhid_hid_stop(struct hid_device *hid)
  98{
  99        struct uhid_device *uhid = hid->driver_data;
 100
 101        hid->claimed = 0;
 102        uhid_queue_event(uhid, UHID_STOP);
 103}
 104
 105static int uhid_hid_open(struct hid_device *hid)
 106{
 107        struct uhid_device *uhid = hid->driver_data;
 108
 109        return uhid_queue_event(uhid, UHID_OPEN);
 110}
 111
 112static void uhid_hid_close(struct hid_device *hid)
 113{
 114        struct uhid_device *uhid = hid->driver_data;
 115
 116        uhid_queue_event(uhid, UHID_CLOSE);
 117}
 118
 119static int uhid_hid_parse(struct hid_device *hid)
 120{
 121        struct uhid_device *uhid = hid->driver_data;
 122
 123        return hid_parse_report(hid, uhid->rd_data, uhid->rd_size);
 124}
 125
 126static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum,
 127                            __u8 *buf, size_t count, unsigned char rtype)
 128{
 129        struct uhid_device *uhid = hid->driver_data;
 130        __u8 report_type;
 131        struct uhid_event *ev;
 132        unsigned long flags;
 133        int ret;
 134        size_t uninitialized_var(len);
 135        struct uhid_feature_answer_req *req;
 136
 137        if (!uhid->running)
 138                return -EIO;
 139
 140        switch (rtype) {
 141        case HID_FEATURE_REPORT:
 142                report_type = UHID_FEATURE_REPORT;
 143                break;
 144        case HID_OUTPUT_REPORT:
 145                report_type = UHID_OUTPUT_REPORT;
 146                break;
 147        case HID_INPUT_REPORT:
 148                report_type = UHID_INPUT_REPORT;
 149                break;
 150        default:
 151                return -EINVAL;
 152        }
 153
 154        ret = mutex_lock_interruptible(&uhid->report_lock);
 155        if (ret)
 156                return ret;
 157
 158        ev = kzalloc(sizeof(*ev), GFP_KERNEL);
 159        if (!ev) {
 160                ret = -ENOMEM;
 161                goto unlock;
 162        }
 163
 164        spin_lock_irqsave(&uhid->qlock, flags);
 165        ev->type = UHID_FEATURE;
 166        ev->u.feature.id = atomic_inc_return(&uhid->report_id);
 167        ev->u.feature.rnum = rnum;
 168        ev->u.feature.rtype = report_type;
 169
 170        atomic_set(&uhid->report_done, 0);
 171        uhid_queue(uhid, ev);
 172        spin_unlock_irqrestore(&uhid->qlock, flags);
 173
 174        ret = wait_event_interruptible_timeout(uhid->report_wait,
 175                                atomic_read(&uhid->report_done), 5 * HZ);
 176
 177        /*
 178         * Make sure "uhid->running" is cleared on shutdown before
 179         * "uhid->report_done" is set.
 180         */
 181        smp_rmb();
 182        if (!ret || !uhid->running) {
 183                ret = -EIO;
 184        } else if (ret < 0) {
 185                ret = -ERESTARTSYS;
 186        } else {
 187                spin_lock_irqsave(&uhid->qlock, flags);
 188                req = &uhid->report_buf.u.feature_answer;
 189
 190                if (req->err) {
 191                        ret = -EIO;
 192                } else {
 193                        ret = 0;
 194                        len = min(count,
 195                                min_t(size_t, req->size, UHID_DATA_MAX));
 196                        memcpy(buf, req->data, len);
 197                }
 198
 199                spin_unlock_irqrestore(&uhid->qlock, flags);
 200        }
 201
 202        atomic_set(&uhid->report_done, 1);
 203
 204unlock:
 205        mutex_unlock(&uhid->report_lock);
 206        return ret ? ret : len;
 207}
 208
 209static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count,
 210                               unsigned char report_type)
 211{
 212        struct uhid_device *uhid = hid->driver_data;
 213        __u8 rtype;
 214        unsigned long flags;
 215        struct uhid_event *ev;
 216
 217        switch (report_type) {
 218        case HID_FEATURE_REPORT:
 219                rtype = UHID_FEATURE_REPORT;
 220                break;
 221        case HID_OUTPUT_REPORT:
 222                rtype = UHID_OUTPUT_REPORT;
 223                break;
 224        default:
 225                return -EINVAL;
 226        }
 227
 228        if (count < 1 || count > UHID_DATA_MAX)
 229                return -EINVAL;
 230
 231        ev = kzalloc(sizeof(*ev), GFP_KERNEL);
 232        if (!ev)
 233                return -ENOMEM;
 234
 235        ev->type = UHID_OUTPUT;
 236        ev->u.output.size = count;
 237        ev->u.output.rtype = rtype;
 238        memcpy(ev->u.output.data, buf, count);
 239
 240        spin_lock_irqsave(&uhid->qlock, flags);
 241        uhid_queue(uhid, ev);
 242        spin_unlock_irqrestore(&uhid->qlock, flags);
 243
 244        return count;
 245}
 246
 247static int uhid_hid_output_report(struct hid_device *hid, __u8 *buf,
 248                                  size_t count)
 249{
 250        return uhid_hid_output_raw(hid, buf, count, HID_OUTPUT_REPORT);
 251}
 252
 253static int uhid_raw_request(struct hid_device *hid, unsigned char reportnum,
 254                            __u8 *buf, size_t len, unsigned char rtype,
 255                            int reqtype)
 256{
 257        switch (reqtype) {
 258        case HID_REQ_GET_REPORT:
 259                return uhid_hid_get_raw(hid, reportnum, buf, len, rtype);
 260        case HID_REQ_SET_REPORT:
 261                /* TODO: implement proper SET_REPORT functionality */
 262                return -ENOSYS;
 263        default:
 264                return -EIO;
 265        }
 266}
 267
 268static struct hid_ll_driver uhid_hid_driver = {
 269        .start = uhid_hid_start,
 270        .stop = uhid_hid_stop,
 271        .open = uhid_hid_open,
 272        .close = uhid_hid_close,
 273        .parse = uhid_hid_parse,
 274        .output_report = uhid_hid_output_report,
 275        .raw_request = uhid_raw_request,
 276};
 277
 278#ifdef CONFIG_COMPAT
 279
 280/* Apparently we haven't stepped on these rakes enough times yet. */
 281struct uhid_create_req_compat {
 282        __u8 name[128];
 283        __u8 phys[64];
 284        __u8 uniq[64];
 285
 286        compat_uptr_t rd_data;
 287        __u16 rd_size;
 288
 289        __u16 bus;
 290        __u32 vendor;
 291        __u32 product;
 292        __u32 version;
 293        __u32 country;
 294} __attribute__((__packed__));
 295
 296static int uhid_event_from_user(const char __user *buffer, size_t len,
 297                                struct uhid_event *event)
 298{
 299        if (is_compat_task()) {
 300                u32 type;
 301
 302                if (get_user(type, buffer))
 303                        return -EFAULT;
 304
 305                if (type == UHID_CREATE) {
 306                        /*
 307                         * This is our messed up request with compat pointer.
 308                         * It is largish (more than 256 bytes) so we better
 309                         * allocate it from the heap.
 310                         */
 311                        struct uhid_create_req_compat *compat;
 312
 313                        compat = kzalloc(sizeof(*compat), GFP_KERNEL);
 314                        if (!compat)
 315                                return -ENOMEM;
 316
 317                        buffer += sizeof(type);
 318                        len -= sizeof(type);
 319                        if (copy_from_user(compat, buffer,
 320                                           min(len, sizeof(*compat)))) {
 321                                kfree(compat);
 322                                return -EFAULT;
 323                        }
 324
 325                        /* Shuffle the data over to proper structure */
 326                        event->type = type;
 327
 328                        memcpy(event->u.create.name, compat->name,
 329                                sizeof(compat->name));
 330                        memcpy(event->u.create.phys, compat->phys,
 331                                sizeof(compat->phys));
 332                        memcpy(event->u.create.uniq, compat->uniq,
 333                                sizeof(compat->uniq));
 334
 335                        event->u.create.rd_data = compat_ptr(compat->rd_data);
 336                        event->u.create.rd_size = compat->rd_size;
 337
 338                        event->u.create.bus = compat->bus;
 339                        event->u.create.vendor = compat->vendor;
 340                        event->u.create.product = compat->product;
 341                        event->u.create.version = compat->version;
 342                        event->u.create.country = compat->country;
 343
 344                        kfree(compat);
 345                        return 0;
 346                }
 347                /* All others can be copied directly */
 348        }
 349
 350        if (copy_from_user(event, buffer, min(len, sizeof(*event))))
 351                return -EFAULT;
 352
 353        return 0;
 354}
 355#else
 356static int uhid_event_from_user(const char __user *buffer, size_t len,
 357                                struct uhid_event *event)
 358{
 359        if (copy_from_user(event, buffer, min(len, sizeof(*event))))
 360                return -EFAULT;
 361
 362        return 0;
 363}
 364#endif
 365
 366static int uhid_dev_create(struct uhid_device *uhid,
 367                           const struct uhid_event *ev)
 368{
 369        struct hid_device *hid;
 370        int ret;
 371
 372        if (uhid->running)
 373                return -EALREADY;
 374
 375        uhid->rd_size = ev->u.create.rd_size;
 376        if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE)
 377                return -EINVAL;
 378
 379        uhid->rd_data = kmalloc(uhid->rd_size, GFP_KERNEL);
 380        if (!uhid->rd_data)
 381                return -ENOMEM;
 382
 383        if (copy_from_user(uhid->rd_data, ev->u.create.rd_data,
 384                           uhid->rd_size)) {
 385                ret = -EFAULT;
 386                goto err_free;
 387        }
 388
 389        hid = hid_allocate_device();
 390        if (IS_ERR(hid)) {
 391                ret = PTR_ERR(hid);
 392                goto err_free;
 393        }
 394
 395        strncpy(hid->name, ev->u.create.name, 127);
 396        hid->name[127] = 0;
 397        strncpy(hid->phys, ev->u.create.phys, 63);
 398        hid->phys[63] = 0;
 399        strncpy(hid->uniq, ev->u.create.uniq, 63);
 400        hid->uniq[63] = 0;
 401
 402        hid->ll_driver = &uhid_hid_driver;
 403        hid->bus = ev->u.create.bus;
 404        hid->vendor = ev->u.create.vendor;
 405        hid->product = ev->u.create.product;
 406        hid->version = ev->u.create.version;
 407        hid->country = ev->u.create.country;
 408        hid->driver_data = uhid;
 409        hid->dev.parent = uhid_misc.this_device;
 410
 411        uhid->hid = hid;
 412        uhid->running = true;
 413
 414        ret = hid_add_device(hid);
 415        if (ret) {
 416                hid_err(hid, "Cannot register HID device\n");
 417                goto err_hid;
 418        }
 419
 420        return 0;
 421
 422err_hid:
 423        hid_destroy_device(hid);
 424        uhid->hid = NULL;
 425        uhid->running = false;
 426err_free:
 427        kfree(uhid->rd_data);
 428        return ret;
 429}
 430
 431static int uhid_dev_create2(struct uhid_device *uhid,
 432                            const struct uhid_event *ev)
 433{
 434        struct hid_device *hid;
 435        int ret;
 436
 437        if (uhid->running)
 438                return -EALREADY;
 439
 440        uhid->rd_size = ev->u.create2.rd_size;
 441        if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE)
 442                return -EINVAL;
 443
 444        uhid->rd_data = kmemdup(ev->u.create2.rd_data, uhid->rd_size,
 445                                GFP_KERNEL);
 446        if (!uhid->rd_data)
 447                return -ENOMEM;
 448
 449        hid = hid_allocate_device();
 450        if (IS_ERR(hid)) {
 451                ret = PTR_ERR(hid);
 452                goto err_free;
 453        }
 454
 455        strncpy(hid->name, ev->u.create2.name, 127);
 456        hid->name[127] = 0;
 457        strncpy(hid->phys, ev->u.create2.phys, 63);
 458        hid->phys[63] = 0;
 459        strncpy(hid->uniq, ev->u.create2.uniq, 63);
 460        hid->uniq[63] = 0;
 461
 462        hid->ll_driver = &uhid_hid_driver;
 463        hid->bus = ev->u.create2.bus;
 464        hid->vendor = ev->u.create2.vendor;
 465        hid->product = ev->u.create2.product;
 466        hid->version = ev->u.create2.version;
 467        hid->country = ev->u.create2.country;
 468        hid->driver_data = uhid;
 469        hid->dev.parent = uhid_misc.this_device;
 470
 471        uhid->hid = hid;
 472        uhid->running = true;
 473
 474        ret = hid_add_device(hid);
 475        if (ret) {
 476                hid_err(hid, "Cannot register HID device\n");
 477                goto err_hid;
 478        }
 479
 480        return 0;
 481
 482err_hid:
 483        hid_destroy_device(hid);
 484        uhid->hid = NULL;
 485        uhid->running = false;
 486err_free:
 487        kfree(uhid->rd_data);
 488        return ret;
 489}
 490
 491static int uhid_dev_destroy(struct uhid_device *uhid)
 492{
 493        if (!uhid->running)
 494                return -EINVAL;
 495
 496        /* clear "running" before setting "report_done" */
 497        uhid->running = false;
 498        smp_wmb();
 499        atomic_set(&uhid->report_done, 1);
 500        wake_up_interruptible(&uhid->report_wait);
 501
 502        hid_destroy_device(uhid->hid);
 503        kfree(uhid->rd_data);
 504
 505        return 0;
 506}
 507
 508static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev)
 509{
 510        if (!uhid->running)
 511                return -EINVAL;
 512
 513        hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data,
 514                         min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0);
 515
 516        return 0;
 517}
 518
 519static int uhid_dev_input2(struct uhid_device *uhid, struct uhid_event *ev)
 520{
 521        if (!uhid->running)
 522                return -EINVAL;
 523
 524        hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input2.data,
 525                         min_t(size_t, ev->u.input2.size, UHID_DATA_MAX), 0);
 526
 527        return 0;
 528}
 529
 530static int uhid_dev_feature_answer(struct uhid_device *uhid,
 531                                   struct uhid_event *ev)
 532{
 533        unsigned long flags;
 534
 535        if (!uhid->running)
 536                return -EINVAL;
 537
 538        spin_lock_irqsave(&uhid->qlock, flags);
 539
 540        /* id for old report; drop it silently */
 541        if (atomic_read(&uhid->report_id) != ev->u.feature_answer.id)
 542                goto unlock;
 543        if (atomic_read(&uhid->report_done))
 544                goto unlock;
 545
 546        memcpy(&uhid->report_buf, ev, sizeof(*ev));
 547        atomic_set(&uhid->report_done, 1);
 548        wake_up_interruptible(&uhid->report_wait);
 549
 550unlock:
 551        spin_unlock_irqrestore(&uhid->qlock, flags);
 552        return 0;
 553}
 554
 555static int uhid_char_open(struct inode *inode, struct file *file)
 556{
 557        struct uhid_device *uhid;
 558
 559        uhid = kzalloc(sizeof(*uhid), GFP_KERNEL);
 560        if (!uhid)
 561                return -ENOMEM;
 562
 563        mutex_init(&uhid->devlock);
 564        mutex_init(&uhid->report_lock);
 565        spin_lock_init(&uhid->qlock);
 566        init_waitqueue_head(&uhid->waitq);
 567        init_waitqueue_head(&uhid->report_wait);
 568        uhid->running = false;
 569        atomic_set(&uhid->report_done, 1);
 570
 571        file->private_data = uhid;
 572        nonseekable_open(inode, file);
 573
 574        return 0;
 575}
 576
 577static int uhid_char_release(struct inode *inode, struct file *file)
 578{
 579        struct uhid_device *uhid = file->private_data;
 580        unsigned int i;
 581
 582        uhid_dev_destroy(uhid);
 583
 584        for (i = 0; i < UHID_BUFSIZE; ++i)
 585                kfree(uhid->outq[i]);
 586
 587        kfree(uhid);
 588
 589        return 0;
 590}
 591
 592static ssize_t uhid_char_read(struct file *file, char __user *buffer,
 593                                size_t count, loff_t *ppos)
 594{
 595        struct uhid_device *uhid = file->private_data;
 596        int ret;
 597        unsigned long flags;
 598        size_t len;
 599
 600        /* they need at least the "type" member of uhid_event */
 601        if (count < sizeof(__u32))
 602                return -EINVAL;
 603
 604try_again:
 605        if (file->f_flags & O_NONBLOCK) {
 606                if (uhid->head == uhid->tail)
 607                        return -EAGAIN;
 608        } else {
 609                ret = wait_event_interruptible(uhid->waitq,
 610                                                uhid->head != uhid->tail);
 611                if (ret)
 612                        return ret;
 613        }
 614
 615        ret = mutex_lock_interruptible(&uhid->devlock);
 616        if (ret)
 617                return ret;
 618
 619        if (uhid->head == uhid->tail) {
 620                mutex_unlock(&uhid->devlock);
 621                goto try_again;
 622        } else {
 623                len = min(count, sizeof(**uhid->outq));
 624                if (copy_to_user(buffer, uhid->outq[uhid->tail], len)) {
 625                        ret = -EFAULT;
 626                } else {
 627                        kfree(uhid->outq[uhid->tail]);
 628                        uhid->outq[uhid->tail] = NULL;
 629
 630                        spin_lock_irqsave(&uhid->qlock, flags);
 631                        uhid->tail = (uhid->tail + 1) % UHID_BUFSIZE;
 632                        spin_unlock_irqrestore(&uhid->qlock, flags);
 633                }
 634        }
 635
 636        mutex_unlock(&uhid->devlock);
 637        return ret ? ret : len;
 638}
 639
 640static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
 641                                size_t count, loff_t *ppos)
 642{
 643        struct uhid_device *uhid = file->private_data;
 644        int ret;
 645        size_t len;
 646
 647        /* we need at least the "type" member of uhid_event */
 648        if (count < sizeof(__u32))
 649                return -EINVAL;
 650
 651        ret = mutex_lock_interruptible(&uhid->devlock);
 652        if (ret)
 653                return ret;
 654
 655        memset(&uhid->input_buf, 0, sizeof(uhid->input_buf));
 656        len = min(count, sizeof(uhid->input_buf));
 657
 658        ret = uhid_event_from_user(buffer, len, &uhid->input_buf);
 659        if (ret)
 660                goto unlock;
 661
 662        switch (uhid->input_buf.type) {
 663        case UHID_CREATE:
 664                ret = uhid_dev_create(uhid, &uhid->input_buf);
 665                break;
 666        case UHID_CREATE2:
 667                ret = uhid_dev_create2(uhid, &uhid->input_buf);
 668                break;
 669        case UHID_DESTROY:
 670                ret = uhid_dev_destroy(uhid);
 671                break;
 672        case UHID_INPUT:
 673                ret = uhid_dev_input(uhid, &uhid->input_buf);
 674                break;
 675        case UHID_INPUT2:
 676                ret = uhid_dev_input2(uhid, &uhid->input_buf);
 677                break;
 678        case UHID_FEATURE_ANSWER:
 679                ret = uhid_dev_feature_answer(uhid, &uhid->input_buf);
 680                break;
 681        default:
 682                ret = -EOPNOTSUPP;
 683        }
 684
 685unlock:
 686        mutex_unlock(&uhid->devlock);
 687
 688        /* return "count" not "len" to not confuse the caller */
 689        return ret ? ret : count;
 690}
 691
 692static unsigned int uhid_char_poll(struct file *file, poll_table *wait)
 693{
 694        struct uhid_device *uhid = file->private_data;
 695
 696        poll_wait(file, &uhid->waitq, wait);
 697
 698        if (uhid->head != uhid->tail)
 699                return POLLIN | POLLRDNORM;
 700
 701        return 0;
 702}
 703
 704static const struct file_operations uhid_fops = {
 705        .owner          = THIS_MODULE,
 706        .open           = uhid_char_open,
 707        .release        = uhid_char_release,
 708        .read           = uhid_char_read,
 709        .write          = uhid_char_write,
 710        .poll           = uhid_char_poll,
 711        .llseek         = no_llseek,
 712};
 713
 714static struct miscdevice uhid_misc = {
 715        .fops           = &uhid_fops,
 716        .minor          = UHID_MINOR,
 717        .name           = UHID_NAME,
 718};
 719
 720static int __init uhid_init(void)
 721{
 722        return misc_register(&uhid_misc);
 723}
 724
 725static void __exit uhid_exit(void)
 726{
 727        misc_deregister(&uhid_misc);
 728}
 729
 730module_init(uhid_init);
 731module_exit(uhid_exit);
 732MODULE_LICENSE("GPL");
 733MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
 734MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem");
 735MODULE_ALIAS_MISCDEV(UHID_MINOR);
 736MODULE_ALIAS("devname:" UHID_NAME);
 737