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