提交 636ba13a 编写于 作者: C Chris Dickens 提交者: Felipe Balbi

usb: gadget: composite: remove duplicated code in OS desc handling

When the host wants to fetch OS descriptors, it sends two requests. The
first is only for the header and the second for the full amount
specified by the header in the first request. The OS descriptor handling
code is distinguishing the header-only requests based on the wLength of
the setup packet, but the same code is executed in both cases to
construct the actual header. Simplify this by always constructing the
header and then filling out the rest of the request if the wLength is
greater than the size of the header.

Also remove the duplicate code for queueing the request to ep0 by adding
a goto label.
Signed-off-by: NChris Dickens <christopher.a.dickens@gmail.com>
Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
上级 5d6ae4f0
...@@ -1427,6 +1427,7 @@ static int fill_ext_compat(struct usb_configuration *c, u8 *buf) ...@@ -1427,6 +1427,7 @@ static int fill_ext_compat(struct usb_configuration *c, u8 *buf)
int i, count; int i, count;
count = 16; count = 16;
buf += 16;
for (i = 0; i < c->next_interface_id; ++i) { for (i = 0; i < c->next_interface_id; ++i) {
struct usb_function *f; struct usb_function *f;
int j; int j;
...@@ -1502,6 +1503,7 @@ static int fill_ext_prop(struct usb_configuration *c, int interface, u8 *buf) ...@@ -1502,6 +1503,7 @@ static int fill_ext_prop(struct usb_configuration *c, int interface, u8 *buf)
f = c->interface[interface]; f = c->interface[interface];
count = 10; /* header length */ count = 10; /* header length */
buf += 10;
for (j = 0; j < f->os_desc_n; ++j) { for (j = 0; j < f->os_desc_n; ++j) {
if (interface != f->os_desc_table[j].if_id) if (interface != f->os_desc_table[j].if_id)
continue; continue;
...@@ -1833,7 +1835,6 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1833,7 +1835,6 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
if (w_index != 0x4 || (w_value >> 8)) if (w_index != 0x4 || (w_value >> 8))
break; break;
buf[6] = w_index; buf[6] = w_index;
if (w_length == 0x10) {
/* Number of ext compat interfaces */ /* Number of ext compat interfaces */
count = count_ext_compat(os_desc_cfg); count = count_ext_compat(os_desc_cfg);
buf[8] = count; buf[8] = count;
...@@ -1841,14 +1842,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1841,14 +1842,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
count += 16; /* header */ count += 16; /* header */
put_unaligned_le32(count, buf); put_unaligned_le32(count, buf);
value = w_length; value = w_length;
} else { if (w_length > 0x10) {
/* "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;
value = fill_ext_compat(os_desc_cfg, buf); value = fill_ext_compat(os_desc_cfg, buf);
value = min_t(u16, w_length, value); value = min_t(u16, w_length, value);
} }
...@@ -1858,46 +1852,23 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1858,46 +1852,23 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
break; break;
interface = w_value & 0xFF; interface = w_value & 0xFF;
buf[6] = w_index; buf[6] = w_index;
if (w_length == 0x0A) {
count = count_ext_prop(os_desc_cfg, count = count_ext_prop(os_desc_cfg,
interface); interface);
put_unaligned_le16(count, buf + 8); put_unaligned_le16(count, buf + 8);
count = len_ext_prop(os_desc_cfg, count = len_ext_prop(os_desc_cfg,
interface); interface);
put_unaligned_le32(count, buf); put_unaligned_le32(count, buf);
value = w_length; value = w_length;
} else { 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);
buf += 10;
value = fill_ext_prop(os_desc_cfg, value = fill_ext_prop(os_desc_cfg,
interface, buf); interface, buf);
if (value < 0) if (value >= 0)
return value;
value = min_t(u16, w_length, value); value = min_t(u16, w_length, value);
} }
break; break;
} }
if (value >= 0) { goto check_value;
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;
} }
VDBG(cdev, VDBG(cdev,
...@@ -1971,6 +1942,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1971,6 +1942,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
goto done; goto done;
} }
check_value:
/* respond with data transfer before status phase? */ /* respond with data transfer before status phase? */
if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) { if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) {
req->length = value; req->length = value;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册