usb: gadget: composite: Return SSP Dev Cap descriptor
authorJohn Youn <John.Youn@synopsys.com>
Sat, 6 Feb 2016 01:05:53 +0000 (17:05 -0800)
committerFelipe Balbi <balbi@kernel.org>
Fri, 4 Mar 2016 13:14:23 +0000 (15:14 +0200)
If a gadget supports SuperSpeedPlus or higher speeds, return a
SuperSpeedPlus USB Device Capability descriptor.

Currently this implementation returns a fixed descriptor with typical
values set.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
drivers/usb/gadget/composite.c

index ce5dbc59311d4ec190064223e0ee40d41aa0d69d..11d243349ebff1461d397fc05904d63e0281b50b 100644 (file)
@@ -597,6 +597,48 @@ static int bos_desc(struct usb_composite_dev *cdev)
        ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat;
        ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat;
 
+       /* The SuperSpeedPlus USB Device Capability descriptor */
+       if (gadget_is_superspeed_plus(cdev->gadget)) {
+               struct usb_ssp_cap_descriptor *ssp_cap;
+
+               ssp_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
+               bos->bNumDeviceCaps++;
+
+               /*
+                * Report typical values.
+                */
+
+               le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SSP_CAP_SIZE(1));
+               ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1);
+               ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
+               ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE;
+
+               /* SSAC = 1 (2 attributes) */
+               ssp_cap->bmAttributes = cpu_to_le32(1);
+
+               /* Min RX/TX Lane Count = 1 */
+               ssp_cap->wFunctionalitySupport = (1 << 8) | (1 << 12);
+
+               /*
+                * bmSublinkSpeedAttr[0]:
+                *   ST  = Symmetric, RX
+                *   LSE =  3 (Gbps)
+                *   LP  =  1 (SuperSpeedPlus)
+                *   LSM = 10 (10 Gbps)
+                */
+               ssp_cap->bmSublinkSpeedAttr[0] =
+                       (3 << 4) | (1 << 14) | (0xa << 16);
+               /*
+                * bmSublinkSpeedAttr[1] =
+                *   ST  = Symmetric, TX
+                *   LSE =  3 (Gbps)
+                *   LP  =  1 (SuperSpeedPlus)
+                *   LSM = 10 (10 Gbps)
+                */
+               ssp_cap->bmSublinkSpeedAttr[1] =
+                       (3 << 4) | (1 << 14) | (0xa << 16) | (1 << 7);
+       }
+
        return le16_to_cpu(bos->wTotalLength);
 }