1184610Salfred/* $FreeBSD$ */
2184610Salfred/*-
3184610Salfred * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4184610Salfred * Copyright (c) 2007-2008 Daniel Drake.  All rights reserved.
5184610Salfred * Copyright (c) 2001 Johannes Erdfelt.  All rights reserved.
6184610Salfred *
7184610Salfred * Redistribution and use in source and binary forms, with or without
8184610Salfred * modification, are permitted provided that the following conditions
9184610Salfred * are met:
10184610Salfred * 1. Redistributions of source code must retain the above copyright
11184610Salfred *    notice, this list of conditions and the following disclaimer.
12184610Salfred * 2. Redistributions in binary form must reproduce the above copyright
13184610Salfred *    notice, this list of conditions and the following disclaimer in the
14184610Salfred *    documentation and/or other materials provided with the distribution.
15184610Salfred *
16184610Salfred * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17184610Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18184610Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19184610Salfred * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20184610Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21184610Salfred * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22184610Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23184610Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24184610Salfred * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25184610Salfred * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26184610Salfred * SUCH DAMAGE.
27184610Salfred */
28184610Salfred
29184610Salfred/*
30184610Salfred * NOTE: This file contains the definition of some standard USB
31184610Salfred * structures. All structures which name ends by *DECODED use host byte
32184610Salfred * order.
33184610Salfred */
34184610Salfred
35184610Salfred/*
36184610Salfred * NOTE: This file uses a lot of macros. If you want to see what the
37184610Salfred * macros become when they are expanded then run the following
38184610Salfred * commands from your shell:
39184610Salfred *
40184610Salfred * cpp libusb20_desc.h > temp.h
41184610Salfred * indent temp.h
42184610Salfred * less temp.h
43184610Salfred */
44184610Salfred
45184610Salfred#ifndef _LIBUSB20_DESC_H_
46184610Salfred#define	_LIBUSB20_DESC_H_
47184610Salfred
48248236Shselasky#ifndef LIBUSB_GLOBAL_INCLUDE_FILE
49248236Shselasky#include <stdint.h>
50248236Shselasky#endif
51248236Shselasky
52184610Salfred#ifdef __cplusplus
53184610Salfredextern	"C" {
54184610Salfred#endif
55184610Salfred#if 0
56184610Salfred};					/* style */
57184610Salfred
58184610Salfred#endif
59184610Salfred/* basic macros */
60184610Salfred
61184610Salfred#define	LIBUSB20__NOT(...) __VA_ARGS__
62184610Salfred#define	LIBUSB20_NOT(arg) LIBUSB20__NOT(LIBUSB20_YES arg(() LIBUSB20_NO))
63184610Salfred#define	LIBUSB20_YES(...) __VA_ARGS__
64184610Salfred#define	LIBUSB20_NO(...)
65184610Salfred#define	LIBUSB20_END(...) __VA_ARGS__
66184610Salfred#define	LIBUSB20_MAX(a,b) (((a) > (b)) ? (a) : (b))
67184610Salfred#define	LIBUSB20_MIN(a,b) (((a) < (b)) ? (a) : (b))
68184610Salfred
69184610Salfred#define	LIBUSB20_ADD_BYTES(ptr,off) \
70185087Salfred  ((void *)(((const uint8_t *)(ptr)) + (off) - ((const uint8_t *)0)))
71184610Salfred
72184610Salfred/* basic message elements */
73184610Salfredenum {
74184610Salfred	LIBUSB20_ME_INT8,
75184610Salfred	LIBUSB20_ME_INT16,
76184610Salfred	LIBUSB20_ME_INT32,
77184610Salfred	LIBUSB20_ME_INT64,
78184610Salfred	LIBUSB20_ME_STRUCT,
79184610Salfred	LIBUSB20_ME_MAX,		/* used to indicate end */
80184610Salfred};
81184610Salfred
82184610Salfred/* basic message element modifiers */
83184610Salfredenum {
84184610Salfred	LIBUSB20_ME_IS_UNSIGNED = 0x00,
85184610Salfred	LIBUSB20_ME_IS_SIGNED = 0x80,
86184610Salfred	LIBUSB20_ME_MASK = 0x7F,
87184610Salfred};
88184610Salfred
89184610Salfredenum {
90184610Salfred	LIBUSB20_ME_IS_RAW,		/* structure excludes length field
91184610Salfred					 * (hardcoded value) */
92184610Salfred	LIBUSB20_ME_IS_ENCODED,		/* structure includes length field */
93184610Salfred	LIBUSB20_ME_IS_EMPTY,		/* no structure */
94184610Salfred	LIBUSB20_ME_IS_DECODED,		/* structure is recursive */
95184610Salfred};
96184610Salfred
97184610Salfred/* basic helper structures and macros */
98184610Salfred
99184610Salfred#define	LIBUSB20_ME_STRUCT_ALIGN sizeof(void *)
100184610Salfred
101184610Salfredstruct libusb20_me_struct {
102184610Salfred	void   *ptr;			/* data pointer */
103184610Salfred	uint16_t len;			/* defaults to zero */
104184610Salfred	uint16_t type;			/* defaults to LIBUSB20_ME_IS_EMPTY */
105184610Salfred} __aligned(LIBUSB20_ME_STRUCT_ALIGN);
106184610Salfred
107184610Salfredstruct libusb20_me_format {
108184610Salfred	const uint8_t *format;		/* always set */
109184610Salfred	const char *desc;		/* optionally set */
110184610Salfred	const char *fields;		/* optionally set */
111184610Salfred};
112184610Salfred
113184610Salfred#define	LIBUSB20_ME_STRUCT(n, field, arg, ismeta)		\
114184610Salfred  ismeta ( LIBUSB20_ME_STRUCT, 1, 0, )			\
115184610Salfred  LIBUSB20_NOT(ismeta) ( struct libusb20_me_struct field; )
116184610Salfred
117184610Salfred#define	LIBUSB20_ME_STRUCT_ARRAY(n, field, arg, ismeta)	\
118184610Salfred  ismeta ( LIBUSB20_ME_STRUCT , (arg) & 0xFF,		\
119184610Salfred	   ((arg) / 0x100) & 0xFF, )			\
120184610Salfred  LIBUSB20_NOT(ismeta) ( struct libusb20_me_struct field [arg]; )
121184610Salfred
122184610Salfred#define	LIBUSB20_ME_INTEGER(n, field, ismeta, un, u, bits, a, size)	\
123184610Salfred  ismeta ( LIBUSB20_ME_INT##bits |					\
124184610Salfred	   LIBUSB20_ME_IS_##un##SIGNED ,				\
125184610Salfred	   (size) & 0xFF, ((size) / 0x100) & 0xFF, )		\
126184610Salfred  LIBUSB20_NOT(ismeta) ( u##int##bits##_t				\
127184610Salfred		    __aligned((bits) / 8) field a; )
128184610Salfred
129184610Salfred#define	LIBUSB20_ME_UINT8_T(n, field, arg, ismeta) \
130184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 8, , 1)
131184610Salfred
132184610Salfred#define	LIBUSB20_ME_UINT8_ARRAY_T(n, field, arg, ismeta) \
133184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 8, [arg], arg)
134184610Salfred
135184610Salfred#define	LIBUSB20_ME_SINT8_T(n, field, arg, ismeta) \
136184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 8, , 1)
137184610Salfred
138184610Salfred#define	LIBUSB20_ME_SINT8_ARRAY_T(n, field, arg, ismeta) \
139184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 8, [arg], arg)
140184610Salfred
141184610Salfred#define	LIBUSB20_ME_UINT16_T(n, field, arg, ismeta) \
142184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 16, , 1)
143184610Salfred
144184610Salfred#define	LIBUSB20_ME_UINT16_ARRAY_T(n, field, arg, ismeta) \
145184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 16, [arg], arg)
146184610Salfred
147184610Salfred#define	LIBUSB20_ME_SINT16_T(n, field, arg, ismeta) \
148184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 16, , 1)
149184610Salfred
150184610Salfred#define	LIBUSB20_ME_SINT16_ARRAY_T(n, field, arg, ismeta) \
151184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 16, [arg], arg)
152184610Salfred
153184610Salfred#define	LIBUSB20_ME_UINT32_T(n, field, arg, ismeta) \
154184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 32, , 1)
155184610Salfred
156184610Salfred#define	LIBUSB20_ME_UINT32_ARRAY_T(n, field, arg, ismeta) \
157184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 32, [arg], arg)
158184610Salfred
159184610Salfred#define	LIBUSB20_ME_SINT32_T(n, field, arg, ismeta) \
160184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 32, , 1)
161184610Salfred
162184610Salfred#define	LIBUSB20_ME_SINT32_ARRAY_T(n, field, arg, ismeta) \
163184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 32, [arg], arg)
164184610Salfred
165184610Salfred#define	LIBUSB20_ME_UINT64_T(n, field, arg, ismeta) \
166184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 64, , 1)
167184610Salfred
168184610Salfred#define	LIBUSB20_ME_UINT64_ARRAY_T(n, field, arg, ismeta) \
169184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 64, [arg], arg)
170184610Salfred
171184610Salfred#define	LIBUSB20_ME_SINT64_T(n, field, arg, ismeta) \
172184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 64, , 1)
173184610Salfred
174184610Salfred#define	LIBUSB20_ME_SINT64_ARRAY_T(n, field, arg, ismeta) \
175184610Salfred  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 64, [arg], arg)
176184610Salfred
177184610Salfred#define	LIBUSB20_MAKE_DECODED_FIELD(n, type, field, arg) \
178184610Salfred  LIBUSB20_ME_##type (n, field, arg, LIBUSB20_NO)
179184610Salfred
180184610Salfred#define	LIBUSB20_MAKE_STRUCT(name)			\
181184610Salfred  extern const struct libusb20_me_format			\
182184610Salfred	 name##_FORMAT[1];				\
183184610Salfred  struct name##_DECODED {				\
184184610Salfred    const struct libusb20_me_format *name##_FORMAT;	\
185184610Salfred    name (LIBUSB20_MAKE_DECODED_FIELD,)			\
186184610Salfred  }
187184610Salfred
188184610Salfred#define	LIBUSB20_MAKE_STRUCT_FORMAT(name)		\
189184610Salfred  const struct libusb20_me_format			\
190184610Salfred    name##_FORMAT[1] = {{			\
191184610Salfred      .format = LIBUSB20_MAKE_FORMAT(name),	\
192184610Salfred      .desc = #name,				\
193184610Salfred      .fields = NULL,				\
194184610Salfred  }}
195184610Salfred
196184610Salfred#define	LIBUSB20_MAKE_FORMAT_SUB(n, type, field, arg) \
197184610Salfred  LIBUSB20_ME_##type (n, field, arg, LIBUSB20_YES)
198184610Salfred
199184610Salfred#define	LIBUSB20_MAKE_FORMAT(what) (const uint8_t []) \
200184610Salfred  { what (LIBUSB20_MAKE_FORMAT_SUB, ) LIBUSB20_ME_MAX, 0, 0 }
201184610Salfred
202184610Salfred#define	LIBUSB20_INIT(what, ptr) do {		\
203184610Salfred    memset(ptr, 0, sizeof(*(ptr)));		\
204184610Salfred    (ptr)->what##_FORMAT = what##_FORMAT;	\
205184610Salfred} while (0)
206184610Salfred
207184610Salfred#define	LIBUSB20_DEVICE_DESC(m,n) \
208184610Salfred  m(n, UINT8_T, bLength, ) \
209184610Salfred  m(n, UINT8_T, bDescriptorType, ) \
210184610Salfred  m(n, UINT16_T, bcdUSB, ) \
211184610Salfred  m(n, UINT8_T, bDeviceClass, ) \
212184610Salfred  m(n, UINT8_T, bDeviceSubClass, ) \
213184610Salfred  m(n, UINT8_T, bDeviceProtocol, ) \
214184610Salfred  m(n, UINT8_T, bMaxPacketSize0, ) \
215184610Salfred  m(n, UINT16_T, idVendor, ) \
216184610Salfred  m(n, UINT16_T, idProduct, ) \
217184610Salfred  m(n, UINT16_T, bcdDevice, ) \
218184610Salfred  m(n, UINT8_T, iManufacturer, ) \
219184610Salfred  m(n, UINT8_T, iProduct, ) \
220184610Salfred  m(n, UINT8_T, iSerialNumber, ) \
221184610Salfred  m(n, UINT8_T, bNumConfigurations, ) \
222184610Salfred
223184610SalfredLIBUSB20_MAKE_STRUCT(LIBUSB20_DEVICE_DESC);
224184610Salfred
225184610Salfred#define	LIBUSB20_ENDPOINT_DESC(m,n) \
226184610Salfred  m(n, UINT8_T,  bLength, ) \
227184610Salfred  m(n, UINT8_T,  bDescriptorType, ) \
228184610Salfred  m(n, UINT8_T,  bEndpointAddress, ) \
229184610Salfred  m(n, UINT8_T,  bmAttributes, ) \
230184610Salfred  m(n, UINT16_T, wMaxPacketSize, ) \
231184610Salfred  m(n, UINT8_T,  bInterval, ) \
232184610Salfred  m(n, UINT8_T,  bRefresh, ) \
233184610Salfred  m(n, UINT8_T,  bSynchAddress, ) \
234184610Salfred
235184610SalfredLIBUSB20_MAKE_STRUCT(LIBUSB20_ENDPOINT_DESC);
236184610Salfred
237184610Salfred#define	LIBUSB20_INTERFACE_DESC(m,n) \
238184610Salfred  m(n, UINT8_T,  bLength, ) \
239184610Salfred  m(n, UINT8_T,  bDescriptorType, ) \
240184610Salfred  m(n, UINT8_T,  bInterfaceNumber, ) \
241184610Salfred  m(n, UINT8_T,  bAlternateSetting, ) \
242184610Salfred  m(n, UINT8_T,  bNumEndpoints, ) \
243184610Salfred  m(n, UINT8_T,  bInterfaceClass, ) \
244184610Salfred  m(n, UINT8_T,  bInterfaceSubClass, ) \
245184610Salfred  m(n, UINT8_T,  bInterfaceProtocol, ) \
246184610Salfred  m(n, UINT8_T,  iInterface, ) \
247184610Salfred
248184610SalfredLIBUSB20_MAKE_STRUCT(LIBUSB20_INTERFACE_DESC);
249184610Salfred
250184610Salfred#define	LIBUSB20_CONFIG_DESC(m,n) \
251184610Salfred  m(n, UINT8_T,  bLength, ) \
252184610Salfred  m(n, UINT8_T,  bDescriptorType, ) \
253184610Salfred  m(n, UINT16_T, wTotalLength, ) \
254184610Salfred  m(n, UINT8_T,  bNumInterfaces, ) \
255184610Salfred  m(n, UINT8_T,  bConfigurationValue, ) \
256184610Salfred  m(n, UINT8_T,  iConfiguration, ) \
257184610Salfred  m(n, UINT8_T,  bmAttributes, ) \
258184610Salfred  m(n, UINT8_T,  bMaxPower, ) \
259184610Salfred
260184610SalfredLIBUSB20_MAKE_STRUCT(LIBUSB20_CONFIG_DESC);
261184610Salfred
262184610Salfred#define	LIBUSB20_CONTROL_SETUP(m,n) \
263184610Salfred  m(n, UINT8_T,  bmRequestType, ) \
264184610Salfred  m(n, UINT8_T,  bRequest, ) \
265184610Salfred  m(n, UINT16_T, wValue, ) \
266184610Salfred  m(n, UINT16_T, wIndex, ) \
267184610Salfred  m(n, UINT16_T, wLength, ) \
268184610Salfred
269184610SalfredLIBUSB20_MAKE_STRUCT(LIBUSB20_CONTROL_SETUP);
270184610Salfred
271227404Shselasky#define	LIBUSB20_SS_ENDPT_COMP_DESC(m,n) \
272227404Shselasky  m(n, UINT8_T,  bLength, ) \
273227404Shselasky  m(n, UINT8_T,  bDescriptorType, ) \
274227404Shselasky  m(n, UINT8_T,  bMaxBurst, ) \
275227404Shselasky  m(n, UINT8_T,  bmAttributes, ) \
276227404Shselasky  m(n, UINT16_T, wBytesPerInterval, ) \
277227404Shselasky
278227404ShselaskyLIBUSB20_MAKE_STRUCT(LIBUSB20_SS_ENDPT_COMP_DESC);
279227404Shselasky
280227404Shselasky#define	LIBUSB20_USB_20_DEVCAP_DESC(m,n) \
281227404Shselasky  m(n, UINT8_T,  bLength, ) \
282227404Shselasky  m(n, UINT8_T,  bDescriptorType, ) \
283227404Shselasky  m(n, UINT8_T,  bDevCapabilityType, ) \
284227404Shselasky  m(n, UINT32_T, bmAttributes, ) \
285227404Shselasky
286227404ShselaskyLIBUSB20_MAKE_STRUCT(LIBUSB20_USB_20_DEVCAP_DESC);
287227404Shselasky
288227404Shselasky#define	LIBUSB20_SS_USB_DEVCAP_DESC(m,n) \
289227404Shselasky  m(n, UINT8_T,  bLength, ) \
290227404Shselasky  m(n, UINT8_T,  bDescriptorType, ) \
291227404Shselasky  m(n, UINT8_T,  bDevCapabilityType, ) \
292227404Shselasky  m(n, UINT8_T,  bmAttributes, ) \
293227404Shselasky  m(n, UINT16_T, wSpeedSupported, ) \
294227404Shselasky  m(n, UINT8_T,  bFunctionalitySupport, ) \
295227404Shselasky  m(n, UINT8_T,  bU1DevExitLat, ) \
296227404Shselasky  m(n, UINT16_T, wU2DevExitLat, ) \
297227404Shselasky
298227404ShselaskyLIBUSB20_MAKE_STRUCT(LIBUSB20_SS_USB_DEVCAP_DESC);
299227404Shselasky
300227404Shselasky#define	LIBUSB20_BOS_DESCRIPTOR(m,n) \
301227404Shselasky  m(n, UINT8_T,  bLength, ) \
302227404Shselasky  m(n, UINT8_T,  bDescriptorType, ) \
303227404Shselasky  m(n, UINT16_T, wTotalLength, ) \
304227404Shselasky  m(n, UINT8_T,  bNumDeviceCapabilities, ) \
305227404Shselasky
306227404ShselaskyLIBUSB20_MAKE_STRUCT(LIBUSB20_BOS_DESCRIPTOR);
307227404Shselasky
308184610Salfred/* standard USB stuff */
309184610Salfred
310184610Salfred/** \ingroup desc
311184610Salfred * Device and/or Interface Class codes */
312184610Salfredenum libusb20_class_code {
313184610Salfred	/** In the context of a \ref LIBUSB20_DEVICE_DESC "device
314184610Salfred	 * descriptor", this bDeviceClass value indicates that each
315184610Salfred	 * interface specifies its own class information and all
316184610Salfred	 * interfaces operate independently.
317184610Salfred	 */
318184610Salfred	LIBUSB20_CLASS_PER_INTERFACE = 0,
319184610Salfred
320184610Salfred	/** Audio class */
321184610Salfred	LIBUSB20_CLASS_AUDIO = 1,
322184610Salfred
323184610Salfred	/** Communications class */
324184610Salfred	LIBUSB20_CLASS_COMM = 2,
325184610Salfred
326184610Salfred	/** Human Interface Device class */
327184610Salfred	LIBUSB20_CLASS_HID = 3,
328184610Salfred
329184610Salfred	/** Printer dclass */
330184610Salfred	LIBUSB20_CLASS_PRINTER = 7,
331184610Salfred
332184610Salfred	/** Picture transfer protocol class */
333184610Salfred	LIBUSB20_CLASS_PTP = 6,
334184610Salfred
335184610Salfred	/** Mass storage class */
336184610Salfred	LIBUSB20_CLASS_MASS_STORAGE = 8,
337184610Salfred
338184610Salfred	/** Hub class */
339184610Salfred	LIBUSB20_CLASS_HUB = 9,
340184610Salfred
341184610Salfred	/** Data class */
342184610Salfred	LIBUSB20_CLASS_DATA = 10,
343184610Salfred
344184610Salfred	/** Class is vendor-specific */
345184610Salfred	LIBUSB20_CLASS_VENDOR_SPEC = 0xff,
346184610Salfred};
347184610Salfred
348184610Salfred/** \ingroup desc
349184610Salfred * Descriptor types as defined by the USB specification. */
350184610Salfredenum libusb20_descriptor_type {
351184610Salfred	/** Device descriptor. See LIBUSB20_DEVICE_DESC. */
352184610Salfred	LIBUSB20_DT_DEVICE = 0x01,
353184610Salfred
354184610Salfred	/** Configuration descriptor. See LIBUSB20_CONFIG_DESC. */
355184610Salfred	LIBUSB20_DT_CONFIG = 0x02,
356184610Salfred
357184610Salfred	/** String descriptor */
358184610Salfred	LIBUSB20_DT_STRING = 0x03,
359184610Salfred
360184610Salfred	/** Interface descriptor. See LIBUSB20_INTERFACE_DESC. */
361184610Salfred	LIBUSB20_DT_INTERFACE = 0x04,
362184610Salfred
363184610Salfred	/** Endpoint descriptor. See LIBUSB20_ENDPOINT_DESC. */
364184610Salfred	LIBUSB20_DT_ENDPOINT = 0x05,
365184610Salfred
366184610Salfred	/** HID descriptor */
367184610Salfred	LIBUSB20_DT_HID = 0x21,
368184610Salfred
369184610Salfred	/** HID report descriptor */
370184610Salfred	LIBUSB20_DT_REPORT = 0x22,
371184610Salfred
372184610Salfred	/** Physical descriptor */
373184610Salfred	LIBUSB20_DT_PHYSICAL = 0x23,
374184610Salfred
375184610Salfred	/** Hub descriptor */
376184610Salfred	LIBUSB20_DT_HUB = 0x29,
377227404Shselasky
378227404Shselasky	/** Binary Object Store, BOS */
379227404Shselasky	LIBUSB20_DT_BOS = 0x0f,
380227404Shselasky
381227404Shselasky	/** Device Capability */
382227404Shselasky	LIBUSB20_DT_DEVICE_CAPABILITY = 0x10,
383227404Shselasky
384227404Shselasky	/** SuperSpeed endpoint companion */
385227404Shselasky	LIBUSB20_DT_SS_ENDPOINT_COMPANION = 0x30,
386184610Salfred};
387184610Salfred
388227404Shselasky/** \ingroup desc
389227404Shselasky * Device capability types as defined by the USB specification. */
390227404Shselaskyenum libusb20_device_capability_type {
391227404Shselasky	LIBUSB20_WIRELESS_USB_DEVICE_CAPABILITY = 0x1,
392227404Shselasky	LIBUSB20_USB_2_0_EXTENSION_DEVICE_CAPABILITY = 0x2,
393227404Shselasky	LIBUSB20_SS_USB_DEVICE_CAPABILITY = 0x3,
394227404Shselasky	LIBUSB20_CONTAINER_ID_DEVICE_CAPABILITY = 0x4,
395227404Shselasky};
396227404Shselasky
397184610Salfred/* Descriptor sizes per descriptor type */
398184610Salfred#define	LIBUSB20_DT_DEVICE_SIZE			18
399184610Salfred#define	LIBUSB20_DT_CONFIG_SIZE			9
400184610Salfred#define	LIBUSB20_DT_INTERFACE_SIZE		9
401184610Salfred#define	LIBUSB20_DT_ENDPOINT_SIZE		7
402184610Salfred#define	LIBUSB20_DT_ENDPOINT_AUDIO_SIZE		9	/* Audio extension */
403184610Salfred#define	LIBUSB20_DT_HUB_NONVAR_SIZE		7
404227404Shselasky#define	LIBUSB20_DT_SS_ENDPOINT_COMPANION_SIZE	6
405227404Shselasky#define	LIBUSB20_DT_BOS_SIZE		5
406227404Shselasky#define	LIBUSB20_USB_2_0_EXTENSION_DEVICE_CAPABILITY_SIZE	7
407227404Shselasky#define	LIBUSB20_SS_USB_DEVICE_CAPABILITY_SIZE	10
408184610Salfred
409184610Salfred#define	LIBUSB20_ENDPOINT_ADDRESS_MASK	0x0f	/* in bEndpointAddress */
410184610Salfred#define	LIBUSB20_ENDPOINT_DIR_MASK	0x80
411184610Salfred
412184610Salfred/** \ingroup desc
413184610Salfred * Endpoint direction. Values for bit 7 of the
414184610Salfred * \ref LIBUSB20_ENDPOINT_DESC::bEndpointAddress "endpoint address" scheme.
415184610Salfred */
416184610Salfredenum libusb20_endpoint_direction {
417184610Salfred	/** In: device-to-host */
418184610Salfred	LIBUSB20_ENDPOINT_IN = 0x80,
419184610Salfred
420184610Salfred	/** Out: host-to-device */
421184610Salfred	LIBUSB20_ENDPOINT_OUT = 0x00,
422184610Salfred};
423184610Salfred
424184610Salfred#define	LIBUSB20_TRANSFER_TYPE_MASK	0x03	/* in bmAttributes */
425184610Salfred
426184610Salfred/** \ingroup desc
427184610Salfred * Endpoint transfer type. Values for bits 0:1 of the
428184610Salfred * \ref LIBUSB20_ENDPOINT_DESC::bmAttributes "endpoint attributes" field.
429184610Salfred */
430184610Salfredenum libusb20_transfer_type {
431184610Salfred	/** Control endpoint */
432184610Salfred	LIBUSB20_TRANSFER_TYPE_CONTROL = 0,
433184610Salfred
434184610Salfred	/** Isochronous endpoint */
435184610Salfred	LIBUSB20_TRANSFER_TYPE_ISOCHRONOUS = 1,
436184610Salfred
437184610Salfred	/** Bulk endpoint */
438184610Salfred	LIBUSB20_TRANSFER_TYPE_BULK = 2,
439184610Salfred
440184610Salfred	/** Interrupt endpoint */
441184610Salfred	LIBUSB20_TRANSFER_TYPE_INTERRUPT = 3,
442184610Salfred};
443184610Salfred
444184610Salfred/** \ingroup misc
445184610Salfred * Standard requests, as defined in table 9-3 of the USB2 specifications */
446184610Salfredenum libusb20_standard_request {
447184610Salfred	/** Request status of the specific recipient */
448184610Salfred	LIBUSB20_REQUEST_GET_STATUS = 0x00,
449184610Salfred
450184610Salfred	/** Clear or disable a specific feature */
451184610Salfred	LIBUSB20_REQUEST_CLEAR_FEATURE = 0x01,
452184610Salfred
453184610Salfred	/* 0x02 is reserved */
454184610Salfred
455184610Salfred	/** Set or enable a specific feature */
456184610Salfred	LIBUSB20_REQUEST_SET_FEATURE = 0x03,
457184610Salfred
458184610Salfred	/* 0x04 is reserved */
459184610Salfred
460184610Salfred	/** Set device address for all future accesses */
461184610Salfred	LIBUSB20_REQUEST_SET_ADDRESS = 0x05,
462184610Salfred
463184610Salfred	/** Get the specified descriptor */
464184610Salfred	LIBUSB20_REQUEST_GET_DESCRIPTOR = 0x06,
465184610Salfred
466184610Salfred	/** Used to update existing descriptors or add new descriptors */
467184610Salfred	LIBUSB20_REQUEST_SET_DESCRIPTOR = 0x07,
468184610Salfred
469184610Salfred	/** Get the current device configuration value */
470184610Salfred	LIBUSB20_REQUEST_GET_CONFIGURATION = 0x08,
471184610Salfred
472184610Salfred	/** Set device configuration */
473184610Salfred	LIBUSB20_REQUEST_SET_CONFIGURATION = 0x09,
474184610Salfred
475184610Salfred	/** Return the selected alternate setting for the specified
476184610Salfred	 * interface */
477184610Salfred	LIBUSB20_REQUEST_GET_INTERFACE = 0x0A,
478184610Salfred
479184610Salfred	/** Select an alternate interface for the specified interface */
480184610Salfred	LIBUSB20_REQUEST_SET_INTERFACE = 0x0B,
481184610Salfred
482184610Salfred	/** Set then report an endpoint's synchronization frame */
483184610Salfred	LIBUSB20_REQUEST_SYNCH_FRAME = 0x0C,
484277245Shselasky
485277245Shselasky	/** Set U1 and U2 system exit latency */
486277245Shselasky	LIBUSB20_REQUEST_SET_SEL = 0x30,
487277245Shselasky
488277245Shselasky	/** Set isochronous delay */
489277245Shselasky	LIBUSB20_REQUEST_SET_ISOCH_DELAY = 0x31,
490184610Salfred};
491184610Salfred
492184610Salfred/** \ingroup misc
493184610Salfred * Request type bits of the
494184610Salfred * \ref libusb20_control_setup::bmRequestType "bmRequestType" field in
495184610Salfred * control transfers. */
496184610Salfredenum libusb20_request_type {
497184610Salfred	/** Standard */
498184610Salfred	LIBUSB20_REQUEST_TYPE_STANDARD = (0x00 << 5),
499184610Salfred
500184610Salfred	/** Class */
501184610Salfred	LIBUSB20_REQUEST_TYPE_CLASS = (0x01 << 5),
502184610Salfred
503184610Salfred	/** Vendor */
504184610Salfred	LIBUSB20_REQUEST_TYPE_VENDOR = (0x02 << 5),
505184610Salfred
506184610Salfred	/** Reserved */
507184610Salfred	LIBUSB20_REQUEST_TYPE_RESERVED = (0x03 << 5),
508184610Salfred};
509184610Salfred
510184610Salfred/** \ingroup misc
511184610Salfred * Recipient bits of the
512184610Salfred * \ref libusb20_control_setup::bmRequestType "bmRequestType" field in
513184610Salfred * control transfers. Values 4 through 31 are reserved. */
514184610Salfredenum libusb20_request_recipient {
515184610Salfred	/** Device */
516184610Salfred	LIBUSB20_RECIPIENT_DEVICE = 0x00,
517184610Salfred
518184610Salfred	/** Interface */
519184610Salfred	LIBUSB20_RECIPIENT_INTERFACE = 0x01,
520184610Salfred
521184610Salfred	/** Endpoint */
522184610Salfred	LIBUSB20_RECIPIENT_ENDPOINT = 0x02,
523184610Salfred
524184610Salfred	/** Other */
525184610Salfred	LIBUSB20_RECIPIENT_OTHER = 0x03,
526184610Salfred};
527184610Salfred
528184610Salfred#define	LIBUSB20_ISO_SYNC_TYPE_MASK		0x0C
529184610Salfred
530184610Salfred/** \ingroup desc
531184610Salfred * Synchronization type for isochronous endpoints. Values for bits 2:3
532184610Salfred * of the \ref LIBUSB20_ENDPOINT_DESC::bmAttributes "bmAttributes"
533184610Salfred * field in LIBUSB20_ENDPOINT_DESC.
534184610Salfred */
535184610Salfredenum libusb20_iso_sync_type {
536184610Salfred	/** No synchronization */
537184610Salfred	LIBUSB20_ISO_SYNC_TYPE_NONE = 0,
538184610Salfred
539184610Salfred	/** Asynchronous */
540184610Salfred	LIBUSB20_ISO_SYNC_TYPE_ASYNC = 1,
541184610Salfred
542184610Salfred	/** Adaptive */
543184610Salfred	LIBUSB20_ISO_SYNC_TYPE_ADAPTIVE = 2,
544184610Salfred
545184610Salfred	/** Synchronous */
546184610Salfred	LIBUSB20_ISO_SYNC_TYPE_SYNC = 3,
547184610Salfred};
548184610Salfred
549184610Salfred#define	LIBUSB20_ISO_USAGE_TYPE_MASK 0x30
550184610Salfred
551184610Salfred/** \ingroup desc
552184610Salfred * Usage type for isochronous endpoints. Values for bits 4:5 of the
553184610Salfred * \ref LIBUSB20_ENDPOINT_DESC::bmAttributes "bmAttributes" field in
554184610Salfred * LIBUSB20_ENDPOINT_DESC.
555184610Salfred */
556184610Salfredenum libusb20_iso_usage_type {
557184610Salfred	/** Data endpoint */
558184610Salfred	LIBUSB20_ISO_USAGE_TYPE_DATA = 0,
559184610Salfred
560184610Salfred	/** Feedback endpoint */
561184610Salfred	LIBUSB20_ISO_USAGE_TYPE_FEEDBACK = 1,
562184610Salfred
563184610Salfred	/** Implicit feedback Data endpoint */
564184610Salfred	LIBUSB20_ISO_USAGE_TYPE_IMPLICIT = 2,
565184610Salfred};
566184610Salfred
567184610Salfredstruct libusb20_endpoint {
568184610Salfred	struct LIBUSB20_ENDPOINT_DESC_DECODED desc;
569184610Salfred	struct libusb20_me_struct extra;
570184610Salfred} __aligned(sizeof(void *));
571184610Salfred
572184610Salfredstruct libusb20_interface {
573184610Salfred	struct LIBUSB20_INTERFACE_DESC_DECODED desc;
574184610Salfred	struct libusb20_me_struct extra;
575184610Salfred	struct libusb20_interface *altsetting;
576184610Salfred	struct libusb20_endpoint *endpoints;
577184610Salfred	uint8_t	num_altsetting;
578184610Salfred	uint8_t	num_endpoints;
579184610Salfred} __aligned(sizeof(void *));
580184610Salfred
581184610Salfredstruct libusb20_config {
582184610Salfred	struct LIBUSB20_CONFIG_DESC_DECODED desc;
583184610Salfred	struct libusb20_me_struct extra;
584184610Salfred	struct libusb20_interface *interface;
585184610Salfred	uint8_t	num_interface;
586184610Salfred} __aligned(sizeof(void *));
587184610Salfred
588184610Salfreduint8_t	libusb20_me_get_1(const struct libusb20_me_struct *ie, uint16_t offset);
589184610Salfreduint16_t libusb20_me_get_2(const struct libusb20_me_struct *ie, uint16_t offset);
590184610Salfreduint16_t libusb20_me_encode(void *ptr, uint16_t len, const void *pd);
591184610Salfreduint16_t libusb20_me_decode(const void *ptr, uint16_t len, void *pd);
592184610Salfredconst uint8_t *libusb20_desc_foreach(const struct libusb20_me_struct *pdesc, const uint8_t *psubdesc);
593184610Salfredstruct libusb20_config *libusb20_parse_config_desc(const void *config_desc);
594184610Salfred
595184610Salfred#if 0
596184610Salfred{					/* style */
597184610Salfred#endif
598184610Salfred#ifdef __cplusplus
599184610Salfred}
600184610Salfred
601184610Salfred#endif
602184610Salfred
603184610Salfred#endif					/* _LIBUSB20_DESC_H_ */
604