.. | .. |
---|
10 | 10 | #include <linux/ctype.h> |
---|
11 | 11 | #include <linux/debugfs.h> |
---|
12 | 12 | #include <linux/delay.h> |
---|
| 13 | +#include <linux/idr.h> |
---|
13 | 14 | #include <linux/kref.h> |
---|
14 | 15 | #include <linux/miscdevice.h> |
---|
15 | 16 | #include <linux/module.h> |
---|
.. | .. |
---|
34 | 35 | MODULE_LICENSE("GPL"); |
---|
35 | 36 | |
---|
36 | 37 | /*----------------------------------------------------------------------*/ |
---|
| 38 | + |
---|
| 39 | +static DEFINE_IDA(driver_id_numbers); |
---|
| 40 | +#define DRIVER_DRIVER_NAME_LENGTH_MAX 32 |
---|
37 | 41 | |
---|
38 | 42 | #define RAW_EVENT_QUEUE_SIZE 16 |
---|
39 | 43 | |
---|
.. | .. |
---|
144 | 148 | STATE_DEV_INVALID = 0, |
---|
145 | 149 | STATE_DEV_OPENED, |
---|
146 | 150 | STATE_DEV_INITIALIZED, |
---|
| 151 | + STATE_DEV_REGISTERING, |
---|
147 | 152 | STATE_DEV_RUNNING, |
---|
148 | 153 | STATE_DEV_CLOSED, |
---|
149 | 154 | STATE_DEV_FAILED |
---|
.. | .. |
---|
158 | 163 | |
---|
159 | 164 | /* Reference to misc device: */ |
---|
160 | 165 | struct device *dev; |
---|
| 166 | + |
---|
| 167 | + /* Make driver names unique */ |
---|
| 168 | + int driver_id_number; |
---|
161 | 169 | |
---|
162 | 170 | /* Protected by lock: */ |
---|
163 | 171 | enum dev_state state; |
---|
.. | .. |
---|
187 | 195 | spin_lock_init(&dev->lock); |
---|
188 | 196 | init_completion(&dev->ep0_done); |
---|
189 | 197 | raw_event_queue_init(&dev->queue); |
---|
| 198 | + dev->driver_id_number = -1; |
---|
190 | 199 | return dev; |
---|
191 | 200 | } |
---|
192 | 201 | |
---|
.. | .. |
---|
197 | 206 | |
---|
198 | 207 | kfree(dev->udc_name); |
---|
199 | 208 | kfree(dev->driver.udc_name); |
---|
| 209 | + kfree(dev->driver.driver.name); |
---|
| 210 | + if (dev->driver_id_number >= 0) |
---|
| 211 | + ida_free(&driver_id_numbers, dev->driver_id_number); |
---|
200 | 212 | if (dev->req) { |
---|
201 | 213 | if (dev->ep0_urb_queued) |
---|
202 | 214 | usb_ep_dequeue(dev->gadget->ep0, dev->req); |
---|
.. | .. |
---|
417 | 429 | static int raw_ioctl_init(struct raw_dev *dev, unsigned long value) |
---|
418 | 430 | { |
---|
419 | 431 | int ret = 0; |
---|
| 432 | + int driver_id_number; |
---|
420 | 433 | struct usb_raw_init arg; |
---|
421 | 434 | char *udc_driver_name; |
---|
422 | 435 | char *udc_device_name; |
---|
| 436 | + char *driver_driver_name; |
---|
423 | 437 | unsigned long flags; |
---|
424 | 438 | |
---|
425 | 439 | if (copy_from_user(&arg, (void __user *)value, sizeof(arg))) |
---|
.. | .. |
---|
438 | 452 | return -EINVAL; |
---|
439 | 453 | } |
---|
440 | 454 | |
---|
| 455 | + driver_id_number = ida_alloc(&driver_id_numbers, GFP_KERNEL); |
---|
| 456 | + if (driver_id_number < 0) |
---|
| 457 | + return driver_id_number; |
---|
| 458 | + |
---|
| 459 | + driver_driver_name = kmalloc(DRIVER_DRIVER_NAME_LENGTH_MAX, GFP_KERNEL); |
---|
| 460 | + if (!driver_driver_name) { |
---|
| 461 | + ret = -ENOMEM; |
---|
| 462 | + goto out_free_driver_id_number; |
---|
| 463 | + } |
---|
| 464 | + snprintf(driver_driver_name, DRIVER_DRIVER_NAME_LENGTH_MAX, |
---|
| 465 | + DRIVER_NAME ".%d", driver_id_number); |
---|
| 466 | + |
---|
441 | 467 | udc_driver_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL); |
---|
442 | | - if (!udc_driver_name) |
---|
443 | | - return -ENOMEM; |
---|
| 468 | + if (!udc_driver_name) { |
---|
| 469 | + ret = -ENOMEM; |
---|
| 470 | + goto out_free_driver_driver_name; |
---|
| 471 | + } |
---|
444 | 472 | ret = strscpy(udc_driver_name, &arg.driver_name[0], |
---|
445 | 473 | UDC_NAME_LENGTH_MAX); |
---|
446 | | - if (ret < 0) { |
---|
447 | | - kfree(udc_driver_name); |
---|
448 | | - return ret; |
---|
449 | | - } |
---|
| 474 | + if (ret < 0) |
---|
| 475 | + goto out_free_udc_driver_name; |
---|
450 | 476 | ret = 0; |
---|
451 | 477 | |
---|
452 | 478 | udc_device_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL); |
---|
453 | 479 | if (!udc_device_name) { |
---|
454 | | - kfree(udc_driver_name); |
---|
455 | | - return -ENOMEM; |
---|
| 480 | + ret = -ENOMEM; |
---|
| 481 | + goto out_free_udc_driver_name; |
---|
456 | 482 | } |
---|
457 | 483 | ret = strscpy(udc_device_name, &arg.device_name[0], |
---|
458 | 484 | UDC_NAME_LENGTH_MAX); |
---|
459 | | - if (ret < 0) { |
---|
460 | | - kfree(udc_driver_name); |
---|
461 | | - kfree(udc_device_name); |
---|
462 | | - return ret; |
---|
463 | | - } |
---|
| 485 | + if (ret < 0) |
---|
| 486 | + goto out_free_udc_device_name; |
---|
464 | 487 | ret = 0; |
---|
465 | 488 | |
---|
466 | 489 | spin_lock_irqsave(&dev->lock, flags); |
---|
467 | 490 | if (dev->state != STATE_DEV_OPENED) { |
---|
468 | 491 | dev_dbg(dev->dev, "fail, device is not opened\n"); |
---|
469 | | - kfree(udc_driver_name); |
---|
470 | | - kfree(udc_device_name); |
---|
471 | 492 | ret = -EINVAL; |
---|
472 | 493 | goto out_unlock; |
---|
473 | 494 | } |
---|
.. | .. |
---|
482 | 503 | dev->driver.suspend = gadget_suspend; |
---|
483 | 504 | dev->driver.resume = gadget_resume; |
---|
484 | 505 | dev->driver.reset = gadget_reset; |
---|
485 | | - dev->driver.driver.name = DRIVER_NAME; |
---|
| 506 | + dev->driver.driver.name = driver_driver_name; |
---|
486 | 507 | dev->driver.udc_name = udc_device_name; |
---|
487 | 508 | dev->driver.match_existing_only = 1; |
---|
| 509 | + dev->driver_id_number = driver_id_number; |
---|
488 | 510 | |
---|
489 | 511 | dev->state = STATE_DEV_INITIALIZED; |
---|
| 512 | + spin_unlock_irqrestore(&dev->lock, flags); |
---|
| 513 | + return ret; |
---|
490 | 514 | |
---|
491 | 515 | out_unlock: |
---|
492 | 516 | spin_unlock_irqrestore(&dev->lock, flags); |
---|
| 517 | +out_free_udc_device_name: |
---|
| 518 | + kfree(udc_device_name); |
---|
| 519 | +out_free_udc_driver_name: |
---|
| 520 | + kfree(udc_driver_name); |
---|
| 521 | +out_free_driver_driver_name: |
---|
| 522 | + kfree(driver_driver_name); |
---|
| 523 | +out_free_driver_id_number: |
---|
| 524 | + ida_free(&driver_id_numbers, driver_id_number); |
---|
493 | 525 | return ret; |
---|
494 | 526 | } |
---|
495 | 527 | |
---|
.. | .. |
---|
507 | 539 | ret = -EINVAL; |
---|
508 | 540 | goto out_unlock; |
---|
509 | 541 | } |
---|
| 542 | + dev->state = STATE_DEV_REGISTERING; |
---|
510 | 543 | spin_unlock_irqrestore(&dev->lock, flags); |
---|
511 | 544 | |
---|
512 | 545 | ret = usb_gadget_probe_driver(&dev->driver); |
---|
.. | .. |
---|
564 | 597 | return -ENODEV; |
---|
565 | 598 | } |
---|
566 | 599 | length = min(arg.length, event->length); |
---|
567 | | - if (copy_to_user((void __user *)value, event, sizeof(*event) + length)) |
---|
| 600 | + if (copy_to_user((void __user *)value, event, sizeof(*event) + length)) { |
---|
| 601 | + kfree(event); |
---|
568 | 602 | return -EFAULT; |
---|
| 603 | + } |
---|
569 | 604 | |
---|
| 605 | + kfree(event); |
---|
570 | 606 | return 0; |
---|
571 | 607 | } |
---|
572 | 608 | |
---|
.. | .. |
---|
1000 | 1036 | ret = -EBUSY; |
---|
1001 | 1037 | goto out_unlock; |
---|
1002 | 1038 | } |
---|
1003 | | - if ((in && !ep->ep->caps.dir_in) || (!in && ep->ep->caps.dir_in)) { |
---|
| 1039 | + if (in != usb_endpoint_dir_in(ep->ep->desc)) { |
---|
1004 | 1040 | dev_dbg(&dev->gadget->dev, "fail, wrong direction\n"); |
---|
1005 | 1041 | ret = -EINVAL; |
---|
1006 | 1042 | goto out_unlock; |
---|