linux/drivers/usb/gadget/f_hid.c
<<
>>
Prefs
   1/*
   2 * f_hid.c -- USB HID function driver
   3 *
   4 * Copyright (C) 2010 Fabien Chouteau <fabien.chouteau@barco.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/hid.h>
  15#include <linux/cdev.h>
  16#include <linux/mutex.h>
  17#include <linux/poll.h>
  18#include <linux/uaccess.h>
  19#include <linux/wait.h>
  20#include <linux/sched.h>
  21#include <linux/usb/g_hid.h>
  22
  23static int major, minors;
  24static struct class *hidg_class;
  25
  26/*-------------------------------------------------------------------------*/
  27/*                            HID gadget struct                            */
  28
  29struct f_hidg_req_list {
  30        struct usb_request      *req;
  31        unsigned int            pos;
  32        struct list_head        list;
  33};
  34
  35struct f_hidg {
  36        /* configuration */
  37        unsigned char                   bInterfaceSubClass;
  38        unsigned char                   bInterfaceProtocol;
  39        unsigned short                  report_desc_length;
  40        char                            *report_desc;
  41        unsigned short                  report_length;
  42
  43        /* recv report */
  44        struct list_head                completed_out_req;
  45        spinlock_t                      spinlock;
  46        wait_queue_head_t               read_queue;
  47        unsigned int                    qlen;
  48
  49        /* send report */
  50        struct mutex                    lock;
  51        bool                            write_pending;
  52        wait_queue_head_t               write_queue;
  53        struct usb_request              *req;
  54
  55        int                             minor;
  56        struct cdev                     cdev;
  57        struct usb_function             func;
  58
  59        struct usb_ep                   *in_ep;
  60        struct usb_ep                   *out_ep;
  61};
  62
  63static inline struct f_hidg *func_to_hidg(struct usb_function *f)
  64{
  65        return container_of(f, struct f_hidg, func);
  66}
  67
  68/*-------------------------------------------------------------------------*/
  69/*                           Static descriptors                            */
  70
  71static struct usb_interface_descriptor hidg_interface_desc = {
  72        .bLength                = sizeof hidg_interface_desc,
  73        .bDescriptorType        = USB_DT_INTERFACE,
  74        /* .bInterfaceNumber    = DYNAMIC */
  75        .bAlternateSetting      = 0,
  76        .bNumEndpoints          = 2,
  77        .bInterfaceClass        = USB_CLASS_HID,
  78        /* .bInterfaceSubClass  = DYNAMIC */
  79        /* .bInterfaceProtocol  = DYNAMIC */
  80        /* .iInterface          = DYNAMIC */
  81};
  82
  83static struct hid_descriptor hidg_desc = {
  84        .bLength                        = sizeof hidg_desc,
  85        .bDescriptorType                = HID_DT_HID,
  86        .bcdHID                         = 0x0101,
  87        .bCountryCode                   = 0x00,
  88        .bNumDescriptors                = 0x1,
  89        /*.desc[0].bDescriptorType      = DYNAMIC */
  90        /*.desc[0].wDescriptorLenght    = DYNAMIC */
  91};
  92
  93/* High-Speed Support */
  94
  95static struct usb_endpoint_descriptor hidg_hs_in_ep_desc = {
  96        .bLength                = USB_DT_ENDPOINT_SIZE,
  97        .bDescriptorType        = USB_DT_ENDPOINT,
  98        .bEndpointAddress       = USB_DIR_IN,
  99        .bmAttributes           = USB_ENDPOINT_XFER_INT,
 100        /*.wMaxPacketSize       = DYNAMIC */
 101        .bInterval              = 4, /* FIXME: Add this field in the
 102                                      * HID gadget configuration?
 103                                      * (struct hidg_func_descriptor)
 104                                      */
 105};
 106
 107static struct usb_endpoint_descriptor hidg_hs_out_ep_desc = {
 108        .bLength                = USB_DT_ENDPOINT_SIZE,
 109        .bDescriptorType        = USB_DT_ENDPOINT,
 110        .bEndpointAddress       = USB_DIR_OUT,
 111        .bmAttributes           = USB_ENDPOINT_XFER_INT,
 112        /*.wMaxPacketSize       = DYNAMIC */
 113        .bInterval              = 4, /* FIXME: Add this field in the
 114                                      * HID gadget configuration?
 115                                      * (struct hidg_func_descriptor)
 116                                      */
 117};
 118
 119static struct usb_descriptor_header *hidg_hs_descriptors[] = {
 120        (struct usb_descriptor_header *)&hidg_interface_desc,
 121        (struct usb_descriptor_header *)&hidg_desc,
 122        (struct usb_descriptor_header *)&hidg_hs_in_ep_desc,
 123        (struct usb_descriptor_header *)&hidg_hs_out_ep_desc,
 124        NULL,
 125};
 126
 127/* Full-Speed Support */
 128
 129static struct usb_endpoint_descriptor hidg_fs_in_ep_desc = {
 130        .bLength                = USB_DT_ENDPOINT_SIZE,
 131        .bDescriptorType        = USB_DT_ENDPOINT,
 132        .bEndpointAddress       = USB_DIR_IN,
 133        .bmAttributes           = USB_ENDPOINT_XFER_INT,
 134        /*.wMaxPacketSize       = DYNAMIC */
 135        .bInterval              = 10, /* FIXME: Add this field in the
 136                                       * HID gadget configuration?
 137                                       * (struct hidg_func_descriptor)
 138                                       */
 139};
 140
 141static struct usb_endpoint_descriptor hidg_fs_out_ep_desc = {
 142        .bLength                = USB_DT_ENDPOINT_SIZE,
 143        .bDescriptorType        = USB_DT_ENDPOINT,
 144        .bEndpointAddress       = USB_DIR_OUT,
 145        .bmAttributes           = USB_ENDPOINT_XFER_INT,
 146        /*.wMaxPacketSize       = DYNAMIC */
 147        .bInterval              = 10, /* FIXME: Add this field in the
 148                                       * HID gadget configuration?
 149                                       * (struct hidg_func_descriptor)
 150                                       */
 151};
 152
 153static struct usb_descriptor_header *hidg_fs_descriptors[] = {
 154        (struct usb_descriptor_header *)&hidg_interface_desc,
 155        (struct usb_descriptor_header *)&hidg_desc,
 156        (struct usb_descriptor_header *)&hidg_fs_in_ep_desc,
 157        (struct usb_descriptor_header *)&hidg_fs_out_ep_desc,
 158        NULL,
 159};
 160
 161/*-------------------------------------------------------------------------*/
 162/*                              Char Device                                */
 163
 164static ssize_t f_hidg_read(struct file *file, char __user *buffer,
 165                        size_t count, loff_t *ptr)
 166{
 167        struct f_hidg *hidg = file->private_data;
 168        struct f_hidg_req_list *list;
 169        struct usb_request *req;
 170        unsigned long flags;
 171        int ret;
 172
 173        if (!count)
 174                return 0;
 175
 176        if (!access_ok(VERIFY_WRITE, buffer, count))
 177                return -EFAULT;
 178
 179        spin_lock_irqsave(&hidg->spinlock, flags);
 180
 181#define READ_COND (!list_empty(&hidg->completed_out_req))
 182
 183        /* wait for at least one buffer to complete */
 184        while (!READ_COND) {
 185                spin_unlock_irqrestore(&hidg->spinlock, flags);
 186                if (file->f_flags & O_NONBLOCK)
 187                        return -EAGAIN;
 188
 189                if (wait_event_interruptible(hidg->read_queue, READ_COND))
 190                        return -ERESTARTSYS;
 191
 192                spin_lock_irqsave(&hidg->spinlock, flags);
 193        }
 194
 195        /* pick the first one */
 196        list = list_first_entry(&hidg->completed_out_req,
 197                                struct f_hidg_req_list, list);
 198        req = list->req;
 199        count = min_t(unsigned int, count, req->actual - list->pos);
 200        spin_unlock_irqrestore(&hidg->spinlock, flags);
 201
 202        /* copy to user outside spinlock */
 203        count -= copy_to_user(buffer, req->buf + list->pos, count);
 204        list->pos += count;
 205
 206        /*
 207         * if this request is completely handled and transfered to
 208         * userspace, remove its entry from the list and requeue it
 209         * again. Otherwise, we will revisit it again upon the next
 210         * call, taking into account its current read position.
 211         */
 212        if (list->pos == req->actual) {
 213                spin_lock_irqsave(&hidg->spinlock, flags);
 214                list_del(&list->list);
 215                kfree(list);
 216                spin_unlock_irqrestore(&hidg->spinlock, flags);
 217
 218                req->length = hidg->report_length;
 219                ret = usb_ep_queue(hidg->out_ep, req, GFP_KERNEL);
 220                if (ret < 0)
 221                        return ret;
 222        }
 223
 224        return count;
 225}
 226
 227static void f_hidg_req_complete(struct usb_ep *ep, struct usb_request *req)
 228{
 229        struct f_hidg *hidg = (struct f_hidg *)ep->driver_data;
 230
 231        if (req->status != 0) {
 232                ERROR(hidg->func.config->cdev,
 233                        "End Point Request ERROR: %d\n", req->status);
 234        }
 235
 236        hidg->write_pending = 0;
 237        wake_up(&hidg->write_queue);
 238}
 239
 240static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
 241                            size_t count, loff_t *offp)
 242{
 243        struct f_hidg *hidg  = file->private_data;
 244        ssize_t status = -ENOMEM;
 245
 246        if (!access_ok(VERIFY_READ, buffer, count))
 247                return -EFAULT;
 248
 249        mutex_lock(&hidg->lock);
 250
 251#define WRITE_COND (!hidg->write_pending)
 252
 253        /* write queue */
 254        while (!WRITE_COND) {
 255                mutex_unlock(&hidg->lock);
 256                if (file->f_flags & O_NONBLOCK)
 257                        return -EAGAIN;
 258
 259                if (wait_event_interruptible_exclusive(
 260                                hidg->write_queue, WRITE_COND))
 261                        return -ERESTARTSYS;
 262
 263                mutex_lock(&hidg->lock);
 264        }
 265
 266        count  = min_t(unsigned, count, hidg->report_length);
 267        status = copy_from_user(hidg->req->buf, buffer, count);
 268
 269        if (status != 0) {
 270                ERROR(hidg->func.config->cdev,
 271                        "copy_from_user error\n");
 272                mutex_unlock(&hidg->lock);
 273                return -EINVAL;
 274        }
 275
 276        hidg->req->status   = 0;
 277        hidg->req->zero     = 0;
 278        hidg->req->length   = count;
 279        hidg->req->complete = f_hidg_req_complete;
 280        hidg->req->context  = hidg;
 281        hidg->write_pending = 1;
 282
 283        status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC);
 284        if (status < 0) {
 285                ERROR(hidg->func.config->cdev,
 286                        "usb_ep_queue error on int endpoint %zd\n", status);
 287                hidg->write_pending = 0;
 288                wake_up(&hidg->write_queue);
 289        } else {
 290                status = count;
 291        }
 292
 293        mutex_unlock(&hidg->lock);
 294
 295        return status;
 296}
 297
 298static unsigned int f_hidg_poll(struct file *file, poll_table *wait)
 299{
 300        struct f_hidg   *hidg  = file->private_data;
 301        unsigned int    ret = 0;
 302
 303        poll_wait(file, &hidg->read_queue, wait);
 304        poll_wait(file, &hidg->write_queue, wait);
 305
 306        if (WRITE_COND)
 307                ret |= POLLOUT | POLLWRNORM;
 308
 309        if (READ_COND)
 310                ret |= POLLIN | POLLRDNORM;
 311
 312        return ret;
 313}
 314
 315#undef WRITE_COND
 316#undef READ_COND
 317
 318static int f_hidg_release(struct inode *inode, struct file *fd)
 319{
 320        fd->private_data = NULL;
 321        return 0;
 322}
 323
 324static int f_hidg_open(struct inode *inode, struct file *fd)
 325{
 326        struct f_hidg *hidg =
 327                container_of(inode->i_cdev, struct f_hidg, cdev);
 328
 329        fd->private_data = hidg;
 330
 331        return 0;
 332}
 333
 334/*-------------------------------------------------------------------------*/
 335/*                                usb_function                             */
 336
 337static struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep, unsigned length)
 338{
 339        struct usb_request *req;
 340
 341        req = usb_ep_alloc_request(ep, GFP_ATOMIC);
 342        if (req) {
 343                req->length = length;
 344                req->buf = kmalloc(length, GFP_ATOMIC);
 345                if (!req->buf) {
 346                        usb_ep_free_request(ep, req);
 347                        req = NULL;
 348                }
 349        }
 350        return req;
 351}
 352
 353static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req)
 354{
 355        struct f_hidg *hidg = (struct f_hidg *) req->context;
 356        struct f_hidg_req_list *req_list;
 357        unsigned long flags;
 358
 359        req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC);
 360        if (!req_list)
 361                return;
 362
 363        req_list->req = req;
 364
 365        spin_lock_irqsave(&hidg->spinlock, flags);
 366        list_add_tail(&req_list->list, &hidg->completed_out_req);
 367        spin_unlock_irqrestore(&hidg->spinlock, flags);
 368
 369        wake_up(&hidg->read_queue);
 370}
 371
 372static int hidg_setup(struct usb_function *f,
 373                const struct usb_ctrlrequest *ctrl)
 374{
 375        struct f_hidg                   *hidg = func_to_hidg(f);
 376        struct usb_composite_dev        *cdev = f->config->cdev;
 377        struct usb_request              *req  = cdev->req;
 378        int status = 0;
 379        __u16 value, length;
 380
 381        value   = __le16_to_cpu(ctrl->wValue);
 382        length  = __le16_to_cpu(ctrl->wLength);
 383
 384        VDBG(cdev, "hid_setup crtl_request : bRequestType:0x%x bRequest:0x%x "
 385                "Value:0x%x\n", ctrl->bRequestType, ctrl->bRequest, value);
 386
 387        switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
 388        case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
 389                  | HID_REQ_GET_REPORT):
 390                VDBG(cdev, "get_report\n");
 391
 392                /* send an empty report */
 393                length = min_t(unsigned, length, hidg->report_length);
 394                memset(req->buf, 0x0, length);
 395
 396                goto respond;
 397                break;
 398
 399        case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
 400                  | HID_REQ_GET_PROTOCOL):
 401                VDBG(cdev, "get_protocol\n");
 402                goto stall;
 403                break;
 404
 405        case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
 406                  | HID_REQ_SET_REPORT):
 407                VDBG(cdev, "set_report | wLenght=%d\n", ctrl->wLength);
 408                goto stall;
 409                break;
 410
 411        case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
 412                  | HID_REQ_SET_PROTOCOL):
 413                VDBG(cdev, "set_protocol\n");
 414                goto stall;
 415                break;
 416
 417        case ((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8
 418                  | USB_REQ_GET_DESCRIPTOR):
 419                switch (value >> 8) {
 420                case HID_DT_HID:
 421                        VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n");
 422                        length = min_t(unsigned short, length,
 423                                                   hidg_desc.bLength);
 424                        memcpy(req->buf, &hidg_desc, length);
 425                        goto respond;
 426                        break;
 427                case HID_DT_REPORT:
 428                        VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: REPORT\n");
 429                        length = min_t(unsigned short, length,
 430                                                   hidg->report_desc_length);
 431                        memcpy(req->buf, hidg->report_desc, length);
 432                        goto respond;
 433                        break;
 434
 435                default:
 436                        VDBG(cdev, "Unknown descriptor request 0x%x\n",
 437                                 value >> 8);
 438                        goto stall;
 439                        break;
 440                }
 441                break;
 442
 443        default:
 444                VDBG(cdev, "Unknown request 0x%x\n",
 445                         ctrl->bRequest);
 446                goto stall;
 447                break;
 448        }
 449
 450stall:
 451        return -EOPNOTSUPP;
 452
 453respond:
 454        req->zero = 0;
 455        req->length = length;
 456        status = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
 457        if (status < 0)
 458                ERROR(cdev, "usb_ep_queue error on ep0 %d\n", value);
 459        return status;
 460}
 461
 462static void hidg_disable(struct usb_function *f)
 463{
 464        struct f_hidg *hidg = func_to_hidg(f);
 465        struct f_hidg_req_list *list, *next;
 466
 467        usb_ep_disable(hidg->in_ep);
 468        hidg->in_ep->driver_data = NULL;
 469
 470        usb_ep_disable(hidg->out_ep);
 471        hidg->out_ep->driver_data = NULL;
 472
 473        list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
 474                list_del(&list->list);
 475                kfree(list);
 476        }
 477}
 478
 479static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 480{
 481        struct usb_composite_dev                *cdev = f->config->cdev;
 482        struct f_hidg                           *hidg = func_to_hidg(f);
 483        int i, status = 0;
 484
 485        VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt);
 486
 487        if (hidg->in_ep != NULL) {
 488                /* restart endpoint */
 489                if (hidg->in_ep->driver_data != NULL)
 490                        usb_ep_disable(hidg->in_ep);
 491
 492                status = config_ep_by_speed(f->config->cdev->gadget, f,
 493                                            hidg->in_ep);
 494                if (status) {
 495                        ERROR(cdev, "config_ep_by_speed FAILED!\n");
 496                        goto fail;
 497                }
 498                status = usb_ep_enable(hidg->in_ep);
 499                if (status < 0) {
 500                        ERROR(cdev, "Enable IN endpoint FAILED!\n");
 501                        goto fail;
 502                }
 503                hidg->in_ep->driver_data = hidg;
 504        }
 505
 506
 507        if (hidg->out_ep != NULL) {
 508                /* restart endpoint */
 509                if (hidg->out_ep->driver_data != NULL)
 510                        usb_ep_disable(hidg->out_ep);
 511
 512                status = config_ep_by_speed(f->config->cdev->gadget, f,
 513                                            hidg->out_ep);
 514                if (status) {
 515                        ERROR(cdev, "config_ep_by_speed FAILED!\n");
 516                        goto fail;
 517                }
 518                status = usb_ep_enable(hidg->out_ep);
 519                if (status < 0) {
 520                        ERROR(cdev, "Enable IN endpoint FAILED!\n");
 521                        goto fail;
 522                }
 523                hidg->out_ep->driver_data = hidg;
 524
 525                /*
 526                 * allocate a bunch of read buffers and queue them all at once.
 527                 */
 528                for (i = 0; i < hidg->qlen && status == 0; i++) {
 529                        struct usb_request *req =
 530                                        hidg_alloc_ep_req(hidg->out_ep,
 531                                                          hidg->report_length);
 532                        if (req) {
 533                                req->complete = hidg_set_report_complete;
 534                                req->context  = hidg;
 535                                status = usb_ep_queue(hidg->out_ep, req,
 536                                                      GFP_ATOMIC);
 537                                if (status)
 538                                        ERROR(cdev, "%s queue req --> %d\n",
 539                                                hidg->out_ep->name, status);
 540                        } else {
 541                                usb_ep_disable(hidg->out_ep);
 542                                hidg->out_ep->driver_data = NULL;
 543                                status = -ENOMEM;
 544                                goto fail;
 545                        }
 546                }
 547        }
 548
 549fail:
 550        return status;
 551}
 552
 553const struct file_operations f_hidg_fops = {
 554        .owner          = THIS_MODULE,
 555        .open           = f_hidg_open,
 556        .release        = f_hidg_release,
 557        .write          = f_hidg_write,
 558        .read           = f_hidg_read,
 559        .poll           = f_hidg_poll,
 560        .llseek         = noop_llseek,
 561};
 562
 563static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
 564{
 565        struct usb_ep           *ep;
 566        struct f_hidg           *hidg = func_to_hidg(f);
 567        int                     status;
 568        dev_t                   dev;
 569
 570        /* allocate instance-specific interface IDs, and patch descriptors */
 571        status = usb_interface_id(c, f);
 572        if (status < 0)
 573                goto fail;
 574        hidg_interface_desc.bInterfaceNumber = status;
 575
 576        /* allocate instance-specific endpoints */
 577        status = -ENODEV;
 578        ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc);
 579        if (!ep)
 580                goto fail;
 581        ep->driver_data = c->cdev;      /* claim */
 582        hidg->in_ep = ep;
 583
 584        ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc);
 585        if (!ep)
 586                goto fail;
 587        ep->driver_data = c->cdev;      /* claim */
 588        hidg->out_ep = ep;
 589
 590        /* preallocate request and buffer */
 591        status = -ENOMEM;
 592        hidg->req = usb_ep_alloc_request(hidg->in_ep, GFP_KERNEL);
 593        if (!hidg->req)
 594                goto fail;
 595
 596        hidg->req->buf = kmalloc(hidg->report_length, GFP_KERNEL);
 597        if (!hidg->req->buf)
 598                goto fail;
 599
 600        /* set descriptor dynamic values */
 601        hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
 602        hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
 603        hidg_hs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
 604        hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
 605        hidg_hs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
 606        hidg_fs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
 607        hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT;
 608        hidg_desc.desc[0].wDescriptorLength =
 609                cpu_to_le16(hidg->report_desc_length);
 610
 611        hidg_hs_in_ep_desc.bEndpointAddress =
 612                hidg_fs_in_ep_desc.bEndpointAddress;
 613        hidg_hs_out_ep_desc.bEndpointAddress =
 614                hidg_fs_out_ep_desc.bEndpointAddress;
 615
 616        status = usb_assign_descriptors(f, hidg_fs_descriptors,
 617                        hidg_hs_descriptors, NULL);
 618        if (status)
 619                goto fail;
 620
 621        mutex_init(&hidg->lock);
 622        spin_lock_init(&hidg->spinlock);
 623        init_waitqueue_head(&hidg->write_queue);
 624        init_waitqueue_head(&hidg->read_queue);
 625        INIT_LIST_HEAD(&hidg->completed_out_req);
 626
 627        /* create char device */
 628        cdev_init(&hidg->cdev, &f_hidg_fops);
 629        dev = MKDEV(major, hidg->minor);
 630        status = cdev_add(&hidg->cdev, dev, 1);
 631        if (status)
 632                goto fail;
 633
 634        device_create(hidg_class, NULL, dev, NULL, "%s%d", "hidg", hidg->minor);
 635
 636        return 0;
 637
 638fail:
 639        ERROR(f->config->cdev, "hidg_bind FAILED\n");
 640        if (hidg->req != NULL) {
 641                kfree(hidg->req->buf);
 642                if (hidg->in_ep != NULL)
 643                        usb_ep_free_request(hidg->in_ep, hidg->req);
 644        }
 645
 646        usb_free_all_descriptors(f);
 647        return status;
 648}
 649
 650static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
 651{
 652        struct f_hidg *hidg = func_to_hidg(f);
 653
 654        device_destroy(hidg_class, MKDEV(major, hidg->minor));
 655        cdev_del(&hidg->cdev);
 656
 657        /* disable/free request and end point */
 658        usb_ep_disable(hidg->in_ep);
 659        usb_ep_dequeue(hidg->in_ep, hidg->req);
 660        kfree(hidg->req->buf);
 661        usb_ep_free_request(hidg->in_ep, hidg->req);
 662
 663        usb_free_all_descriptors(f);
 664
 665        kfree(hidg->report_desc);
 666        kfree(hidg);
 667}
 668
 669/*-------------------------------------------------------------------------*/
 670/*                                 Strings                                 */
 671
 672#define CT_FUNC_HID_IDX 0
 673
 674static struct usb_string ct_func_string_defs[] = {
 675        [CT_FUNC_HID_IDX].s     = "HID Interface",
 676        {},                     /* end of list */
 677};
 678
 679static struct usb_gadget_strings ct_func_string_table = {
 680        .language       = 0x0409,       /* en-US */
 681        .strings        = ct_func_string_defs,
 682};
 683
 684static struct usb_gadget_strings *ct_func_strings[] = {
 685        &ct_func_string_table,
 686        NULL,
 687};
 688
 689/*-------------------------------------------------------------------------*/
 690/*                             usb_configuration                           */
 691
 692int __init hidg_bind_config(struct usb_configuration *c,
 693                            struct hidg_func_descriptor *fdesc, int index)
 694{
 695        struct f_hidg *hidg;
 696        int status;
 697
 698        if (index >= minors)
 699                return -ENOENT;
 700
 701        /* maybe allocate device-global string IDs, and patch descriptors */
 702        if (ct_func_string_defs[CT_FUNC_HID_IDX].id == 0) {
 703                status = usb_string_id(c->cdev);
 704                if (status < 0)
 705                        return status;
 706                ct_func_string_defs[CT_FUNC_HID_IDX].id = status;
 707                hidg_interface_desc.iInterface = status;
 708        }
 709
 710        /* allocate and initialize one new instance */
 711        hidg = kzalloc(sizeof *hidg, GFP_KERNEL);
 712        if (!hidg)
 713                return -ENOMEM;
 714
 715        hidg->minor = index;
 716        hidg->bInterfaceSubClass = fdesc->subclass;
 717        hidg->bInterfaceProtocol = fdesc->protocol;
 718        hidg->report_length = fdesc->report_length;
 719        hidg->report_desc_length = fdesc->report_desc_length;
 720        hidg->report_desc = kmemdup(fdesc->report_desc,
 721                                    fdesc->report_desc_length,
 722                                    GFP_KERNEL);
 723        if (!hidg->report_desc) {
 724                kfree(hidg);
 725                return -ENOMEM;
 726        }
 727
 728        hidg->func.name    = "hid";
 729        hidg->func.strings = ct_func_strings;
 730        hidg->func.bind    = hidg_bind;
 731        hidg->func.unbind  = hidg_unbind;
 732        hidg->func.set_alt = hidg_set_alt;
 733        hidg->func.disable = hidg_disable;
 734        hidg->func.setup   = hidg_setup;
 735
 736        /* this could me made configurable at some point */
 737        hidg->qlen         = 4;
 738
 739        status = usb_add_function(c, &hidg->func);
 740        if (status)
 741                kfree(hidg);
 742
 743        return status;
 744}
 745
 746int __init ghid_setup(struct usb_gadget *g, int count)
 747{
 748        int status;
 749        dev_t dev;
 750
 751        hidg_class = class_create(THIS_MODULE, "hidg");
 752
 753        status = alloc_chrdev_region(&dev, 0, count, "hidg");
 754        if (!status) {
 755                major = MAJOR(dev);
 756                minors = count;
 757        }
 758
 759        return status;
 760}
 761
 762void ghid_cleanup(void)
 763{
 764        if (major) {
 765                unregister_chrdev_region(MKDEV(major, 0), minors);
 766                major = minors = 0;
 767        }
 768
 769        class_destroy(hidg_class);
 770        hidg_class = NULL;
 771}
 772