aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2012-01-02 06:35:41 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2012-01-04 18:52:42 -0500
commit18b7ede5f7ee2092aedcb578d3ac30bd5d4fc23c (patch)
treea49fe4ec2a86b37c8bed5041b8314c118b1ebead
parente28dbb0661ca49ada2d6a307a1ec93dd75d515e0 (diff)
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>
-rw-r--r--drivers/usb/dwc3/gadget.c3
-rw-r--r--drivers/usb/host/xhci.c3
-rw-r--r--include/linux/usb/ch9.h20
3 files changed, 21 insertions, 5 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 4c6bedad51fd..a696bde53222 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -297,8 +297,7 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
297 params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN 297 params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN
298 | DWC3_DEPCFG_XFER_NOT_READY_EN; 298 | DWC3_DEPCFG_XFER_NOT_READY_EN;
299 299
300 if (comp_desc && USB_SS_MAX_STREAMS(comp_desc->bmAttributes) 300 if (usb_ss_max_streams(comp_desc) && usb_endpoint_xfer_bulk(desc)) {
301 && usb_endpoint_xfer_bulk(desc)) {
302 params.param1 |= DWC3_DEPCFG_STREAM_CAPABLE 301 params.param1 |= DWC3_DEPCFG_STREAM_CAPABLE
303 | DWC3_DEPCFG_STREAM_EVENT_EN; 302 | DWC3_DEPCFG_STREAM_EVENT_EN;
304 dep->stream_capable = true; 303 dep->stream_capable = true;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index f3d0b8d96440..dda84756c465 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -2799,8 +2799,7 @@ static int xhci_calculate_streams_and_bitmask(struct xhci_hcd *xhci,
2799 if (ret < 0) 2799 if (ret < 0)
2800 return ret; 2800 return ret;
2801 2801
2802 max_streams = USB_SS_MAX_STREAMS( 2802 max_streams = usb_ss_max_streams(&eps[i]->ss_ep_comp);
2803 eps[i]->ss_ep_comp.bmAttributes);
2804 if (max_streams < (*num_streams - 1)) { 2803 if (max_streams < (*num_streams - 1)) {
2805 xhci_dbg(xhci, "Ep 0x%x only supports %u stream IDs.\n", 2804 xhci_dbg(xhci, "Ep 0x%x only supports %u stream IDs.\n",
2806 eps[i]->desc.bEndpointAddress, 2805 eps[i]->desc.bEndpointAddress,
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index d5da6c68c250..61b29057b054 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -605,8 +605,26 @@ struct usb_ss_ep_comp_descriptor {
605} __attribute__ ((packed)); 605} __attribute__ ((packed));
606 606
607#define USB_DT_SS_EP_COMP_SIZE 6 607#define USB_DT_SS_EP_COMP_SIZE 6
608
608/* Bits 4:0 of bmAttributes if this is a bulk endpoint */ 609/* Bits 4:0 of bmAttributes if this is a bulk endpoint */
609#define USB_SS_MAX_STREAMS(p) (1 << ((p) & 0x1f)) 610static inline int
611usb_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/* Bits 1:0 of bmAttributes if this is an isoc endpoint */ 628/* Bits 1:0 of bmAttributes if this is an isoc endpoint */
611#define USB_SS_MULT(p) (1 + ((p) & 0x3)) 629#define USB_SS_MULT(p) (1 + ((p) & 0x3))
612 630