summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/usb/usba/bos.h
blob: 417dd1e60c171a2f93e58942e98a6d46728985dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright 2019 Joyent, Inc.
 */

#ifndef _SYS_USB_BOS_H
#define	_SYS_USB_BOS_H

/*
 * This header contains definitions that relate to the USB Binary Object Store.
 * While this functionality was originally introduced with WUSB, it was used in
 * USB 3.x as a way to provide additional device related information. This is
 * currently separate from the primary usbai headers as this functionality is
 * not currently used by client device drivers themselves, but only by the hub
 * driver for private functionality.
 *
 * This data is all derived from the USB 3.1 specification, Chapter 9.6.2 Binary
 * Device Object Store (BOS).
 */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Capability list, see USB 3.1 r1.0, Table 9-14.
 */
#define	USB_BOS_TYPE_INVALID		0x00	/* Internal, synthetic value */
#define	USB_BOS_TYPE_WUSB		0x01
#define	USB_BOS_TYPE_USB2_EXT		0x02
#define	USB_BOS_TYPE_SUPERSPEED		0x03
#define	USB_BOS_TYPE_CONTAINER		0x04
#define	USB_BOS_TYPE_PLATFORM		0x05
#define	USB_BOS_TYPE_PD_CAP		0x06
#define	USB_BOS_TYPE_BATTERY_INFO	0x07
#define	USB_BOS_TYPE_PD_CONSUMER_CAP	0x08
#define	USB_BOS_TYPE_PD_PRODUCER_CAP	0x09
#define	USB_BOS_TYPE_SUPERSPEED_PLUS	0x0a
#define	USB_BOS_TYPE_PRECISION_TIME	0x0b
#define	USB_BOS_TYPE_WUSB_EXT		0x0c

/*
 * General Binary Object Store (BOS) descriptor. This is returned at the start
 * of the BOS tree. See USB 3.1/Table 9-12.
 */
typedef struct usb_bos_descr {
	uint8_t		bLength;		/* Descriptor size */
	uint8_t		bDescriptorType;	/* Set to USB_DESCR_TYPE_BOS */
	uint16_t	wTotalLength;		/* Total length */
	uint8_t		bNumDeviceCaps;		/* Number of caps that follow */
} usb_bos_descr_t;

/*
 * This is the size of the usb_bos_descr_t in terms of packed bytes.
 */
#define	USB_BOS_PACKED_SIZE	5

/*
 * This represents a Device Capability Descriptor. bNumDeviceCaps of these
 * follow the usb_bos_descr_t. This structure is the generic header of each
 * device capability. Capability specific ones follow this. See USB 3.1/Table
 * 9-14.
 */
typedef struct usb_dev_cap_descr {
	uint8_t		bLength;		/* Descriptor size */
	uint8_t		bDescriptorType;	/* USB_TYPE_DEV_CAPABILITY */
	uint8_t		bDevCapabilityType;	/* USB_BOS_TYPE_* value */
} usb_dev_cap_descr_t;

#define	USB_DEV_CAP_PACKED_SIZE	3

/*
 * SuperSpeed devices include this descriptor to describe additional
 * capabilities that they have when operating in USB 2.0 High-Speed mode. See
 * USB 3.1/9.6.2.1 USB 2.0 Extension.
 */
typedef struct usb_bos_usb2ext {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint8_t		bDevCapabilityType;
	uint32_t	bmAttributes;		/* Bitfield defined below */
} usb_bos_usb2ext_t;

#define	USB_BOS_USB2EXT_PACKED_SIZE	7

#define	USB_BOS_USB2EXT_LPM	0x02

/*
 * SuperSpeed devices include this descriptor to describe various hardware
 * attributes related to basic USB 3.0 SuperSpeed functionality. See USB
 * 3.1/9.6.2.2 SuperSpeed USB Device Capability.
 */
typedef struct usb_bos_ssusb {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint8_t		bDevCapabilityType;
	uint8_t		bmAttributes;		/* Capability bitfield */
	uint16_t	wSpeedsSupported;	/* speed bitmap defined below */
	uint8_t		bFunctionalitySupport;	/* Minimum supported speed */
	uint8_t		bU1DevExitLat;		/* Exit latency in us */
	uint16_t	bU2DevExitLat;		/* Exit latency in us */
} usb_bos_ssusb_t;

#define	USB_BOS_SSUSB_PACKED_SIZE	10

#define	USB_BOS_SSUB_CAP_LTM	0x02

#define	USB_BOS_SSUSB_SPEED_LOW		(1 << 0)
#define	USB_BOS_SSUSB_SPEED_FULL	(1 << 1)
#define	USB_BOS_SSUSB_SPEED_HIGH	(1 << 2)
#define	USB_BOS_SSUSB_SPEED_SUPER	(1 << 3)

/*
 * This structure is used to indicate a UUID for a given device that could
 * register on multiple ports. For example, a hub that appears on both a USB 2.x
 * and USB 3.x port like a hub. This UUID allows one to know that the device is
 * the same. See USB 3.1/9.6.2.3 Container ID.
 */
typedef struct usb_bos_container {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint8_t		bDevCapabilityType;
	uint8_t		bReserved;
	uint8_t		ContainerId[16];
} usb_bos_container_t;

#define	USB_BOS_CONTAINER_PACKED_SIZE	20

/*
 * This structure is used to indicate a platform-specific capability. For more
 * information, see USB 3.1/9.6.2.4 Platform Descriptor.
 */
typedef struct usb_bos_platform {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint8_t		bDevCapabilityType;
	uint8_t		bReserved;
	uint8_t		PlatformCapabilityUUID[16];
	uint8_t		CapabilityData[];
} usb_bos_platform_t;

#define	USB_BOS_PLATFORM_MIN_PACKED_SIZE	20

/*
 * This structure is used to indicate capabilities and attributes of a
 * SuperSpeedPlus link. This describes the USB 3.1+ speed needs and minimum
 * attributes of the device. See USB 3.1/9.6.2.5 SuperSpeedPlus USB Device
 * Capability.
 */
typedef struct usb_bos_ssplus {
	uint8_t		bLength;
	uint8_t		bDescriptortype;
	uint8_t		bDevCapabilityType;
	uint8_t		bReserved;
	uint32_t	bmAttributes;
	uint16_t	wFunctionalitySupport;
	uint16_t	wReserved;
	uint32_t	bmSublinkSpeedAttr[];
} usb_bos_ssplus_t;

#define	USB_BOS_SSPLUS_MIN_PACKED_SIZE	16

/*
 * These macros take apart the bmAttributes fields.
 */
#define	USB_BOS_SSPLUS_NSSAC(x)	(((x) & 0xf) + 1)
#define	USB_BOS_SSPLUS_NSSIC(x)	((((x) & 0xf0) >> 4) + 1)

/*
 * These macros take apart the wFunctionalitySupport member.
 */
#define	USB_BOS_SSPLUS_MIN_SSAI(x)	((x) & 0x0f)
#define	USB_BOS_SSPLUS_MIN_RX_LANE(x)	(((x) >> 8) & 0xf)
#define	USB_BOS_SSPLUS_MIN_TX_LANE(x)	(((x) >> 12) & 0xf)

/*
 * These macros are used to take apart the bmSublinkSpeedAttr members. There is
 * always at least one of them that exist in each attribute; however, there
 * could be more based on the value in NSSAC.
 */
#define	USB_BOS_SSPLUS_ATTR_SSID(x)	((x) & 0xf)
#define	USB_BOS_SSPLUS_ATTR_LSE(x)	(((x) >> 4) & 0x3)
#define	USB_BOS_SSPLUS_ATTR_LSE_BITPS	0
#define	USB_BOS_SSPLUS_ATTR_LSE_KBITPS	1
#define	USB_BOS_SSPLUS_ATTR_LSE_GBITPS	2

/*
 * These two macros take apart the sublink type. bit 6 indicates whether or not
 * the links are symmetric or asymmetric. It is asymmetric if the value is set
 * to one (USB_BOS_SSPLUS_ATTR_ST_ASYM), symmetric otherwise. If it is
 * asymmetric, then bit 7 indicates whether or not it's a tx or rx link.
 */
#define	USB_BOS_SSPLUS_ATTR_ST_ASYM	(1 << 6)
#define	USB_BOS_SSPLUS_ATTR_ST_TX	(1 << 7)

#define	USB_BOS_SSPLUS_ATTR_LP(x)	(((x) >> 14) & 0x3)
#define	USB_BOS_SSPLUS_ATTR_LP_SS	0x0
#define	USB_BOS_SSPLUS_ATTR_LP_SSPLUS	0x1

#define	USB_BOS_SSPLUS_ATTR_LSM(x)	((x) >> 16)

typedef struct usb_bos_precision_time {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint8_t		bDevCapabilityType;
} usb_bos_precision_time_t;

#define	USB_BOS_PRECISION_TIME_PACKED_SIZE	3

/*
 * This structure serves as an internal, parsed representation of a USB bos
 * descriptor.
 */
typedef struct usb_bos {
	uint8_t ubos_length;
	uint8_t ubos_type;
	union {
		usb_bos_usb2ext_t ubos_usb2;
		usb_bos_ssusb_t	ubos_ssusb;
		usb_bos_container_t ubos_container;
		usb_bos_platform_t ubos_platform;
		usb_bos_ssplus_t ubos_ssplus;
		usb_bos_precision_time_t ubos_time;
		uint8_t	ubos_raw[256];
	} ubos_caps;
} usb_bos_t;

#ifdef __cplusplus
}
#endif

#endif /* _SYS_USB_BOS_H */