From 5da665fcec1a308f5273aacb9da8e87b89da8b4f Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 25 Jan 2016 15:30:46 +0200 Subject: [PATCH] xhci: USB 3.1 add default Speed Attributes to SuperSpeedPlus device capability 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 Signed-off-by: Greg Kroah-Hartman --- 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 b30b4ce294d3..d61fcc48099e 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; -- 2.20.1