summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/composite.c72
1 files changed, 22 insertions, 50 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index b8b629c615d3..1924e20f6e8c 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1427,6 +1427,7 @@ static int fill_ext_compat(struct usb_configuration *c, u8 *buf)
int i, count;
count = 16;
+ buf += 16;
for (i = 0; i < c->next_interface_id; ++i) {
struct usb_function *f;
int j;
@@ -1502,6 +1503,7 @@ static int fill_ext_prop(struct usb_configuration *c, int interface, u8 *buf)
f = c->interface[interface];
count = 10; /* header length */
+ buf += 10;
for (j = 0; j < f->os_desc_n; ++j) {
if (interface != f->os_desc_table[j].if_id)
continue;
@@ -1833,22 +1835,14 @@ unknown:
if (w_index != 0x4 || (w_value >> 8))
break;
buf[6] = w_index;
- if (w_length == 0x10) {
- /* Number of ext compat interfaces */
- count = count_ext_compat(os_desc_cfg);
- buf[8] = count;
- count *= 24; /* 24 B/ext compat desc */
- count += 16; /* header */
- put_unaligned_le32(count, buf);
- value = w_length;
- } else {
- /* "extended compatibility ID"s */
- count = count_ext_compat(os_desc_cfg);
- buf[8] = count;
- count *= 24; /* 24 B/ext compat desc */
- count += 16; /* header */
- put_unaligned_le32(count, buf);
- buf += 16;
+ /* Number of ext compat interfaces */
+ count = count_ext_compat(os_desc_cfg);
+ buf[8] = count;
+ count *= 24; /* 24 B/ext compat desc */
+ count += 16; /* header */
+ put_unaligned_le32(count, buf);
+ value = w_length;
+ if (w_length > 0x10) {
value = fill_ext_compat(os_desc_cfg, buf);
value = min_t(u16, w_length, value);
}
@@ -1858,46 +1852,23 @@ unknown:
break;
interface = w_value & 0xFF;
buf[6] = w_index;
- if (w_length == 0x0A) {
- count = count_ext_prop(os_desc_cfg,
- interface);
- put_unaligned_le16(count, buf + 8);
- count = len_ext_prop(os_desc_cfg,
- interface);
- put_unaligned_le32(count, buf);
-
- value = w_length;
- } else {
- count = count_ext_prop(os_desc_cfg,
- interface);
- put_unaligned_le16(count, buf + 8);
- count = len_ext_prop(os_desc_cfg,
- interface);
- put_unaligned_le32(count, buf);
- buf += 10;
+ count = count_ext_prop(os_desc_cfg,
+ interface);
+ put_unaligned_le16(count, buf + 8);
+ count = len_ext_prop(os_desc_cfg,
+ interface);
+ put_unaligned_le32(count, buf);
+ value = w_length;
+ if (w_length > 0x0A) {
value = fill_ext_prop(os_desc_cfg,
interface, buf);
- if (value < 0)
- return value;
- value = min_t(u16, w_length, value);
+ if (value >= 0)
+ value = min_t(u16, w_length, value);
}
break;
}
- if (value >= 0) {
- req->length = value;
- req->context = cdev;
- req->zero = value < w_length;
- value = composite_ep0_queue(cdev, req,
- GFP_ATOMIC);
- if (value < 0) {
- DBG(cdev, "ep_queue --> %d\n", value);
- req->status = 0;
- composite_setup_complete(gadget->ep0,
- req);
- }
- }
- return value;
+ goto check_value;
}
VDBG(cdev,
@@ -1971,6 +1942,7 @@ try_fun_setup:
goto done;
}
+check_value:
/* respond with data transfer before status phase? */
if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) {
req->length = value;