USB: gadget: composite: Dynamically set IAD bFirstInterface
authorJohn Michelau <john.michelau@motorola.com>
Fri, 10 Dec 2010 18:09:53 +0000 (12:09 -0600)
committermgross <mark.gross@intel.com>
Wed, 9 Nov 2011 20:03:34 +0000 (12:03 -0800)
bFirstInterface should be set equal to bInterfaceNumber of
the first interface in a grouping. It's currently being set
only when a composite device is bound, and it does not get
updated when functions are enabled or disabled.

Signed-off-by: Mike Lockwood <lockwood@android.com>
drivers/usb/gadget/composite.c

index c2684b5..96d8987 100644 (file)
@@ -305,6 +305,7 @@ static int config_buf(struct usb_configuration *config,
 {
        struct usb_config_descriptor    *c = buf;
        struct usb_interface_descriptor *intf;
+       struct usb_interface_assoc_descriptor *iad = NULL;
        void                            *next = buf + USB_DT_CONFIG_SIZE;
        int                             len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
        struct usb_function             *f;
@@ -358,6 +359,20 @@ static int config_buf(struct usb_configuration *config,
                                        intf->bInterfaceNumber = interfaceCount++;
                                else
                                        intf->bInterfaceNumber = interfaceCount - 1;
+                               if (iad) {
+                                       iad->bFirstInterface =
+                                                       intf->bInterfaceNumber;
+                                       iad = NULL;
+                               }
+                       } else if (intf->bDescriptorType ==
+                                       USB_DT_INTERFACE_ASSOCIATION) {
+                               /* This will be first if it exists. Save
+                                * a pointer to it so we can properly set
+                                * bFirstInterface when we process the first
+                                * interface.
+                                */
+                               iad = (struct usb_interface_assoc_descriptor *)
+                                               dest;
                        }
                        dest += intf->bLength;
                }