diff options
Diffstat (limited to 'drivers/usb/gadget/composite.c')
-rw-r--r-- | drivers/usb/gadget/composite.c | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 391d169f8d07..e483f80822d2 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -673,20 +673,83 @@ static int get_string(struct usb_composite_dev *cdev, | |||
673 | * string IDs. Drivers for functions, configurations, or gadgets will | 673 | * string IDs. Drivers for functions, configurations, or gadgets will |
674 | * then store that ID in the appropriate descriptors and string table. | 674 | * then store that ID in the appropriate descriptors and string table. |
675 | * | 675 | * |
676 | * All string identifier should be allocated using this routine, to | 676 | * All string identifier should be allocated using this, |
677 | * ensure that for example different functions don't wrongly assign | 677 | * @usb_string_ids_tab() or @usb_string_ids_n() routine, to ensure |
678 | * different meanings to the same identifier. | 678 | * that for example different functions don't wrongly assign different |
679 | * meanings to the same identifier. | ||
679 | */ | 680 | */ |
680 | int usb_string_id(struct usb_composite_dev *cdev) | 681 | int usb_string_id(struct usb_composite_dev *cdev) |
681 | { | 682 | { |
682 | if (cdev->next_string_id < 254) { | 683 | if (cdev->next_string_id < 254) { |
683 | /* string id 0 is reserved */ | 684 | /* string id 0 is reserved by USB spec for list of |
685 | * supported languages */ | ||
686 | /* 255 reserved as well? -- mina86 */ | ||
684 | cdev->next_string_id++; | 687 | cdev->next_string_id++; |
685 | return cdev->next_string_id; | 688 | return cdev->next_string_id; |
686 | } | 689 | } |
687 | return -ENODEV; | 690 | return -ENODEV; |
688 | } | 691 | } |
689 | 692 | ||
693 | /** | ||
694 | * usb_string_ids() - allocate unused string IDs in batch | ||
695 | * @cdev: the device whose string descriptor IDs are being allocated | ||
696 | * @str: an array of usb_string objects to assign numbers to | ||
697 | * Context: single threaded during gadget setup | ||
698 | * | ||
699 | * @usb_string_ids() is called from bind() callbacks to allocate | ||
700 | * string IDs. Drivers for functions, configurations, or gadgets will | ||
701 | * then copy IDs from the string table to the appropriate descriptors | ||
702 | * and string table for other languages. | ||
703 | * | ||
704 | * All string identifier should be allocated using this, | ||
705 | * @usb_string_id() or @usb_string_ids_n() routine, to ensure that for | ||
706 | * example different functions don't wrongly assign different meanings | ||
707 | * to the same identifier. | ||
708 | */ | ||
709 | int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str) | ||
710 | { | ||
711 | int next = cdev->next_string_id; | ||
712 | |||
713 | for (; str->s; ++str) { | ||
714 | if (unlikely(next >= 254)) | ||
715 | return -ENODEV; | ||
716 | str->id = ++next; | ||
717 | } | ||
718 | |||
719 | cdev->next_string_id = next; | ||
720 | |||
721 | return 0; | ||
722 | } | ||
723 | |||
724 | /** | ||
725 | * usb_string_ids_n() - allocate unused string IDs in batch | ||
726 | * @cdev: the device whose string descriptor IDs are being allocated | ||
727 | * @n: number of string IDs to allocate | ||
728 | * Context: single threaded during gadget setup | ||
729 | * | ||
730 | * Returns the first requested ID. This ID and next @n-1 IDs are now | ||
731 | * valid IDs. At least providind that @n is non zore because if it | ||
732 | * is, returns last requested ID which is now very useful information. | ||
733 | * | ||
734 | * @usb_string_ids_n() is called from bind() callbacks to allocate | ||
735 | * string IDs. Drivers for functions, configurations, or gadgets will | ||
736 | * then store that ID in the appropriate descriptors and string table. | ||
737 | * | ||
738 | * All string identifier should be allocated using this, | ||
739 | * @usb_string_id() or @usb_string_ids_n() routine, to ensure that for | ||
740 | * example different functions don't wrongly assign different meanings | ||
741 | * to the same identifier. | ||
742 | */ | ||
743 | int usb_string_ids_n(struct usb_composite_dev *c, unsigned n) | ||
744 | { | ||
745 | unsigned next = c->next_string_id; | ||
746 | if (unlikely(n > 254 || (unsigned)next + n > 254)) | ||
747 | return -ENODEV; | ||
748 | c->next_string_id += n; | ||
749 | return next + 1; | ||
750 | } | ||
751 | |||
752 | |||
690 | /*-------------------------------------------------------------------------*/ | 753 | /*-------------------------------------------------------------------------*/ |
691 | 754 | ||
692 | static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) | 755 | static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) |
@@ -893,6 +956,8 @@ static void composite_disconnect(struct usb_gadget *gadget) | |||
893 | spin_lock_irqsave(&cdev->lock, flags); | 956 | spin_lock_irqsave(&cdev->lock, flags); |
894 | if (cdev->config) | 957 | if (cdev->config) |
895 | reset_config(cdev); | 958 | reset_config(cdev); |
959 | if (composite->disconnect) | ||
960 | composite->disconnect(cdev); | ||
896 | spin_unlock_irqrestore(&cdev->lock, flags); | 961 | spin_unlock_irqrestore(&cdev->lock, flags); |
897 | } | 962 | } |
898 | 963 | ||