These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / usb / gadget / composite.c
index 58b4657..8b14c2a 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/utsname.h>
 
 #include <linux/usb/composite.h>
+#include <linux/usb/otg.h>
 #include <asm/unaligned.h>
 
 #include "u_os_desc.h"
@@ -209,6 +210,12 @@ int usb_add_function(struct usb_configuration *config,
        function->config = config;
        list_add_tail(&function->list, &config->functions);
 
+       if (function->bind_deactivated) {
+               value = usb_function_deactivate(function);
+               if (value)
+                       goto done;
+       }
+
        /* REVISIT *require* function->bind? */
        if (function->bind) {
                value = function->bind(config, function);
@@ -279,7 +286,7 @@ int usb_function_deactivate(struct usb_function *function)
        spin_lock_irqsave(&cdev->lock, flags);
 
        if (cdev->deactivations == 0)
-               status = usb_gadget_disconnect(cdev->gadget);
+               status = usb_gadget_deactivate(cdev->gadget);
        if (status == 0)
                cdev->deactivations++;
 
@@ -311,7 +318,7 @@ int usb_function_activate(struct usb_function *function)
        else {
                cdev->deactivations--;
                if (cdev->deactivations == 0)
-                       status = usb_gadget_connect(cdev->gadget);
+                       status = usb_gadget_activate(cdev->gadget);
        }
 
        spin_unlock_irqrestore(&cdev->lock, flags);
@@ -832,9 +839,7 @@ int usb_add_config(struct usb_composite_dev *cdev,
                }
        }
 
-       /* set_alt(), or next bind(), sets up
-        * ep->driver_data as needed.
-        */
+       /* set_alt(), or next bind(), sets up ep->claimed as needed */
        usb_ep_autoconfig_reset(cdev->gadget);
 
 done:
@@ -896,7 +901,7 @@ void usb_remove_config(struct usb_composite_dev *cdev,
 
 /* We support strings in multiple languages ... string descriptor zero
  * says which languages are supported.  The typical case will be that
- * only one language (probably English) is used, with I18N handled on
+ * only one language (probably English) is used, with i18n handled on
  * the host side.
  */
 
@@ -949,7 +954,7 @@ static int get_string(struct usb_composite_dev *cdev,
        struct usb_function             *f;
        int                             len;
 
-       /* Yes, not only is USB's I18N support probably more than most
+       /* Yes, not only is USB's i18n support probably more than most
         * folk will ever care about ... also, it's all supported here.
         * (Except for UTF8 support for Unicode's "Astral Planes".)
         */
@@ -1499,6 +1504,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                                } else {
                                        cdev->desc.bcdUSB = cpu_to_le16(0x0210);
                                }
+                       } else {
+                               cdev->desc.bcdUSB = cpu_to_le16(0x0200);
                        }
 
                        value = min(w_length, (u16) sizeof cdev->desc);
@@ -1534,6 +1541,32 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                                value = min(w_length, (u16) value);
                        }
                        break;
+               case USB_DT_OTG:
+                       if (gadget_is_otg(gadget)) {
+                               struct usb_configuration *config;
+                               int otg_desc_len = 0;
+
+                               if (cdev->config)
+                                       config = cdev->config;
+                               else
+                                       config = list_first_entry(
+                                                       &cdev->configs,
+                                               struct usb_configuration, list);
+                               if (!config)
+                                       goto done;
+
+                               if (gadget->otg_caps &&
+                                       (gadget->otg_caps->otg_rev >= 0x0200))
+                                       otg_desc_len += sizeof(
+                                               struct usb_otg20_descriptor);
+                               else
+                                       otg_desc_len += sizeof(
+                                               struct usb_otg_descriptor);
+
+                               value = min_t(int, w_length, otg_desc_len);
+                               memcpy(req->buf, config->descriptors[0], value);
+                       }
+                       break;
                }
                break;