Skip to content

Commit

Permalink
usb: fix regression in SuperSpeed endpoint descriptor parsing
Browse files Browse the repository at this point in the history
commit b37d83a ("usb: Parse the new USB 3.1 SuperSpeedPlus Isoc
endpoint companion descriptor") caused a regression in 4.6-rc1 and fails
to parse SuperSpeed endpoint companion descriptors.

The new SuperSpeedPlus Isoc endpoint companion parsing code incorrectly
decreased the the remaining buffer size before comparing the size with the
expected length of the descriptor.

This lead to possible failure in reading the SuperSpeed endpoint companion
descriptor of the last endpoint, displaying a message like:

"No SuperSpeed endpoint companion for config 1 interface 0 altsetting 0
 ep 129: using minimum values"

Fix it by decreasing the size after comparing it.
Also finish all the SS endpoint companion parsing before calling SSP isoc
endpoint parsing function.

Fixes: b37d83a
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
matnyman authored and gregkh committed Mar 31, 2016
1 parent b348d7d commit 59b9023
Showing 1 changed file with 7 additions and 9 deletions.
16 changes: 7 additions & 9 deletions drivers/usb/core/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
* be the first thing immediately following the endpoint descriptor.
*/
desc = (struct usb_ss_ep_comp_descriptor *) buffer;
buffer += desc->bLength;
size -= desc->bLength;

if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP ||
size < USB_DT_SS_EP_COMP_SIZE) {
Expand All @@ -100,7 +98,8 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
ep->desc.wMaxPacketSize;
return;
}

buffer += desc->bLength;
size -= desc->bLength;
memcpy(&ep->ss_ep_comp, desc, USB_DT_SS_EP_COMP_SIZE);

/* Check the various values */
Expand Down Expand Up @@ -146,12 +145,6 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
ep->ss_ep_comp.bmAttributes = 2;
}

/* Parse a possible SuperSpeedPlus isoc ep companion descriptor */
if (usb_endpoint_xfer_isoc(&ep->desc) &&
USB_SS_SSP_ISOC_COMP(desc->bmAttributes))
usb_parse_ssp_isoc_endpoint_companion(ddev, cfgno, inum, asnum,
ep, buffer, size);

if (usb_endpoint_xfer_isoc(&ep->desc))
max_tx = (desc->bMaxBurst + 1) *
(USB_SS_MULT(desc->bmAttributes)) *
Expand All @@ -171,6 +164,11 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
max_tx);
ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
}
/* Parse a possible SuperSpeedPlus isoc ep companion descriptor */
if (usb_endpoint_xfer_isoc(&ep->desc) &&
USB_SS_SSP_ISOC_COMP(desc->bmAttributes))
usb_parse_ssp_isoc_endpoint_companion(ddev, cfgno, inum, asnum,
ep, buffer, size);
}

static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
Expand Down

0 comments on commit 59b9023

Please sign in to comment.