aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/composite.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/composite.c')
-rw-r--r--drivers/usb/gadget/composite.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index f2da0269e1b1..59e85234fa0a 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -149,16 +149,17 @@ done:
149int usb_function_deactivate(struct usb_function *function) 149int usb_function_deactivate(struct usb_function *function)
150{ 150{
151 struct usb_composite_dev *cdev = function->config->cdev; 151 struct usb_composite_dev *cdev = function->config->cdev;
152 unsigned long flags;
152 int status = 0; 153 int status = 0;
153 154
154 spin_lock(&cdev->lock); 155 spin_lock_irqsave(&cdev->lock, flags);
155 156
156 if (cdev->deactivations == 0) 157 if (cdev->deactivations == 0)
157 status = usb_gadget_disconnect(cdev->gadget); 158 status = usb_gadget_disconnect(cdev->gadget);
158 if (status == 0) 159 if (status == 0)
159 cdev->deactivations++; 160 cdev->deactivations++;
160 161
161 spin_unlock(&cdev->lock); 162 spin_unlock_irqrestore(&cdev->lock, flags);
162 return status; 163 return status;
163} 164}
164 165
@@ -683,6 +684,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
683 struct usb_request *req = cdev->req; 684 struct usb_request *req = cdev->req;
684 int value = -EOPNOTSUPP; 685 int value = -EOPNOTSUPP;
685 u16 w_index = le16_to_cpu(ctrl->wIndex); 686 u16 w_index = le16_to_cpu(ctrl->wIndex);
687 u8 intf = w_index & 0xFF;
686 u16 w_value = le16_to_cpu(ctrl->wValue); 688 u16 w_value = le16_to_cpu(ctrl->wValue);
687 u16 w_length = le16_to_cpu(ctrl->wLength); 689 u16 w_length = le16_to_cpu(ctrl->wLength);
688 struct usb_function *f = NULL; 690 struct usb_function *f = NULL;
@@ -769,10 +771,10 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
769 goto unknown; 771 goto unknown;
770 if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES) 772 if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
771 break; 773 break;
772 f = cdev->config->interface[w_index]; 774 f = cdev->config->interface[intf];
773 if (!f) 775 if (!f)
774 break; 776 break;
775 if (w_value && !f->get_alt) 777 if (w_value && !f->set_alt)
776 break; 778 break;
777 value = f->set_alt(f, w_index, w_value); 779 value = f->set_alt(f, w_index, w_value);
778 break; 780 break;
@@ -781,7 +783,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
781 goto unknown; 783 goto unknown;
782 if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES) 784 if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
783 break; 785 break;
784 f = cdev->config->interface[w_index]; 786 f = cdev->config->interface[intf];
785 if (!f) 787 if (!f)
786 break; 788 break;
787 /* lots of interfaces only need altsetting zero... */ 789 /* lots of interfaces only need altsetting zero... */
@@ -808,7 +810,7 @@ unknown:
808 */ 810 */
809 if ((ctrl->bRequestType & USB_RECIP_MASK) 811 if ((ctrl->bRequestType & USB_RECIP_MASK)
810 == USB_RECIP_INTERFACE) { 812 == USB_RECIP_INTERFACE) {
811 f = cdev->config->interface[w_index]; 813 f = cdev->config->interface[intf];
812 if (f && f->setup) 814 if (f && f->setup)
813 value = f->setup(f, ctrl); 815 value = f->setup(f, ctrl);
814 else 816 else
@@ -1012,7 +1014,7 @@ composite_suspend(struct usb_gadget *gadget)
1012 struct usb_composite_dev *cdev = get_gadget_data(gadget); 1014 struct usb_composite_dev *cdev = get_gadget_data(gadget);
1013 struct usb_function *f; 1015 struct usb_function *f;
1014 1016
1015 /* REVISIT: should we have config and device level 1017 /* REVISIT: should we have config level
1016 * suspend/resume callbacks? 1018 * suspend/resume callbacks?
1017 */ 1019 */
1018 DBG(cdev, "suspend\n"); 1020 DBG(cdev, "suspend\n");
@@ -1022,6 +1024,8 @@ composite_suspend(struct usb_gadget *gadget)
1022 f->suspend(f); 1024 f->suspend(f);
1023 } 1025 }
1024 } 1026 }
1027 if (composite->suspend)
1028 composite->suspend(cdev);
1025} 1029}
1026 1030
1027static void 1031static void
@@ -1030,10 +1034,12 @@ composite_resume(struct usb_gadget *gadget)
1030 struct usb_composite_dev *cdev = get_gadget_data(gadget); 1034 struct usb_composite_dev *cdev = get_gadget_data(gadget);
1031 struct usb_function *f; 1035 struct usb_function *f;
1032 1036
1033 /* REVISIT: should we have config and device level 1037 /* REVISIT: should we have config level
1034 * suspend/resume callbacks? 1038 * suspend/resume callbacks?
1035 */ 1039 */
1036 DBG(cdev, "resume\n"); 1040 DBG(cdev, "resume\n");
1041 if (composite->resume)
1042 composite->resume(cdev);
1037 if (cdev->config) { 1043 if (cdev->config) {
1038 list_for_each_entry(f, &cdev->config->functions, list) { 1044 list_for_each_entry(f, &cdev->config->functions, list) {
1039 if (f->resume) 1045 if (f->resume)