summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/composite.c
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2010-02-13 19:16:07 -0500
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:38:01 -0800
commit4cc27e541135dfd444471a82f70fd6abaa02eae4 (patch)
treed813a6f05f90b60c2c70ddc53655f7e247c5a3a7 /drivers/usb/gadget/composite.c
parentec4648bf7c3df1135d14e39ae8d20d5c3afcb7f2 (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.c27
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;
}