Commit 18b7ede5f7ee2092aedcb578d3ac30bd5d4fc23c

Authored by Felipe Balbi
Committed by Greg Kroah-Hartman
1 parent e28dbb0661

usb: ch9: fix up MaxStreams helper

According to USB 3.0 Specification Table 9-22, if
bmAttributes [4:0] are set to zero, it means "no
streams supported", but the way this helper was
defined on Linux, we will *always* have one stream
which might cause several problems.

For example on DWC3, we would tell the controller
endpoint has streams enabled and yet start transfers
with Stream ID set to 0, which would goof up the host
side.

While doing that, convert the macro to an inline
function due to the different checks we now need.

Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 3 changed files with 21 additions and 5 deletions Side-by-side Diff

drivers/usb/dwc3/gadget.c
... ... @@ -297,8 +297,7 @@
297 297 params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN
298 298 | DWC3_DEPCFG_XFER_NOT_READY_EN;
299 299  
300   - if (comp_desc && USB_SS_MAX_STREAMS(comp_desc->bmAttributes)
301   - && usb_endpoint_xfer_bulk(desc)) {
  300 + if (usb_ss_max_streams(comp_desc) && usb_endpoint_xfer_bulk(desc)) {
302 301 params.param1 |= DWC3_DEPCFG_STREAM_CAPABLE
303 302 | DWC3_DEPCFG_STREAM_EVENT_EN;
304 303 dep->stream_capable = true;
drivers/usb/host/xhci.c
... ... @@ -2799,8 +2799,7 @@
2799 2799 if (ret < 0)
2800 2800 return ret;
2801 2801  
2802   - max_streams = USB_SS_MAX_STREAMS(
2803   - eps[i]->ss_ep_comp.bmAttributes);
  2802 + max_streams = usb_ss_max_streams(&eps[i]->ss_ep_comp);
2804 2803 if (max_streams < (*num_streams - 1)) {
2805 2804 xhci_dbg(xhci, "Ep 0x%x only supports %u stream IDs.\n",
2806 2805 eps[i]->desc.bEndpointAddress,
include/linux/usb/ch9.h
... ... @@ -605,8 +605,26 @@
605 605 } __attribute__ ((packed));
606 606  
607 607 #define USB_DT_SS_EP_COMP_SIZE 6
  608 +
608 609 /* Bits 4:0 of bmAttributes if this is a bulk endpoint */
609   -#define USB_SS_MAX_STREAMS(p) (1 << ((p) & 0x1f))
  610 +static inline int
  611 +usb_ss_max_streams(const struct usb_ss_ep_comp_descriptor *comp)
  612 +{
  613 + int max_streams;
  614 +
  615 + if (!comp)
  616 + return 0;
  617 +
  618 + max_streams = comp->bmAttributes & 0x1f;
  619 +
  620 + if (!max_streams)
  621 + return 0;
  622 +
  623 + max_streams = 1 << max_streams;
  624 +
  625 + return max_streams;
  626 +}
  627 +
610 628 /* Bits 1:0 of bmAttributes if this is an isoc endpoint */
611 629 #define USB_SS_MULT(p) (1 + ((p) & 0x3))
612 630