libusb20_desc.h revision 184610
1/* $FreeBSD: head/lib/libusb20/libusb20_desc.h 184610 2008-11-04 02:31:03Z alfred $ */
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
49extern	"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)))
67
68/* basic message elements */
69enum {
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 */
79enum {
80	LIBUSB20_ME_IS_UNSIGNED = 0x00,
81	LIBUSB20_ME_IS_SIGNED = 0x80,
82	LIBUSB20_ME_MASK = 0x7F,
83};
84
85enum {
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
97struct 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
103struct 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
219LIBUSB20_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
231LIBUSB20_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
244LIBUSB20_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
256LIBUSB20_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
265LIBUSB20_MAKE_STRUCT(LIBUSB20_CONTROL_SETUP);
266
267/* standard USB stuff */
268
269/** \ingroup desc
270 * Device and/or Interface Class codes */
271enum 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. */
309enum 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 */
353enum 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 */
367enum 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 */
383enum 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. */
427enum 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. */
445enum 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 */
466enum 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 */
487enum 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
498struct libusb20_endpoint {
499	struct LIBUSB20_ENDPOINT_DESC_DECODED desc;
500	struct libusb20_me_struct extra;
501} __aligned(sizeof(void *));
502
503struct 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
512struct 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
519uint8_t	libusb20_me_get_1(const struct libusb20_me_struct *ie, uint16_t offset);
520uint16_t libusb20_me_get_2(const struct libusb20_me_struct *ie, uint16_t offset);
521uint16_t libusb20_me_encode(void *ptr, uint16_t len, const void *pd);
522uint16_t libusb20_me_decode(const void *ptr, uint16_t len, void *pd);
523const uint8_t *libusb20_desc_foreach(const struct libusb20_me_struct *pdesc, const uint8_t *psubdesc);
524struct 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