xref: /illumos-gate/usr/src/uts/common/sys/usb/usba/bos.h (revision 0d2006e4)
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