1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2019 Joyent, Inc. 14 */ 15 16 #ifndef _SYS_USB_BOS_H 17 #define _SYS_USB_BOS_H 18 19 /* 20 * This header contains definitions that relate to the USB Binary Object Store. 21 * While this functionality was originally introduced with WUSB, it was used in 22 * USB 3.x as a way to provide additional device related information. This is 23 * currently separate from the primary usbai headers as this functionality is 24 * not currently used by client device drivers themselves, but only by the hub 25 * driver for private functionality. 26 * 27 * This data is all derived from the USB 3.1 specification, Chapter 9.6.2 Binary 28 * Device Object Store (BOS). 29 */ 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 /* 36 * Capability list, see USB 3.1 r1.0, Table 9-14. 37 */ 38 #define USB_BOS_TYPE_INVALID 0x00 /* Internal, synthetic value */ 39 #define USB_BOS_TYPE_WUSB 0x01 40 #define USB_BOS_TYPE_USB2_EXT 0x02 41 #define USB_BOS_TYPE_SUPERSPEED 0x03 42 #define USB_BOS_TYPE_CONTAINER 0x04 43 #define USB_BOS_TYPE_PLATFORM 0x05 44 #define USB_BOS_TYPE_PD_CAP 0x06 45 #define USB_BOS_TYPE_BATTERY_INFO 0x07 46 #define USB_BOS_TYPE_PD_CONSUMER_CAP 0x08 47 #define USB_BOS_TYPE_PD_PRODUCER_CAP 0x09 48 #define USB_BOS_TYPE_SUPERSPEED_PLUS 0x0a 49 #define USB_BOS_TYPE_PRECISION_TIME 0x0b 50 #define USB_BOS_TYPE_WUSB_EXT 0x0c 51 52 /* 53 * General Binary Object Store (BOS) descriptor. This is returned at the start 54 * of the BOS tree. See USB 3.1/Table 9-12. 55 */ 56 typedef struct usb_bos_descr { 57 uint8_t bLength; /* Descriptor size */ 58 uint8_t bDescriptorType; /* Set to USB_DESCR_TYPE_BOS */ 59 uint16_t wTotalLength; /* Total length */ 60 uint8_t bNumDeviceCaps; /* Number of caps that follow */ 61 } usb_bos_descr_t; 62 63 /* 64 * This is the size of the usb_bos_descr_t in terms of packed bytes. 65 */ 66 #define USB_BOS_PACKED_SIZE 5 67 68 /* 69 * This represents a Device Capability Descriptor. bNumDeviceCaps of these 70 * follow the usb_bos_descr_t. This structure is the generic header of each 71 * device capability. Capability specific ones follow this. See USB 3.1/Table 72 * 9-14. 73 */ 74 typedef struct usb_dev_cap_descr { 75 uint8_t bLength; /* Descriptor size */ 76 uint8_t bDescriptorType; /* USB_TYPE_DEV_CAPABILITY */ 77 uint8_t bDevCapabilityType; /* USB_BOS_TYPE_* value */ 78 } usb_dev_cap_descr_t; 79 80 #define USB_DEV_CAP_PACKED_SIZE 3 81 82 /* 83 * SuperSpeed devices include this descriptor to describe additional 84 * capabilities that they have when operating in USB 2.0 High-Speed mode. See 85 * USB 3.1/9.6.2.1 USB 2.0 Extension. 86 */ 87 typedef struct usb_bos_usb2ext { 88 uint8_t bLength; 89 uint8_t bDescriptorType; 90 uint8_t bDevCapabilityType; 91 uint32_t bmAttributes; /* Bitfield defined below */ 92 } usb_bos_usb2ext_t; 93 94 #define USB_BOS_USB2EXT_PACKED_SIZE 7 95 96 #define USB_BOS_USB2EXT_LPM 0x02 97 98 /* 99 * SuperSpeed devices include this descriptor to describe various hardware 100 * attributes related to basic USB 3.0 SuperSpeed functionality. See USB 101 * 3.1/9.6.2.2 SuperSpeed USB Device Capability. 102 */ 103 typedef struct usb_bos_ssusb { 104 uint8_t bLength; 105 uint8_t bDescriptorType; 106 uint8_t bDevCapabilityType; 107 uint8_t bmAttributes; /* Capability bitfield */ 108 uint16_t wSpeedsSupported; /* speed bitmap defined below */ 109 uint8_t bFunctionalitySupport; /* Minimum supported speed */ 110 uint8_t bU1DevExitLat; /* Exit latency in us */ 111 uint16_t bU2DevExitLat; /* Exit latency in us */ 112 } usb_bos_ssusb_t; 113 114 #define USB_BOS_SSUSB_PACKED_SIZE 10 115 116 #define USB_BOS_SSUB_CAP_LTM 0x02 117 118 #define USB_BOS_SSUSB_SPEED_LOW (1 << 0) 119 #define USB_BOS_SSUSB_SPEED_FULL (1 << 1) 120 #define USB_BOS_SSUSB_SPEED_HIGH (1 << 2) 121 #define USB_BOS_SSUSB_SPEED_SUPER (1 << 3) 122 123 /* 124 * This structure is used to indicate a UUID for a given device that could 125 * register on multiple ports. For example, a hub that appears on both a USB 2.x 126 * and USB 3.x port like a hub. This UUID allows one to know that the device is 127 * the same. See USB 3.1/9.6.2.3 Container ID. 128 */ 129 typedef struct usb_bos_container { 130 uint8_t bLength; 131 uint8_t bDescriptorType; 132 uint8_t bDevCapabilityType; 133 uint8_t bReserved; 134 uint8_t ContainerId[16]; 135 } usb_bos_container_t; 136 137 #define USB_BOS_CONTAINER_PACKED_SIZE 20 138 139 /* 140 * This structure is used to indicate a platform-specific capability. For more 141 * information, see USB 3.1/9.6.2.4 Platform Descriptor. 142 */ 143 typedef struct usb_bos_platform { 144 uint8_t bLength; 145 uint8_t bDescriptorType; 146 uint8_t bDevCapabilityType; 147 uint8_t bReserved; 148 uint8_t PlatformCapabilityUUID[16]; 149 uint8_t CapabilityData[]; 150 } usb_bos_platform_t; 151 152 #define USB_BOS_PLATFORM_MIN_PACKED_SIZE 20 153 154 /* 155 * This structure is used to indicate capabilities and attributes of a 156 * SuperSpeedPlus link. This describes the USB 3.1+ speed needs and minimum 157 * attributes of the device. See USB 3.1/9.6.2.5 SuperSpeedPlus USB Device 158 * Capability. 159 */ 160 typedef struct usb_bos_ssplus { 161 uint8_t bLength; 162 uint8_t bDescriptortype; 163 uint8_t bDevCapabilityType; 164 uint8_t bReserved; 165 uint32_t bmAttributes; 166 uint16_t wFunctionalitySupport; 167 uint16_t wReserved; 168 uint32_t bmSublinkSpeedAttr[]; 169 } usb_bos_ssplus_t; 170 171 #define USB_BOS_SSPLUS_MIN_PACKED_SIZE 16 172 173 /* 174 * These macros take apart the bmAttributes fields. 175 */ 176 #define USB_BOS_SSPLUS_NSSAC(x) (((x) & 0xf) + 1) 177 #define USB_BOS_SSPLUS_NSSIC(x) ((((x) & 0xf0) >> 4) + 1) 178 179 /* 180 * These macros take apart the wFunctionalitySupport member. 181 */ 182 #define USB_BOS_SSPLUS_MIN_SSAI(x) ((x) & 0x0f) 183 #define USB_BOS_SSPLUS_MIN_RX_LANE(x) (((x) >> 8) & 0xf) 184 #define USB_BOS_SSPLUS_MIN_TX_LANE(x) (((x) >> 12) & 0xf) 185 186 /* 187 * These macros are used to take apart the bmSublinkSpeedAttr members. There is 188 * always at least one of them that exist in each attribute; however, there 189 * could be more based on the value in NSSAC. 190 */ 191 #define USB_BOS_SSPLUS_ATTR_SSID(x) ((x) & 0xf) 192 #define USB_BOS_SSPLUS_ATTR_LSE(x) (((x) >> 4) & 0x3) 193 #define USB_BOS_SSPLUS_ATTR_LSE_BITPS 0 194 #define USB_BOS_SSPLUS_ATTR_LSE_KBITPS 1 195 #define USB_BOS_SSPLUS_ATTR_LSE_GBITPS 2 196 197 /* 198 * These two macros take apart the sublink type. bit 6 indicates whether or not 199 * the links are symmetric or asymmetric. It is asymmetric if the value is set 200 * to one (USB_BOS_SSPLUS_ATTR_ST_ASYM), symmetric otherwise. If it is 201 * asymmetric, then bit 7 indicates whether or not it's a tx or rx link. 202 */ 203 #define USB_BOS_SSPLUS_ATTR_ST_ASYM (1 << 6) 204 #define USB_BOS_SSPLUS_ATTR_ST_TX (1 << 7) 205 206 #define USB_BOS_SSPLUS_ATTR_LP(x) (((x) >> 14) & 0x3) 207 #define USB_BOS_SSPLUS_ATTR_LP_SS 0x0 208 #define USB_BOS_SSPLUS_ATTR_LP_SSPLUS 0x1 209 210 #define USB_BOS_SSPLUS_ATTR_LSM(x) ((x) >> 16) 211 212 typedef struct usb_bos_precision_time { 213 uint8_t bLength; 214 uint8_t bDescriptorType; 215 uint8_t bDevCapabilityType; 216 } usb_bos_precision_time_t; 217 218 #define USB_BOS_PRECISION_TIME_PACKED_SIZE 3 219 220 /* 221 * This structure serves as an internal, parsed representation of a USB bos 222 * descriptor. 223 */ 224 typedef struct usb_bos { 225 uint8_t ubos_length; 226 uint8_t ubos_type; 227 union { 228 usb_bos_usb2ext_t ubos_usb2; 229 usb_bos_ssusb_t ubos_ssusb; 230 usb_bos_container_t ubos_container; 231 usb_bos_platform_t ubos_platform; 232 usb_bos_ssplus_t ubos_ssplus; 233 usb_bos_precision_time_t ubos_time; 234 uint8_t ubos_raw[256]; 235 } ubos_caps; 236 } usb_bos_t; 237 238 #ifdef __cplusplus 239 } 240 #endif 241 242 #endif /* _SYS_USB_BOS_H */ 243