xref: /freebsd/lib/libusb/libusb20_desc.h (revision 6472ac3d8a86336899b6cfb789a4cd9897e3fab5)
1 /* $FreeBSD$ */
2 /*-
3  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4  * Copyright (c) 2007-2008 Daniel Drake.  All rights reserved.
5  * Copyright (c) 2001 Johannes Erdfelt.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 /*
30  * NOTE: This file contains the definition of some standard USB
31  * structures. All structures which name ends by *DECODED use host byte
32  * order.
33  */
34 
35 /*
36  * NOTE: This file uses a lot of macros. If you want to see what the
37  * macros become when they are expanded then run the following
38  * commands from your shell:
39  *
40  * cpp libusb20_desc.h > temp.h
41  * indent temp.h
42  * less temp.h
43  */
44 
45 #ifndef _LIBUSB20_DESC_H_
46 #define	_LIBUSB20_DESC_H_
47 
48 #ifdef __cplusplus
49 extern	"C" {
50 #endif
51 #if 0
52 };					/* style */
53 
54 #endif
55 /* basic macros */
56 
57 #define	LIBUSB20__NOT(...) __VA_ARGS__
58 #define	LIBUSB20_NOT(arg) LIBUSB20__NOT(LIBUSB20_YES arg(() LIBUSB20_NO))
59 #define	LIBUSB20_YES(...) __VA_ARGS__
60 #define	LIBUSB20_NO(...)
61 #define	LIBUSB20_END(...) __VA_ARGS__
62 #define	LIBUSB20_MAX(a,b) (((a) > (b)) ? (a) : (b))
63 #define	LIBUSB20_MIN(a,b) (((a) < (b)) ? (a) : (b))
64 
65 #define	LIBUSB20_ADD_BYTES(ptr,off) \
66   ((void *)(((const uint8_t *)(ptr)) + (off) - ((const uint8_t *)0)))
67 
68 /* basic message elements */
69 enum {
70 	LIBUSB20_ME_INT8,
71 	LIBUSB20_ME_INT16,
72 	LIBUSB20_ME_INT32,
73 	LIBUSB20_ME_INT64,
74 	LIBUSB20_ME_STRUCT,
75 	LIBUSB20_ME_MAX,		/* used to indicate end */
76 };
77 
78 /* basic message element modifiers */
79 enum {
80 	LIBUSB20_ME_IS_UNSIGNED = 0x00,
81 	LIBUSB20_ME_IS_SIGNED = 0x80,
82 	LIBUSB20_ME_MASK = 0x7F,
83 };
84 
85 enum {
86 	LIBUSB20_ME_IS_RAW,		/* structure excludes length field
87 					 * (hardcoded value) */
88 	LIBUSB20_ME_IS_ENCODED,		/* structure includes length field */
89 	LIBUSB20_ME_IS_EMPTY,		/* no structure */
90 	LIBUSB20_ME_IS_DECODED,		/* structure is recursive */
91 };
92 
93 /* basic helper structures and macros */
94 
95 #define	LIBUSB20_ME_STRUCT_ALIGN sizeof(void *)
96 
97 struct libusb20_me_struct {
98 	void   *ptr;			/* data pointer */
99 	uint16_t len;			/* defaults to zero */
100 	uint16_t type;			/* defaults to LIBUSB20_ME_IS_EMPTY */
101 } __aligned(LIBUSB20_ME_STRUCT_ALIGN);
102 
103 struct libusb20_me_format {
104 	const uint8_t *format;		/* always set */
105 	const char *desc;		/* optionally set */
106 	const char *fields;		/* optionally set */
107 };
108 
109 #define	LIBUSB20_ME_STRUCT(n, field, arg, ismeta)		\
110   ismeta ( LIBUSB20_ME_STRUCT, 1, 0, )			\
111   LIBUSB20_NOT(ismeta) ( struct libusb20_me_struct field; )
112 
113 #define	LIBUSB20_ME_STRUCT_ARRAY(n, field, arg, ismeta)	\
114   ismeta ( LIBUSB20_ME_STRUCT , (arg) & 0xFF,		\
115 	   ((arg) / 0x100) & 0xFF, )			\
116   LIBUSB20_NOT(ismeta) ( struct libusb20_me_struct field [arg]; )
117 
118 #define	LIBUSB20_ME_INTEGER(n, field, ismeta, un, u, bits, a, size)	\
119   ismeta ( LIBUSB20_ME_INT##bits |					\
120 	   LIBUSB20_ME_IS_##un##SIGNED ,				\
121 	   (size) & 0xFF, ((size) / 0x100) & 0xFF, )		\
122   LIBUSB20_NOT(ismeta) ( u##int##bits##_t				\
123 		    __aligned((bits) / 8) field a; )
124 
125 #define	LIBUSB20_ME_UINT8_T(n, field, arg, ismeta) \
126   LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 8, , 1)
127 
128 #define	LIBUSB20_ME_UINT8_ARRAY_T(n, field, arg, ismeta) \
129   LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 8, [arg], arg)
130 
131 #define	LIBUSB20_ME_SINT8_T(n, field, arg, ismeta) \
132   LIBUSB20_ME_INTEGER(n, field, ismeta,,, 8, , 1)
133 
134 #define	LIBUSB20_ME_SINT8_ARRAY_T(n, field, arg, ismeta) \
135   LIBUSB20_ME_INTEGER(n, field, ismeta,,, 8, [arg], arg)
136 
137 #define	LIBUSB20_ME_UINT16_T(n, field, arg, ismeta) \
138   LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 16, , 1)
139 
140 #define	LIBUSB20_ME_UINT16_ARRAY_T(n, field, arg, ismeta) \
141   LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 16, [arg], arg)
142 
143 #define	LIBUSB20_ME_SINT16_T(n, field, arg, ismeta) \
144   LIBUSB20_ME_INTEGER(n, field, ismeta,,, 16, , 1)
145 
146 #define	LIBUSB20_ME_SINT16_ARRAY_T(n, field, arg, ismeta) \
147   LIBUSB20_ME_INTEGER(n, field, ismeta,,, 16, [arg], arg)
148 
149 #define	LIBUSB20_ME_UINT32_T(n, field, arg, ismeta) \
150   LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 32, , 1)
151 
152 #define	LIBUSB20_ME_UINT32_ARRAY_T(n, field, arg, ismeta) \
153   LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 32, [arg], arg)
154 
155 #define	LIBUSB20_ME_SINT32_T(n, field, arg, ismeta) \
156   LIBUSB20_ME_INTEGER(n, field, ismeta,,, 32, , 1)
157 
158 #define	LIBUSB20_ME_SINT32_ARRAY_T(n, field, arg, ismeta) \
159   LIBUSB20_ME_INTEGER(n, field, ismeta,,, 32, [arg], arg)
160 
161 #define	LIBUSB20_ME_UINT64_T(n, field, arg, ismeta) \
162   LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 64, , 1)
163 
164 #define	LIBUSB20_ME_UINT64_ARRAY_T(n, field, arg, ismeta) \
165   LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 64, [arg], arg)
166 
167 #define	LIBUSB20_ME_SINT64_T(n, field, arg, ismeta) \
168   LIBUSB20_ME_INTEGER(n, field, ismeta,,, 64, , 1)
169 
170 #define	LIBUSB20_ME_SINT64_ARRAY_T(n, field, arg, ismeta) \
171   LIBUSB20_ME_INTEGER(n, field, ismeta,,, 64, [arg], arg)
172 
173 #define	LIBUSB20_MAKE_DECODED_FIELD(n, type, field, arg) \
174   LIBUSB20_ME_##type (n, field, arg, LIBUSB20_NO)
175 
176 #define	LIBUSB20_MAKE_STRUCT(name)			\
177   extern const struct libusb20_me_format			\
178 	 name##_FORMAT[1];				\
179   struct name##_DECODED {				\
180     const struct libusb20_me_format *name##_FORMAT;	\
181     name (LIBUSB20_MAKE_DECODED_FIELD,)			\
182   }
183 
184 #define	LIBUSB20_MAKE_STRUCT_FORMAT(name)		\
185   const struct libusb20_me_format			\
186     name##_FORMAT[1] = {{			\
187       .format = LIBUSB20_MAKE_FORMAT(name),	\
188       .desc = #name,				\
189       .fields = NULL,				\
190   }}
191 
192 #define	LIBUSB20_MAKE_FORMAT_SUB(n, type, field, arg) \
193   LIBUSB20_ME_##type (n, field, arg, LIBUSB20_YES)
194 
195 #define	LIBUSB20_MAKE_FORMAT(what) (const uint8_t []) \
196   { what (LIBUSB20_MAKE_FORMAT_SUB, ) LIBUSB20_ME_MAX, 0, 0 }
197 
198 #define	LIBUSB20_INIT(what, ptr) do {		\
199     memset(ptr, 0, sizeof(*(ptr)));		\
200     (ptr)->what##_FORMAT = what##_FORMAT;	\
201 } while (0)
202 
203 #define	LIBUSB20_DEVICE_DESC(m,n) \
204   m(n, UINT8_T, bLength, ) \
205   m(n, UINT8_T, bDescriptorType, ) \
206   m(n, UINT16_T, bcdUSB, ) \
207   m(n, UINT8_T, bDeviceClass, ) \
208   m(n, UINT8_T, bDeviceSubClass, ) \
209   m(n, UINT8_T, bDeviceProtocol, ) \
210   m(n, UINT8_T, bMaxPacketSize0, ) \
211   m(n, UINT16_T, idVendor, ) \
212   m(n, UINT16_T, idProduct, ) \
213   m(n, UINT16_T, bcdDevice, ) \
214   m(n, UINT8_T, iManufacturer, ) \
215   m(n, UINT8_T, iProduct, ) \
216   m(n, UINT8_T, iSerialNumber, ) \
217   m(n, UINT8_T, bNumConfigurations, ) \
218 
219 LIBUSB20_MAKE_STRUCT(LIBUSB20_DEVICE_DESC);
220 
221 #define	LIBUSB20_ENDPOINT_DESC(m,n) \
222   m(n, UINT8_T,  bLength, ) \
223   m(n, UINT8_T,  bDescriptorType, ) \
224   m(n, UINT8_T,  bEndpointAddress, ) \
225   m(n, UINT8_T,  bmAttributes, ) \
226   m(n, UINT16_T, wMaxPacketSize, ) \
227   m(n, UINT8_T,  bInterval, ) \
228   m(n, UINT8_T,  bRefresh, ) \
229   m(n, UINT8_T,  bSynchAddress, ) \
230 
231 LIBUSB20_MAKE_STRUCT(LIBUSB20_ENDPOINT_DESC);
232 
233 #define	LIBUSB20_INTERFACE_DESC(m,n) \
234   m(n, UINT8_T,  bLength, ) \
235   m(n, UINT8_T,  bDescriptorType, ) \
236   m(n, UINT8_T,  bInterfaceNumber, ) \
237   m(n, UINT8_T,  bAlternateSetting, ) \
238   m(n, UINT8_T,  bNumEndpoints, ) \
239   m(n, UINT8_T,  bInterfaceClass, ) \
240   m(n, UINT8_T,  bInterfaceSubClass, ) \
241   m(n, UINT8_T,  bInterfaceProtocol, ) \
242   m(n, UINT8_T,  iInterface, ) \
243 
244 LIBUSB20_MAKE_STRUCT(LIBUSB20_INTERFACE_DESC);
245 
246 #define	LIBUSB20_CONFIG_DESC(m,n) \
247   m(n, UINT8_T,  bLength, ) \
248   m(n, UINT8_T,  bDescriptorType, ) \
249   m(n, UINT16_T, wTotalLength, ) \
250   m(n, UINT8_T,  bNumInterfaces, ) \
251   m(n, UINT8_T,  bConfigurationValue, ) \
252   m(n, UINT8_T,  iConfiguration, ) \
253   m(n, UINT8_T,  bmAttributes, ) \
254   m(n, UINT8_T,  bMaxPower, ) \
255 
256 LIBUSB20_MAKE_STRUCT(LIBUSB20_CONFIG_DESC);
257 
258 #define	LIBUSB20_CONTROL_SETUP(m,n) \
259   m(n, UINT8_T,  bmRequestType, ) \
260   m(n, UINT8_T,  bRequest, ) \
261   m(n, UINT16_T, wValue, ) \
262   m(n, UINT16_T, wIndex, ) \
263   m(n, UINT16_T, wLength, ) \
264 
265 LIBUSB20_MAKE_STRUCT(LIBUSB20_CONTROL_SETUP);
266 
267 /* standard USB stuff */
268 
269 /** \ingroup desc
270  * Device and/or Interface Class codes */
271 enum libusb20_class_code {
272 	/** In the context of a \ref LIBUSB20_DEVICE_DESC "device
273 	 * descriptor", this bDeviceClass value indicates that each
274 	 * interface specifies its own class information and all
275 	 * interfaces operate independently.
276 	 */
277 	LIBUSB20_CLASS_PER_INTERFACE = 0,
278 
279 	/** Audio class */
280 	LIBUSB20_CLASS_AUDIO = 1,
281 
282 	/** Communications class */
283 	LIBUSB20_CLASS_COMM = 2,
284 
285 	/** Human Interface Device class */
286 	LIBUSB20_CLASS_HID = 3,
287 
288 	/** Printer dclass */
289 	LIBUSB20_CLASS_PRINTER = 7,
290 
291 	/** Picture transfer protocol class */
292 	LIBUSB20_CLASS_PTP = 6,
293 
294 	/** Mass storage class */
295 	LIBUSB20_CLASS_MASS_STORAGE = 8,
296 
297 	/** Hub class */
298 	LIBUSB20_CLASS_HUB = 9,
299 
300 	/** Data class */
301 	LIBUSB20_CLASS_DATA = 10,
302 
303 	/** Class is vendor-specific */
304 	LIBUSB20_CLASS_VENDOR_SPEC = 0xff,
305 };
306 
307 /** \ingroup desc
308  * Descriptor types as defined by the USB specification. */
309 enum libusb20_descriptor_type {
310 	/** Device descriptor. See LIBUSB20_DEVICE_DESC. */
311 	LIBUSB20_DT_DEVICE = 0x01,
312 
313 	/** Configuration descriptor. See LIBUSB20_CONFIG_DESC. */
314 	LIBUSB20_DT_CONFIG = 0x02,
315 
316 	/** String descriptor */
317 	LIBUSB20_DT_STRING = 0x03,
318 
319 	/** Interface descriptor. See LIBUSB20_INTERFACE_DESC. */
320 	LIBUSB20_DT_INTERFACE = 0x04,
321 
322 	/** Endpoint descriptor. See LIBUSB20_ENDPOINT_DESC. */
323 	LIBUSB20_DT_ENDPOINT = 0x05,
324 
325 	/** HID descriptor */
326 	LIBUSB20_DT_HID = 0x21,
327 
328 	/** HID report descriptor */
329 	LIBUSB20_DT_REPORT = 0x22,
330 
331 	/** Physical descriptor */
332 	LIBUSB20_DT_PHYSICAL = 0x23,
333 
334 	/** Hub descriptor */
335 	LIBUSB20_DT_HUB = 0x29,
336 };
337 
338 /* Descriptor sizes per descriptor type */
339 #define	LIBUSB20_DT_DEVICE_SIZE			18
340 #define	LIBUSB20_DT_CONFIG_SIZE			9
341 #define	LIBUSB20_DT_INTERFACE_SIZE		9
342 #define	LIBUSB20_DT_ENDPOINT_SIZE		7
343 #define	LIBUSB20_DT_ENDPOINT_AUDIO_SIZE		9	/* Audio extension */
344 #define	LIBUSB20_DT_HUB_NONVAR_SIZE		7
345 
346 #define	LIBUSB20_ENDPOINT_ADDRESS_MASK	0x0f	/* in bEndpointAddress */
347 #define	LIBUSB20_ENDPOINT_DIR_MASK	0x80
348 
349 /** \ingroup desc
350  * Endpoint direction. Values for bit 7 of the
351  * \ref LIBUSB20_ENDPOINT_DESC::bEndpointAddress "endpoint address" scheme.
352  */
353 enum libusb20_endpoint_direction {
354 	/** In: device-to-host */
355 	LIBUSB20_ENDPOINT_IN = 0x80,
356 
357 	/** Out: host-to-device */
358 	LIBUSB20_ENDPOINT_OUT = 0x00,
359 };
360 
361 #define	LIBUSB20_TRANSFER_TYPE_MASK	0x03	/* in bmAttributes */
362 
363 /** \ingroup desc
364  * Endpoint transfer type. Values for bits 0:1 of the
365  * \ref LIBUSB20_ENDPOINT_DESC::bmAttributes "endpoint attributes" field.
366  */
367 enum libusb20_transfer_type {
368 	/** Control endpoint */
369 	LIBUSB20_TRANSFER_TYPE_CONTROL = 0,
370 
371 	/** Isochronous endpoint */
372 	LIBUSB20_TRANSFER_TYPE_ISOCHRONOUS = 1,
373 
374 	/** Bulk endpoint */
375 	LIBUSB20_TRANSFER_TYPE_BULK = 2,
376 
377 	/** Interrupt endpoint */
378 	LIBUSB20_TRANSFER_TYPE_INTERRUPT = 3,
379 };
380 
381 /** \ingroup misc
382  * Standard requests, as defined in table 9-3 of the USB2 specifications */
383 enum libusb20_standard_request {
384 	/** Request status of the specific recipient */
385 	LIBUSB20_REQUEST_GET_STATUS = 0x00,
386 
387 	/** Clear or disable a specific feature */
388 	LIBUSB20_REQUEST_CLEAR_FEATURE = 0x01,
389 
390 	/* 0x02 is reserved */
391 
392 	/** Set or enable a specific feature */
393 	LIBUSB20_REQUEST_SET_FEATURE = 0x03,
394 
395 	/* 0x04 is reserved */
396 
397 	/** Set device address for all future accesses */
398 	LIBUSB20_REQUEST_SET_ADDRESS = 0x05,
399 
400 	/** Get the specified descriptor */
401 	LIBUSB20_REQUEST_GET_DESCRIPTOR = 0x06,
402 
403 	/** Used to update existing descriptors or add new descriptors */
404 	LIBUSB20_REQUEST_SET_DESCRIPTOR = 0x07,
405 
406 	/** Get the current device configuration value */
407 	LIBUSB20_REQUEST_GET_CONFIGURATION = 0x08,
408 
409 	/** Set device configuration */
410 	LIBUSB20_REQUEST_SET_CONFIGURATION = 0x09,
411 
412 	/** Return the selected alternate setting for the specified
413 	 * interface */
414 	LIBUSB20_REQUEST_GET_INTERFACE = 0x0A,
415 
416 	/** Select an alternate interface for the specified interface */
417 	LIBUSB20_REQUEST_SET_INTERFACE = 0x0B,
418 
419 	/** Set then report an endpoint's synchronization frame */
420 	LIBUSB20_REQUEST_SYNCH_FRAME = 0x0C,
421 };
422 
423 /** \ingroup misc
424  * Request type bits of the
425  * \ref libusb20_control_setup::bmRequestType "bmRequestType" field in
426  * control transfers. */
427 enum libusb20_request_type {
428 	/** Standard */
429 	LIBUSB20_REQUEST_TYPE_STANDARD = (0x00 << 5),
430 
431 	/** Class */
432 	LIBUSB20_REQUEST_TYPE_CLASS = (0x01 << 5),
433 
434 	/** Vendor */
435 	LIBUSB20_REQUEST_TYPE_VENDOR = (0x02 << 5),
436 
437 	/** Reserved */
438 	LIBUSB20_REQUEST_TYPE_RESERVED = (0x03 << 5),
439 };
440 
441 /** \ingroup misc
442  * Recipient bits of the
443  * \ref libusb20_control_setup::bmRequestType "bmRequestType" field in
444  * control transfers. Values 4 through 31 are reserved. */
445 enum libusb20_request_recipient {
446 	/** Device */
447 	LIBUSB20_RECIPIENT_DEVICE = 0x00,
448 
449 	/** Interface */
450 	LIBUSB20_RECIPIENT_INTERFACE = 0x01,
451 
452 	/** Endpoint */
453 	LIBUSB20_RECIPIENT_ENDPOINT = 0x02,
454 
455 	/** Other */
456 	LIBUSB20_RECIPIENT_OTHER = 0x03,
457 };
458 
459 #define	LIBUSB20_ISO_SYNC_TYPE_MASK		0x0C
460 
461 /** \ingroup desc
462  * Synchronization type for isochronous endpoints. Values for bits 2:3
463  * of the \ref LIBUSB20_ENDPOINT_DESC::bmAttributes "bmAttributes"
464  * field in LIBUSB20_ENDPOINT_DESC.
465  */
466 enum libusb20_iso_sync_type {
467 	/** No synchronization */
468 	LIBUSB20_ISO_SYNC_TYPE_NONE = 0,
469 
470 	/** Asynchronous */
471 	LIBUSB20_ISO_SYNC_TYPE_ASYNC = 1,
472 
473 	/** Adaptive */
474 	LIBUSB20_ISO_SYNC_TYPE_ADAPTIVE = 2,
475 
476 	/** Synchronous */
477 	LIBUSB20_ISO_SYNC_TYPE_SYNC = 3,
478 };
479 
480 #define	LIBUSB20_ISO_USAGE_TYPE_MASK 0x30
481 
482 /** \ingroup desc
483  * Usage type for isochronous endpoints. Values for bits 4:5 of the
484  * \ref LIBUSB20_ENDPOINT_DESC::bmAttributes "bmAttributes" field in
485  * LIBUSB20_ENDPOINT_DESC.
486  */
487 enum libusb20_iso_usage_type {
488 	/** Data endpoint */
489 	LIBUSB20_ISO_USAGE_TYPE_DATA = 0,
490 
491 	/** Feedback endpoint */
492 	LIBUSB20_ISO_USAGE_TYPE_FEEDBACK = 1,
493 
494 	/** Implicit feedback Data endpoint */
495 	LIBUSB20_ISO_USAGE_TYPE_IMPLICIT = 2,
496 };
497 
498 struct libusb20_endpoint {
499 	struct LIBUSB20_ENDPOINT_DESC_DECODED desc;
500 	struct libusb20_me_struct extra;
501 } __aligned(sizeof(void *));
502 
503 struct libusb20_interface {
504 	struct LIBUSB20_INTERFACE_DESC_DECODED desc;
505 	struct libusb20_me_struct extra;
506 	struct libusb20_interface *altsetting;
507 	struct libusb20_endpoint *endpoints;
508 	uint8_t	num_altsetting;
509 	uint8_t	num_endpoints;
510 } __aligned(sizeof(void *));
511 
512 struct libusb20_config {
513 	struct LIBUSB20_CONFIG_DESC_DECODED desc;
514 	struct libusb20_me_struct extra;
515 	struct libusb20_interface *interface;
516 	uint8_t	num_interface;
517 } __aligned(sizeof(void *));
518 
519 uint8_t	libusb20_me_get_1(const struct libusb20_me_struct *ie, uint16_t offset);
520 uint16_t libusb20_me_get_2(const struct libusb20_me_struct *ie, uint16_t offset);
521 uint16_t libusb20_me_encode(void *ptr, uint16_t len, const void *pd);
522 uint16_t libusb20_me_decode(const void *ptr, uint16_t len, void *pd);
523 const uint8_t *libusb20_desc_foreach(const struct libusb20_me_struct *pdesc, const uint8_t *psubdesc);
524 struct libusb20_config *libusb20_parse_config_desc(const void *config_desc);
525 
526 #if 0
527 {					/* style */
528 #endif
529 #ifdef __cplusplus
530 }
531 
532 #endif
533 
534 #endif					/* _LIBUSB20_DESC_H_ */
535