Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.6 781 lines 20 kB view raw
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/utsname.h> 14#include <linux/module.h> 15#include <linux/hid.h> 16#include <linux/cdev.h> 17#include <linux/mutex.h> 18#include <linux/poll.h> 19#include <linux/uaccess.h> 20#include <linux/wait.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 577 /* allocate instance-specific endpoints */ 578 status = -ENODEV; 579 ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc); 580 if (!ep) 581 goto fail; 582 ep->driver_data = c->cdev; /* claim */ 583 hidg->in_ep = ep; 584 585 ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc); 586 if (!ep) 587 goto fail; 588 ep->driver_data = c->cdev; /* claim */ 589 hidg->out_ep = ep; 590 591 /* preallocate request and buffer */ 592 status = -ENOMEM; 593 hidg->req = usb_ep_alloc_request(hidg->in_ep, GFP_KERNEL); 594 if (!hidg->req) 595 goto fail; 596 597 hidg->req->buf = kmalloc(hidg->report_length, GFP_KERNEL); 598 if (!hidg->req->buf) 599 goto fail; 600 601 /* set descriptor dynamic values */ 602 hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; 603 hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; 604 hidg_hs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); 605 hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); 606 hidg_hs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); 607 hidg_fs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); 608 hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT; 609 hidg_desc.desc[0].wDescriptorLength = 610 cpu_to_le16(hidg->report_desc_length); 611 612 /* copy descriptors */ 613 f->descriptors = usb_copy_descriptors(hidg_fs_descriptors); 614 if (!f->descriptors) 615 goto fail; 616 617 if (gadget_is_dualspeed(c->cdev->gadget)) { 618 hidg_hs_in_ep_desc.bEndpointAddress = 619 hidg_fs_in_ep_desc.bEndpointAddress; 620 hidg_hs_out_ep_desc.bEndpointAddress = 621 hidg_fs_out_ep_desc.bEndpointAddress; 622 f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors); 623 if (!f->hs_descriptors) 624 goto fail; 625 } 626 627 mutex_init(&hidg->lock); 628 spin_lock_init(&hidg->spinlock); 629 init_waitqueue_head(&hidg->write_queue); 630 init_waitqueue_head(&hidg->read_queue); 631 INIT_LIST_HEAD(&hidg->completed_out_req); 632 633 /* create char device */ 634 cdev_init(&hidg->cdev, &f_hidg_fops); 635 dev = MKDEV(major, hidg->minor); 636 status = cdev_add(&hidg->cdev, dev, 1); 637 if (status) 638 goto fail; 639 640 device_create(hidg_class, NULL, dev, NULL, "%s%d", "hidg", hidg->minor); 641 642 return 0; 643 644fail: 645 ERROR(f->config->cdev, "hidg_bind FAILED\n"); 646 if (hidg->req != NULL) { 647 kfree(hidg->req->buf); 648 if (hidg->in_ep != NULL) 649 usb_ep_free_request(hidg->in_ep, hidg->req); 650 } 651 652 usb_free_descriptors(f->hs_descriptors); 653 usb_free_descriptors(f->descriptors); 654 655 return status; 656} 657 658static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) 659{ 660 struct f_hidg *hidg = func_to_hidg(f); 661 662 device_destroy(hidg_class, MKDEV(major, hidg->minor)); 663 cdev_del(&hidg->cdev); 664 665 /* disable/free request and end point */ 666 usb_ep_disable(hidg->in_ep); 667 usb_ep_dequeue(hidg->in_ep, hidg->req); 668 kfree(hidg->req->buf); 669 usb_ep_free_request(hidg->in_ep, hidg->req); 670 671 /* free descriptors copies */ 672 usb_free_descriptors(f->hs_descriptors); 673 usb_free_descriptors(f->descriptors); 674 675 kfree(hidg->report_desc); 676 kfree(hidg); 677} 678 679/*-------------------------------------------------------------------------*/ 680/* Strings */ 681 682#define CT_FUNC_HID_IDX 0 683 684static struct usb_string ct_func_string_defs[] = { 685 [CT_FUNC_HID_IDX].s = "HID Interface", 686 {}, /* end of list */ 687}; 688 689static struct usb_gadget_strings ct_func_string_table = { 690 .language = 0x0409, /* en-US */ 691 .strings = ct_func_string_defs, 692}; 693 694static struct usb_gadget_strings *ct_func_strings[] = { 695 &ct_func_string_table, 696 NULL, 697}; 698 699/*-------------------------------------------------------------------------*/ 700/* usb_configuration */ 701 702int __init hidg_bind_config(struct usb_configuration *c, 703 struct hidg_func_descriptor *fdesc, int index) 704{ 705 struct f_hidg *hidg; 706 int status; 707 708 if (index >= minors) 709 return -ENOENT; 710 711 /* maybe allocate device-global string IDs, and patch descriptors */ 712 if (ct_func_string_defs[CT_FUNC_HID_IDX].id == 0) { 713 status = usb_string_id(c->cdev); 714 if (status < 0) 715 return status; 716 ct_func_string_defs[CT_FUNC_HID_IDX].id = status; 717 hidg_interface_desc.iInterface = status; 718 } 719 720 /* allocate and initialize one new instance */ 721 hidg = kzalloc(sizeof *hidg, GFP_KERNEL); 722 if (!hidg) 723 return -ENOMEM; 724 725 hidg->minor = index; 726 hidg->bInterfaceSubClass = fdesc->subclass; 727 hidg->bInterfaceProtocol = fdesc->protocol; 728 hidg->report_length = fdesc->report_length; 729 hidg->report_desc_length = fdesc->report_desc_length; 730 hidg->report_desc = kmemdup(fdesc->report_desc, 731 fdesc->report_desc_length, 732 GFP_KERNEL); 733 if (!hidg->report_desc) { 734 kfree(hidg); 735 return -ENOMEM; 736 } 737 738 hidg->func.name = "hid"; 739 hidg->func.strings = ct_func_strings; 740 hidg->func.bind = hidg_bind; 741 hidg->func.unbind = hidg_unbind; 742 hidg->func.set_alt = hidg_set_alt; 743 hidg->func.disable = hidg_disable; 744 hidg->func.setup = hidg_setup; 745 746 /* this could me made configurable at some point */ 747 hidg->qlen = 4; 748 749 status = usb_add_function(c, &hidg->func); 750 if (status) 751 kfree(hidg); 752 753 return status; 754} 755 756int __init ghid_setup(struct usb_gadget *g, int count) 757{ 758 int status; 759 dev_t dev; 760 761 hidg_class = class_create(THIS_MODULE, "hidg"); 762 763 status = alloc_chrdev_region(&dev, 0, count, "hidg"); 764 if (!status) { 765 major = MAJOR(dev); 766 minors = count; 767 } 768 769 return status; 770} 771 772void ghid_cleanup(void) 773{ 774 if (major) { 775 unregister_chrdev_region(MKDEV(major, 0), minors); 776 major = minors = 0; 777 } 778 779 class_destroy(hidg_class); 780 hidg_class = NULL; 781}