diff options
author | Mike Lockwood <lockwood@android.com> | 2010-02-13 19:16:07 -0500 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:38:01 -0800 |
commit | 4cc27e541135dfd444471a82f70fd6abaa02eae4 (patch) | |
tree | d813a6f05f90b60c2c70ddc53655f7e247c5a3a7 /drivers/usb/gadget/composite.c | |
parent | ec4648bf7c3df1135d14e39ae8d20d5c3afcb7f2 (diff) |
USB: composite: Compute interface numbers correctly when functions are hidden.
Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'drivers/usb/gadget/composite.c')
-rw-r--r-- | drivers/usb/gadget/composite.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index b02aea804071..f8a446354748 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -404,18 +404,19 @@ static int config_buf(struct usb_configuration *config, enum usb_device_speed speed, void *buf, u8 type) { struct usb_config_descriptor *c = buf; + struct usb_interface_descriptor *intf; void *next = buf + USB_DT_CONFIG_SIZE; int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE; struct usb_function *f; int status; int interfaceCount = 0; + u8 *dest; /* write the config descriptor */ c = buf; c->bLength = USB_DT_CONFIG_SIZE; c->bDescriptorType = type; - /* wTotalLength is written later */ - c->bNumInterfaces = config->next_interface_id; + /* wTotalLength and bNumInterfaces are written later */ c->bConfigurationValue = config->bConfigurationValue; c->iConfiguration = config->iConfiguration; c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; @@ -434,6 +435,7 @@ static int config_buf(struct usb_configuration *config, /* add each function's descriptors */ list_for_each_entry(f, &config->functions, list) { struct usb_descriptor_header **descriptors; + struct usb_descriptor_header *descriptor; switch (speed) { case USB_SPEED_SUPER: @@ -446,26 +448,29 @@ static int config_buf(struct usb_configuration *config, descriptors = f->descriptors; } - if (f->hidden || !descriptors || descriptors[0] == NULL) { - for (; f != config->interface[interfaceCount];) { - interfaceCount++; - c->bNumInterfaces--; - } + if (f->hidden || !descriptors || descriptors[0] == NULL) continue; - } - for (; f != config->interface[interfaceCount];) - interfaceCount++; - status = usb_descriptor_fillbuf(next, len, (const struct usb_descriptor_header **) descriptors); if (status < 0) return status; + + /* set interface numbers dynamically */ + dest = next; + while ((descriptor = *descriptors++) != NULL) { + intf = (struct usb_interface_descriptor *)dest; + if (intf->bDescriptorType == USB_DT_INTERFACE) + intf->bInterfaceNumber = interfaceCount++; + dest += intf->bLength; + } + len -= status; next += status; } len = next - buf; c->wTotalLength = cpu_to_le16(len); + c->bNumInterfaces = interfaceCount; return len; } |