Merge remote-tracking branches 'regulator/fix/88pm800', 'regulator/fix/max8973',...
[linux-drm-fsl-dcu.git] / drivers / usb / gadget / composite.c
index 13adfd1a3f54947f860f10161156a057dde274bc..58b4657fc721d3dabda76b2138ea6c30d539992c 100644 (file)
@@ -1161,11 +1161,11 @@ static struct usb_gadget_string_container *copy_gadget_strings(
  * This function will create a deep copy of usb_gadget_strings and usb_string
  * and attach it to the cdev. The actual string (usb_string.s) will not be
  * copied but only a referenced will be made. The struct usb_gadget_strings
- * array may contain multiple languges and should be NULL terminated.
+ * array may contain multiple languages and should be NULL terminated.
  * The ->language pointer of each struct usb_gadget_strings has to contain the
  * same amount of entries.
  * For instance: sp[0] is en-US, sp[1] is es-ES. It is expected that the first
- * usb_string entry of es-ES containts the translation of the first usb_string
+ * usb_string entry of es-ES contains the translation of the first usb_string
  * entry of en-US. Therefore both entries become the same id assign.
  */
 struct usb_string *usb_gstrings_attach(struct usb_composite_dev *cdev,
@@ -1472,6 +1472,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
        req->length = 0;
        gadget->ep0->driver_data = cdev;
 
+       /*
+        * Don't let non-standard requests match any of the cases below
+        * by accident.
+        */
+       if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD)
+               goto unknown;
+
        switch (ctrl->bRequest) {
 
        /* we handle all standard USB descriptors */
@@ -1751,6 +1758,13 @@ unknown:
                 * take such requests too, if that's ever needed:  to work
                 * in config 0, etc.
                 */
+               if (cdev->config) {
+                       list_for_each_entry(f, &cdev->config->functions, list)
+                               if (f->req_match && f->req_match(f, ctrl))
+                                       goto try_fun_setup;
+                       f = NULL;
+               }
+
                switch (ctrl->bRequestType & USB_RECIP_MASK) {
                case USB_RECIP_INTERFACE:
                        if (!cdev->config || intf >= MAX_CONFIG_INTERFACES)
@@ -1768,7 +1782,7 @@ unknown:
                                f = NULL;
                        break;
                }
-
+try_fun_setup:
                if (f && f->setup)
                        value = f->setup(f, ctrl);
                else {