If a xhci controller does not provide a protocol speed ID (PSI) table, a
default one should be used instead. Add the default values to the
SuperSpeedPlus device capability. Overwrite the default ones if a PSI table
exists. See xHCI 1.1 sectio 7.2.2.1.1 for more info

Signed-off-by: Mathias Nyman <mathias.ny...@linux.intel.com>
---
 drivers/usb/host/xhci-hub.c | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0863d8a..2c26ab50 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -50,14 +50,18 @@ static u8 usb_bos_descriptor [] = {
        0x00,                           /* bU1DevExitLat, set later. */
        0x00, 0x00,                     /* __le16 bU2DevExitLat, set later. */
        /* Second device capability, SuperSpeedPlus */
-       0x0c,                           /* bLength 12, will be adjusted later */
+       0x1c,                           /* bLength 28, will be adjusted later */
        USB_DT_DEVICE_CAPABILITY,       /* Device Capability */
        USB_SSP_CAP_TYPE,               /* bDevCapabilityType SUPERSPEED_PLUS */
        0x00,                           /* bReserved 0 */
-       0x00, 0x00, 0x00, 0x00,         /* bmAttributes, get from xhci psic */
-       0x00, 0x00,                     /* wFunctionalitySupport */
+       0x23, 0x00, 0x00, 0x00,         /* bmAttributes, SSAC=3 SSIC=1 */
+       0x01, 0x00,                     /* wFunctionalitySupport */
        0x00, 0x00,                     /* wReserved 0 */
-       /* Sublink Speed Attributes are added in xhci_create_usb3_bos_desc() */
+       /* Default Sublink Speed Attributes, overwrite if custom PSI exists */
+       0x34, 0x00, 0x05, 0x00,         /* 5Gbps, symmetric, rx, ID = 4 */
+       0xb4, 0x00, 0x05, 0x00,         /* 5Gbps, symmetric, tx, ID = 4 */
+       0x35, 0x40, 0x0a, 0x00,         /* 10Gbps, SSP, symmetric, rx, ID = 5 */
+       0xb5, 0x40, 0x0a, 0x00,         /* 10Gbps, SSP, symmetric, tx, ID = 5 */
 };
 
 static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf,
@@ -72,10 +76,14 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, 
char *buf,
        ssp_cap_size = sizeof(usb_bos_descriptor) - desc_size;
 
        /* does xhci support USB 3.1 Enhanced SuperSpeed */
-       if (xhci->usb3_rhub.min_rev >= 0x01 && xhci->usb3_rhub.psi_uid_count) {
-               /* two SSA entries for each unique PSI ID, one RX and one TX */
-               ssa_count = xhci->usb3_rhub.psi_uid_count * 2;
-               ssa_size = ssa_count * sizeof(u32);
+       if (xhci->usb3_rhub.min_rev >= 0x01) {
+               /* does xhci provide a PSI table for SSA speed attributes? */
+               if (xhci->usb3_rhub.psi_count) {
+                       /* two SSA entries for each unique PSI ID, RX and TX */
+                       ssa_count = xhci->usb3_rhub.psi_uid_count * 2;
+                       ssa_size = ssa_count * sizeof(u32);
+                       ssp_cap_size -= 16; /* skip copying the default SSA */
+               }
                desc_size += ssp_cap_size;
                usb3_1 = true;
        }
@@ -102,7 +110,8 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, 
char *buf,
                put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]);
        }
 
-       if (usb3_1) {
+       /* If PSI table exists, add the custom speed attributes from it */
+       if (usb3_1 && xhci->usb3_rhub.psi_count) {
                u32 ssp_cap_base, bm_attrib, psi;
                int offset;
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to