1 /* $FreeBSD: head/usr.sbin/usbconfig/dump.c 274435 2014-11-12 14:52:44Z hselasky $ */
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include <libusb20_desc.h>
41 #define DUMP0(n,type,field,...) dump_field(pdev, " ", #field, n->field);
42 #define DUMP1(n,type,field,...) dump_field(pdev, " ", #field, n->field);
43 #define DUMP2(n,type,field,...) dump_field(pdev, " ", #field, n->field);
44 #define DUMP3(n,type,field,...) dump_field(pdev, " ", #field, n->field);
47 dump_mode(uint8_t value
)
49 if (value
== LIBUSB20_MODE_HOST
)
55 dump_speed(uint8_t value
)
59 case LIBUSB20_SPEED_LOW
:
60 return ("LOW (1.5Mbps)");
61 case LIBUSB20_SPEED_FULL
:
62 return ("FULL (12Mbps)");
63 case LIBUSB20_SPEED_HIGH
:
64 return ("HIGH (480Mbps)");
65 case LIBUSB20_SPEED_VARIABLE
:
66 return ("VARIABLE (52-480Mbps)");
67 case LIBUSB20_SPEED_SUPER
:
68 return ("SUPER (5.0Gbps)");
72 return ("UNKNOWN ()");
76 dump_power_mode(uint8_t value
)
80 case LIBUSB20_POWER_OFF
:
82 case LIBUSB20_POWER_ON
:
84 case LIBUSB20_POWER_SAVE
:
86 case LIBUSB20_POWER_SUSPEND
:
88 case LIBUSB20_POWER_RESUME
:
96 dump_field(struct libusb20_device
*pdev
, const char *plevel
,
97 const char *field
, uint32_t value
)
99 uint8_t temp_string
[256];
101 printf("%s%s = 0x%04x ", plevel
, field
, value
);
103 if (strlen(plevel
) == 8) {
104 /* Endpoint Descriptor */
106 if (strcmp(field
, "bEndpointAddress") == 0) {
113 if (strcmp(field
, "bmAttributes") == 0) {
114 switch (value
& 0x03) {
116 printf(" <CONTROL>\n");
119 switch (value
& 0x0C) {
121 printf(" <ISOCHRONOUS>\n");
124 printf(" <ASYNC-ISOCHRONOUS>\n");
127 printf(" <ADAPT-ISOCHRONOUS>\n");
130 printf(" <SYNC-ISOCHRONOUS>\n");
138 printf(" <INTERRUPT>\n");
144 if ((field
[0] == 'i') && (field
[1] != 'd')) {
145 /* Indirect String Descriptor */
147 printf(" <no string>\n");
150 if (libusb20_dev_req_string_simple_sync(pdev
, value
,
151 temp_string
, sizeof(temp_string
))) {
152 printf(" <retrieving string failed>\n");
155 printf(" <%s>\n", temp_string
);
158 if (strlen(plevel
) == 2 || strlen(plevel
) == 6) {
160 /* Device and Interface Descriptor class codes */
162 if (strcmp(field
, "bInterfaceClass") == 0 ||
163 strcmp(field
, "bDeviceClass") == 0) {
167 printf(" <Probed by interface class>\n");
170 printf(" <Audio device>\n");
173 printf(" <Communication device>\n");
176 printf(" <HID device>\n");
179 printf(" <Physical device>\n");
182 printf(" <Still imaging>\n");
185 printf(" <Printer device>\n");
188 printf(" <Mass storage>\n");
194 printf(" <CDC-data>\n");
197 printf(" <Smart card>\n");
200 printf(" <Content security>\n");
203 printf(" <Video device>\n");
206 printf(" <Personal healthcare>\n");
209 printf(" <Audio and video device>\n");
212 printf(" <Billboard device>\n");
215 printf(" <Diagnostic device>\n");
218 printf(" <Wireless controller>\n");
221 printf(" <Miscellaneous device>\n");
224 printf(" <Application specific>\n");
227 printf(" <Vendor specific>\n");
230 printf(" <Unknown>\n");
236 /* No additional information */
241 dump_extra(struct libusb20_me_struct
*str
, const char *plevel
)
248 while ((ptr
= libusb20_desc_foreach(str
, ptr
))) {
249 printf("\n" "%sAdditional Descriptor\n\n", plevel
);
250 printf("%sbLength = 0x%02x\n", plevel
, ptr
[0]);
251 printf("%sbDescriptorType = 0x%02x\n", plevel
, ptr
[1]);
253 printf("%sbDescriptorSubType = 0x%02x\n",
255 printf("%s RAW dump: ", plevel
);
256 for (x
= 0; x
!= ptr
[0]; x
++) {
258 printf("\n%s 0x%02x | ", plevel
, x
);
260 printf("0x%02x%s", ptr
[x
],
261 (x
!= (ptr
[0] - 1)) ? ", " : (x
% 8) ? "\n" : "");
269 dump_endpoint(struct libusb20_device
*pdev
,
270 struct libusb20_endpoint
*ep
)
272 struct LIBUSB20_ENDPOINT_DESC_DECODED
*edesc
;
275 LIBUSB20_ENDPOINT_DESC(DUMP3
, edesc
);
276 dump_extra(&ep
->extra
, " " " " " ");
281 dump_iface(struct libusb20_device
*pdev
,
282 struct libusb20_interface
*iface
)
284 struct LIBUSB20_INTERFACE_DESC_DECODED
*idesc
;
287 idesc
= &iface
->desc
;
288 LIBUSB20_INTERFACE_DESC(DUMP2
, idesc
);
289 dump_extra(&iface
->extra
, " " " " " ");
291 for (z
= 0; z
!= iface
->num_endpoints
; z
++) {
292 printf("\n Endpoint %u\n", z
);
293 dump_endpoint(pdev
, iface
->endpoints
+ z
);
299 dump_device_info(struct libusb20_device
*pdev
, uint8_t show_ifdrv
)
305 usage
= libusb20_dev_get_power_usage(pdev
);
307 printf("%s, cfg=%u md=%s spd=%s pwr=%s (%umA)\n",
308 libusb20_dev_get_desc(pdev
),
309 libusb20_dev_get_config_index(pdev
),
310 dump_mode(libusb20_dev_get_mode(pdev
)),
311 dump_speed(libusb20_dev_get_speed(pdev
)),
312 dump_power_mode(libusb20_dev_get_power_mode(pdev
)),
318 for (n
= 0; n
!= 255; n
++) {
319 if (libusb20_dev_get_iface_desc(pdev
, n
, buf
, sizeof(buf
)))
323 printf("ugen%u.%u.%u: %s\n",
324 libusb20_dev_get_bus_number(pdev
),
325 libusb20_dev_get_address(pdev
), n
, buf
);
330 dump_be_quirk_names(struct libusb20_backend
*pbe
)
332 struct libusb20_quirk q
;
336 memset(&q
, 0, sizeof(q
));
338 printf("\nDumping list of supported quirks:\n\n");
340 for (x
= 0; x
!= 0xFFFF; x
++) {
342 error
= libusb20_be_get_quirk_name(pbe
, x
, &q
);
345 printf("No quirk names - maybe the USB quirk "
346 "module has not been loaded.\n");
350 if (strcmp(q
.quirkname
, "UQ_NONE"))
351 printf("%s\n", q
.quirkname
);
358 dump_be_dev_quirks(struct libusb20_backend
*pbe
)
360 struct libusb20_quirk q
;
364 memset(&q
, 0, sizeof(q
));
366 printf("\nDumping current device quirks:\n\n");
368 for (x
= 0; x
!= 0xFFFF; x
++) {
370 error
= libusb20_be_get_dev_quirk(pbe
, x
, &q
);
373 printf("No device quirks - maybe the USB quirk "
374 "module has not been loaded.\n");
378 if (strcmp(q
.quirkname
, "UQ_NONE")) {
379 printf("VID=0x%04x PID=0x%04x REVLO=0x%04x "
380 "REVHI=0x%04x QUIRK=%s\n",
381 q
.vid
, q
.pid
, q
.bcdDeviceLow
,
382 q
.bcdDeviceHigh
, q
.quirkname
);
390 dump_device_desc(struct libusb20_device
*pdev
)
392 struct LIBUSB20_DEVICE_DESC_DECODED
*ddesc
;
394 ddesc
= libusb20_dev_get_device_desc(pdev
);
395 LIBUSB20_DEVICE_DESC(DUMP0
, ddesc
);
400 dump_config(struct libusb20_device
*pdev
, uint8_t all_cfg
)
402 struct LIBUSB20_CONFIG_DESC_DECODED
*cdesc
;
403 struct LIBUSB20_DEVICE_DESC_DECODED
*ddesc
;
404 struct libusb20_config
*pcfg
= NULL
;
406 uint8_t cfg_index_end
;
410 ddesc
= libusb20_dev_get_device_desc(pdev
);
414 cfg_index_end
= ddesc
->bNumConfigurations
;
416 cfg_index
= libusb20_dev_get_config_index(pdev
);
417 cfg_index_end
= cfg_index
+ 1;
420 for (; cfg_index
!= cfg_index_end
; cfg_index
++) {
422 pcfg
= libusb20_dev_alloc_config(pdev
, cfg_index
);
426 printf("\n Configuration index %u\n\n", cfg_index
);
427 cdesc
= &(pcfg
->desc
);
428 LIBUSB20_CONFIG_DESC(DUMP1
, cdesc
);
429 dump_extra(&(pcfg
->extra
), " " " ");
431 for (x
= 0; x
!= pcfg
->num_interface
; x
++) {
432 printf("\n Interface %u\n", x
);
433 dump_iface(pdev
, pcfg
->interface
+ x
);
435 for (y
= 0; y
!= (pcfg
->interface
+ x
)->num_altsetting
; y
++) {
436 printf("\n Interface %u Alt %u\n", x
, y
+ 1);
438 (pcfg
->interface
+ x
)->altsetting
+ y
);
449 dump_string_by_index(struct libusb20_device
*pdev
, uint8_t str_index
)
457 err(1, "out of memory");
459 if (str_index
== 0) {
461 if (libusb20_dev_req_string_sync(pdev
,
462 str_index
, 0, pbuf
, 256)) {
463 printf("STRING_0x%02x = <read error>\n", str_index
);
465 printf("STRING_0x%02x = ", str_index
);
466 len
= (uint8_t)pbuf
[0];
467 for (n
= 0; n
!= len
; n
++) {
468 printf("0x%02x%s", (uint8_t)pbuf
[n
],
469 (n
!= (len
-1)) ? ", " : "");
474 /* ordinary string */
475 if (libusb20_dev_req_string_simple_sync(pdev
,
476 str_index
, pbuf
, 256)) {
477 printf("STRING_0x%02x = <read error>\n", str_index
);
479 printf("STRING_0x%02x = <%s>\n", str_index
, pbuf
);