1eabe30fcSAlfred Perlstein /* $FreeBSD$ */ 2eabe30fcSAlfred Perlstein /*- 3eabe30fcSAlfred Perlstein * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 4eabe30fcSAlfred Perlstein * 5eabe30fcSAlfred Perlstein * Redistribution and use in source and binary forms, with or without 6eabe30fcSAlfred Perlstein * modification, are permitted provided that the following conditions 7eabe30fcSAlfred Perlstein * are met: 8eabe30fcSAlfred Perlstein * 1. Redistributions of source code must retain the above copyright 9eabe30fcSAlfred Perlstein * notice, this list of conditions and the following disclaimer. 10eabe30fcSAlfred Perlstein * 2. Redistributions in binary form must reproduce the above copyright 11eabe30fcSAlfred Perlstein * notice, this list of conditions and the following disclaimer in the 12eabe30fcSAlfred Perlstein * documentation and/or other materials provided with the distribution. 13eabe30fcSAlfred Perlstein * 14eabe30fcSAlfred Perlstein * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15eabe30fcSAlfred Perlstein * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16eabe30fcSAlfred Perlstein * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17eabe30fcSAlfred Perlstein * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18eabe30fcSAlfred Perlstein * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19eabe30fcSAlfred Perlstein * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20eabe30fcSAlfred Perlstein * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21eabe30fcSAlfred Perlstein * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22eabe30fcSAlfred Perlstein * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23eabe30fcSAlfred Perlstein * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24eabe30fcSAlfred Perlstein * SUCH DAMAGE. 25eabe30fcSAlfred Perlstein */ 26eabe30fcSAlfred Perlstein 27eabe30fcSAlfred Perlstein #include <stdio.h> 28eabe30fcSAlfred Perlstein #include <stdlib.h> 29eabe30fcSAlfred Perlstein #include <stdint.h> 30eabe30fcSAlfred Perlstein #include <err.h> 31eabe30fcSAlfred Perlstein #include <string.h> 32eabe30fcSAlfred Perlstein #include <pwd.h> 33eabe30fcSAlfred Perlstein #include <grp.h> 34eabe30fcSAlfred Perlstein #include <ctype.h> 35eabe30fcSAlfred Perlstein 36eabe30fcSAlfred Perlstein #include <libusb20.h> 37eabe30fcSAlfred Perlstein #include <libusb20_desc.h> 38eabe30fcSAlfred Perlstein 39eabe30fcSAlfred Perlstein #include "dump.h" 40eabe30fcSAlfred Perlstein 41eabe30fcSAlfred Perlstein #define DUMP0(n,type,field,...) dump_field(pdev, " ", #field, n->field); 42eabe30fcSAlfred Perlstein #define DUMP1(n,type,field,...) dump_field(pdev, " ", #field, n->field); 43eabe30fcSAlfred Perlstein #define DUMP2(n,type,field,...) dump_field(pdev, " ", #field, n->field); 44eabe30fcSAlfred Perlstein #define DUMP3(n,type,field,...) dump_field(pdev, " ", #field, n->field); 45eabe30fcSAlfred Perlstein 46eabe30fcSAlfred Perlstein const char * 47eabe30fcSAlfred Perlstein dump_mode(uint8_t value) 48eabe30fcSAlfred Perlstein { 49eabe30fcSAlfred Perlstein if (value == LIBUSB20_MODE_HOST) 50eabe30fcSAlfred Perlstein return ("HOST"); 51eabe30fcSAlfred Perlstein return ("DEVICE"); 52eabe30fcSAlfred Perlstein } 53eabe30fcSAlfred Perlstein 54eabe30fcSAlfred Perlstein const char * 55eabe30fcSAlfred Perlstein dump_speed(uint8_t value) 56eabe30fcSAlfred Perlstein { 57eabe30fcSAlfred Perlstein ; /* style fix */ 58eabe30fcSAlfred Perlstein switch (value) { 59eabe30fcSAlfred Perlstein case LIBUSB20_SPEED_LOW: 60eabe30fcSAlfred Perlstein return ("LOW (1.5Mbps)"); 61eabe30fcSAlfred Perlstein case LIBUSB20_SPEED_FULL: 62eabe30fcSAlfred Perlstein return ("FULL (12Mbps)"); 63eabe30fcSAlfred Perlstein case LIBUSB20_SPEED_HIGH: 64eabe30fcSAlfred Perlstein return ("HIGH (480Mbps)"); 65eabe30fcSAlfred Perlstein case LIBUSB20_SPEED_VARIABLE: 66eabe30fcSAlfred Perlstein return ("VARIABLE (52-480Mbps)"); 67eabe30fcSAlfred Perlstein case LIBUSB20_SPEED_SUPER: 68*ccac019aSHans Petter Selasky return ("SUPER (5.0Gbps)"); 69eabe30fcSAlfred Perlstein default: 70eabe30fcSAlfred Perlstein break; 71eabe30fcSAlfred Perlstein } 72*ccac019aSHans Petter Selasky return ("UNKNOWN ()"); 73eabe30fcSAlfred Perlstein } 74eabe30fcSAlfred Perlstein 75eabe30fcSAlfred Perlstein const char * 76eabe30fcSAlfred Perlstein dump_power_mode(uint8_t value) 77eabe30fcSAlfred Perlstein { 78eabe30fcSAlfred Perlstein ; /* style fix */ 79eabe30fcSAlfred Perlstein switch (value) { 80eabe30fcSAlfred Perlstein case LIBUSB20_POWER_OFF: 81eabe30fcSAlfred Perlstein return ("OFF"); 82eabe30fcSAlfred Perlstein case LIBUSB20_POWER_ON: 83eabe30fcSAlfred Perlstein return ("ON"); 84eabe30fcSAlfred Perlstein case LIBUSB20_POWER_SAVE: 85eabe30fcSAlfred Perlstein return ("SAVE"); 86eabe30fcSAlfred Perlstein case LIBUSB20_POWER_SUSPEND: 87eabe30fcSAlfred Perlstein return ("SUSPEND"); 88eabe30fcSAlfred Perlstein case LIBUSB20_POWER_RESUME: 89eabe30fcSAlfred Perlstein return ("RESUME"); 90eabe30fcSAlfred Perlstein default: 91eabe30fcSAlfred Perlstein return ("UNKNOWN"); 92eabe30fcSAlfred Perlstein } 93eabe30fcSAlfred Perlstein } 94eabe30fcSAlfred Perlstein 95eabe30fcSAlfred Perlstein static void 96eabe30fcSAlfred Perlstein dump_field(struct libusb20_device *pdev, const char *plevel, 97eabe30fcSAlfred Perlstein const char *field, uint32_t value) 98eabe30fcSAlfred Perlstein { 99eabe30fcSAlfred Perlstein uint8_t temp_string[256]; 100eabe30fcSAlfred Perlstein 101eabe30fcSAlfred Perlstein printf("%s%s = 0x%04x ", plevel, field, value); 102eabe30fcSAlfred Perlstein 103e975f97cSAndrew Thompson if (strlen(plevel) == 8) { 104e975f97cSAndrew Thompson /* Endpoint Descriptor */ 105e975f97cSAndrew Thompson 106e975f97cSAndrew Thompson if (strcmp(field, "bEndpointAddress") == 0) { 107e975f97cSAndrew Thompson if (value & 0x80) 108e975f97cSAndrew Thompson printf(" <IN>\n"); 109e975f97cSAndrew Thompson else 110e975f97cSAndrew Thompson printf(" <OUT>\n"); 111eabe30fcSAlfred Perlstein return; 112eabe30fcSAlfred Perlstein } 113e975f97cSAndrew Thompson 114e975f97cSAndrew Thompson if (strcmp(field, "bmAttributes") == 0) { 115e975f97cSAndrew Thompson switch (value & 0x03) { 116e975f97cSAndrew Thompson case 0: 117e975f97cSAndrew Thompson printf(" <CONTROL>\n"); 118e975f97cSAndrew Thompson break; 119e975f97cSAndrew Thompson case 1: 120e975f97cSAndrew Thompson switch (value & 0x0C) { 121e975f97cSAndrew Thompson case 0x00: 122e975f97cSAndrew Thompson printf(" <ISOCHRONOUS>\n"); 123e975f97cSAndrew Thompson break; 124e975f97cSAndrew Thompson case 0x04: 125e975f97cSAndrew Thompson printf(" <ASYNC-ISOCHRONOUS>\n"); 126e975f97cSAndrew Thompson break; 127e975f97cSAndrew Thompson case 0x08: 128e975f97cSAndrew Thompson printf(" <ADAPT-ISOCHRONOUS>\n"); 129e975f97cSAndrew Thompson break; 130e975f97cSAndrew Thompson default: 131e975f97cSAndrew Thompson printf(" <SYNC-ISOCHRONOUS>\n"); 132e975f97cSAndrew Thompson break; 133e975f97cSAndrew Thompson } 134e975f97cSAndrew Thompson break; 135e975f97cSAndrew Thompson case 2: 136e975f97cSAndrew Thompson printf(" <BULK>\n"); 137e975f97cSAndrew Thompson break; 138e975f97cSAndrew Thompson default: 139e975f97cSAndrew Thompson printf(" <INTERRUPT>\n"); 140e975f97cSAndrew Thompson break; 141e975f97cSAndrew Thompson } 142e975f97cSAndrew Thompson return; 143e975f97cSAndrew Thompson } 144e975f97cSAndrew Thompson } 145e975f97cSAndrew Thompson 146e975f97cSAndrew Thompson if ((field[0] == 'i') && (field[1] != 'd')) { 147e975f97cSAndrew Thompson /* Indirect String Descriptor */ 148eabe30fcSAlfred Perlstein if (value == 0) { 149eabe30fcSAlfred Perlstein printf(" <no string>\n"); 150eabe30fcSAlfred Perlstein return; 151eabe30fcSAlfred Perlstein } 1526f0e1ffdSAlfred Perlstein if (libusb20_dev_req_string_simple_sync(pdev, value, 1536f0e1ffdSAlfred Perlstein temp_string, sizeof(temp_string))) { 1546f0e1ffdSAlfred Perlstein printf(" <retrieving string failed>\n"); 1556f0e1ffdSAlfred Perlstein return; 156eabe30fcSAlfred Perlstein } 1576f0e1ffdSAlfred Perlstein printf(" <%s>\n", temp_string); 158eabe30fcSAlfred Perlstein return; 159eabe30fcSAlfred Perlstein } 160eabe30fcSAlfred Perlstein 161e975f97cSAndrew Thompson /* No additional information */ 162e975f97cSAndrew Thompson printf("\n"); 163e975f97cSAndrew Thompson } 164e975f97cSAndrew Thompson 165eabe30fcSAlfred Perlstein static void 166eabe30fcSAlfred Perlstein dump_extra(struct libusb20_me_struct *str, const char *plevel) 167eabe30fcSAlfred Perlstein { 168eabe30fcSAlfred Perlstein const uint8_t *ptr; 169eabe30fcSAlfred Perlstein uint8_t x; 170eabe30fcSAlfred Perlstein 171eabe30fcSAlfred Perlstein ptr = NULL; 172eabe30fcSAlfred Perlstein 173eabe30fcSAlfred Perlstein while ((ptr = libusb20_desc_foreach(str, ptr))) { 174eabe30fcSAlfred Perlstein printf("\n" "%sAdditional Descriptor\n\n", plevel); 175eabe30fcSAlfred Perlstein printf("%sbLength = 0x%02x\n", plevel, ptr[0]); 176eabe30fcSAlfred Perlstein printf("%sbDescriptorType = 0x%02x\n", plevel, ptr[1]); 177eabe30fcSAlfred Perlstein if (ptr[0] > 1) 178eabe30fcSAlfred Perlstein printf("%sbDescriptorSubType = 0x%02x\n", 179eabe30fcSAlfred Perlstein plevel, ptr[2]); 180eabe30fcSAlfred Perlstein printf("%s RAW dump: ", plevel); 181eabe30fcSAlfred Perlstein for (x = 0; x != ptr[0]; x++) { 182eabe30fcSAlfred Perlstein if ((x % 8) == 0) { 183eabe30fcSAlfred Perlstein printf("\n%s 0x%02x | ", plevel, x); 184eabe30fcSAlfred Perlstein } 185eabe30fcSAlfred Perlstein printf("0x%02x%s", ptr[x], 186eabe30fcSAlfred Perlstein (x != (ptr[0] - 1)) ? ", " : (x % 8) ? "\n" : ""); 187eabe30fcSAlfred Perlstein } 188eabe30fcSAlfred Perlstein printf("\n"); 189eabe30fcSAlfred Perlstein } 190eabe30fcSAlfred Perlstein return; 191eabe30fcSAlfred Perlstein } 192eabe30fcSAlfred Perlstein 193eabe30fcSAlfred Perlstein static void 194eabe30fcSAlfred Perlstein dump_endpoint(struct libusb20_device *pdev, 195eabe30fcSAlfred Perlstein struct libusb20_endpoint *ep) 196eabe30fcSAlfred Perlstein { 197eabe30fcSAlfred Perlstein struct LIBUSB20_ENDPOINT_DESC_DECODED *edesc; 198eabe30fcSAlfred Perlstein 199eabe30fcSAlfred Perlstein edesc = &ep->desc; 200eabe30fcSAlfred Perlstein LIBUSB20_ENDPOINT_DESC(DUMP3, edesc); 201eabe30fcSAlfred Perlstein dump_extra(&ep->extra, " " " " " "); 202eabe30fcSAlfred Perlstein return; 203eabe30fcSAlfred Perlstein } 204eabe30fcSAlfred Perlstein 205eabe30fcSAlfred Perlstein static void 206eabe30fcSAlfred Perlstein dump_iface(struct libusb20_device *pdev, 207eabe30fcSAlfred Perlstein struct libusb20_interface *iface) 208eabe30fcSAlfred Perlstein { 209eabe30fcSAlfred Perlstein struct LIBUSB20_INTERFACE_DESC_DECODED *idesc; 210eabe30fcSAlfred Perlstein uint8_t z; 211eabe30fcSAlfred Perlstein 212eabe30fcSAlfred Perlstein idesc = &iface->desc; 213eabe30fcSAlfred Perlstein LIBUSB20_INTERFACE_DESC(DUMP2, idesc); 214eabe30fcSAlfred Perlstein dump_extra(&iface->extra, " " " " " "); 215eabe30fcSAlfred Perlstein 216eabe30fcSAlfred Perlstein for (z = 0; z != iface->num_endpoints; z++) { 217eabe30fcSAlfred Perlstein printf("\n Endpoint %u\n", z); 218eabe30fcSAlfred Perlstein dump_endpoint(pdev, iface->endpoints + z); 219eabe30fcSAlfred Perlstein } 220eabe30fcSAlfred Perlstein return; 221eabe30fcSAlfred Perlstein } 222eabe30fcSAlfred Perlstein 223eabe30fcSAlfred Perlstein void 22406d497c1SAndrew Thompson dump_device_info(struct libusb20_device *pdev, uint8_t show_ifdrv) 225eabe30fcSAlfred Perlstein { 22606d497c1SAndrew Thompson char buf[128]; 22706d497c1SAndrew Thompson uint8_t n; 22806d497c1SAndrew Thompson 229eabe30fcSAlfred Perlstein printf("%s, cfg=%u md=%s spd=%s pwr=%s\n", 230eabe30fcSAlfred Perlstein libusb20_dev_get_desc(pdev), 231eabe30fcSAlfred Perlstein libusb20_dev_get_config_index(pdev), 232eabe30fcSAlfred Perlstein dump_mode(libusb20_dev_get_mode(pdev)), 233eabe30fcSAlfred Perlstein dump_speed(libusb20_dev_get_speed(pdev)), 234eabe30fcSAlfred Perlstein dump_power_mode(libusb20_dev_get_power_mode(pdev))); 23506d497c1SAndrew Thompson 23606d497c1SAndrew Thompson if (!show_ifdrv) 237eabe30fcSAlfred Perlstein return; 23806d497c1SAndrew Thompson 23906d497c1SAndrew Thompson for (n = 0; n != 255; n++) { 24006d497c1SAndrew Thompson if (libusb20_dev_get_iface_desc(pdev, n, buf, sizeof(buf))) 24106d497c1SAndrew Thompson break; 24206d497c1SAndrew Thompson if (buf[0] == 0) 24306d497c1SAndrew Thompson continue; 24406d497c1SAndrew Thompson printf("ugen%u.%u.%u: %s\n", 24506d497c1SAndrew Thompson libusb20_dev_get_bus_number(pdev), 24606d497c1SAndrew Thompson libusb20_dev_get_address(pdev), n, buf); 24706d497c1SAndrew Thompson } 248eabe30fcSAlfred Perlstein } 249eabe30fcSAlfred Perlstein 250eabe30fcSAlfred Perlstein void 251eabe30fcSAlfred Perlstein dump_be_quirk_names(struct libusb20_backend *pbe) 252eabe30fcSAlfred Perlstein { 253eabe30fcSAlfred Perlstein struct libusb20_quirk q; 254eabe30fcSAlfred Perlstein uint16_t x; 2556f0e1ffdSAlfred Perlstein int error; 256eabe30fcSAlfred Perlstein 257eabe30fcSAlfred Perlstein memset(&q, 0, sizeof(q)); 258eabe30fcSAlfred Perlstein 259eabe30fcSAlfred Perlstein printf("\nDumping list of supported quirks:\n\n"); 260eabe30fcSAlfred Perlstein 261eabe30fcSAlfred Perlstein for (x = 0; x != 0xFFFF; x++) { 262eabe30fcSAlfred Perlstein 2636f0e1ffdSAlfred Perlstein error = libusb20_be_get_quirk_name(pbe, x, &q); 2646f0e1ffdSAlfred Perlstein if (error) { 265eabe30fcSAlfred Perlstein if (x == 0) { 266eabe30fcSAlfred Perlstein printf("No quirk names - maybe the USB quirk " 267eabe30fcSAlfred Perlstein "module has not been loaded.\n"); 268eabe30fcSAlfred Perlstein } 269eabe30fcSAlfred Perlstein break; 270eabe30fcSAlfred Perlstein } 271eabe30fcSAlfred Perlstein if (strcmp(q.quirkname, "UQ_NONE")) 272eabe30fcSAlfred Perlstein printf("%s\n", q.quirkname); 273eabe30fcSAlfred Perlstein } 274eabe30fcSAlfred Perlstein printf("\n"); 275eabe30fcSAlfred Perlstein return; 276eabe30fcSAlfred Perlstein } 277eabe30fcSAlfred Perlstein 278eabe30fcSAlfred Perlstein void 279eabe30fcSAlfred Perlstein dump_be_dev_quirks(struct libusb20_backend *pbe) 280eabe30fcSAlfred Perlstein { 281eabe30fcSAlfred Perlstein struct libusb20_quirk q; 282eabe30fcSAlfred Perlstein uint16_t x; 2836f0e1ffdSAlfred Perlstein int error; 284eabe30fcSAlfred Perlstein 285eabe30fcSAlfred Perlstein memset(&q, 0, sizeof(q)); 286eabe30fcSAlfred Perlstein 287eabe30fcSAlfred Perlstein printf("\nDumping current device quirks:\n\n"); 288eabe30fcSAlfred Perlstein 289eabe30fcSAlfred Perlstein for (x = 0; x != 0xFFFF; x++) { 290eabe30fcSAlfred Perlstein 2916f0e1ffdSAlfred Perlstein error = libusb20_be_get_dev_quirk(pbe, x, &q); 2926f0e1ffdSAlfred Perlstein if (error) { 293eabe30fcSAlfred Perlstein if (x == 0) { 294eabe30fcSAlfred Perlstein printf("No device quirks - maybe the USB quirk " 295eabe30fcSAlfred Perlstein "module has not been loaded.\n"); 296eabe30fcSAlfred Perlstein } 297eabe30fcSAlfred Perlstein break; 298eabe30fcSAlfred Perlstein } 299eabe30fcSAlfred Perlstein if (strcmp(q.quirkname, "UQ_NONE")) { 300eabe30fcSAlfred Perlstein printf("VID=0x%04x PID=0x%04x REVLO=0x%04x " 301eabe30fcSAlfred Perlstein "REVHI=0x%04x QUIRK=%s\n", 302eabe30fcSAlfred Perlstein q.vid, q.pid, q.bcdDeviceLow, 303eabe30fcSAlfred Perlstein q.bcdDeviceHigh, q.quirkname); 304eabe30fcSAlfred Perlstein } 305eabe30fcSAlfred Perlstein } 306eabe30fcSAlfred Perlstein printf("\n"); 307eabe30fcSAlfred Perlstein return; 308eabe30fcSAlfred Perlstein } 309eabe30fcSAlfred Perlstein 310eabe30fcSAlfred Perlstein void 311eabe30fcSAlfred Perlstein dump_device_desc(struct libusb20_device *pdev) 312eabe30fcSAlfred Perlstein { 313eabe30fcSAlfred Perlstein struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 314eabe30fcSAlfred Perlstein 315eabe30fcSAlfred Perlstein ddesc = libusb20_dev_get_device_desc(pdev); 316eabe30fcSAlfred Perlstein LIBUSB20_DEVICE_DESC(DUMP0, ddesc); 317eabe30fcSAlfred Perlstein return; 318eabe30fcSAlfred Perlstein } 319eabe30fcSAlfred Perlstein 320eabe30fcSAlfred Perlstein void 321eabe30fcSAlfred Perlstein dump_config(struct libusb20_device *pdev, uint8_t all_cfg) 322eabe30fcSAlfred Perlstein { 323eabe30fcSAlfred Perlstein struct LIBUSB20_CONFIG_DESC_DECODED *cdesc; 324eabe30fcSAlfred Perlstein struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 325eabe30fcSAlfred Perlstein struct libusb20_config *pcfg = NULL; 326eabe30fcSAlfred Perlstein uint8_t cfg_index; 327eabe30fcSAlfred Perlstein uint8_t cfg_index_end; 328eabe30fcSAlfred Perlstein uint8_t x; 329eabe30fcSAlfred Perlstein uint8_t y; 330eabe30fcSAlfred Perlstein 331eabe30fcSAlfred Perlstein ddesc = libusb20_dev_get_device_desc(pdev); 332eabe30fcSAlfred Perlstein 333eabe30fcSAlfred Perlstein if (all_cfg) { 334eabe30fcSAlfred Perlstein cfg_index = 0; 335eabe30fcSAlfred Perlstein cfg_index_end = ddesc->bNumConfigurations; 336eabe30fcSAlfred Perlstein } else { 337eabe30fcSAlfred Perlstein cfg_index = libusb20_dev_get_config_index(pdev); 338eabe30fcSAlfred Perlstein cfg_index_end = cfg_index + 1; 339eabe30fcSAlfred Perlstein } 340eabe30fcSAlfred Perlstein 341eabe30fcSAlfred Perlstein for (; cfg_index != cfg_index_end; cfg_index++) { 342eabe30fcSAlfred Perlstein 343eabe30fcSAlfred Perlstein pcfg = libusb20_dev_alloc_config(pdev, cfg_index); 344eabe30fcSAlfred Perlstein if (!pcfg) { 345eabe30fcSAlfred Perlstein continue; 346eabe30fcSAlfred Perlstein } 347eabe30fcSAlfred Perlstein printf("\n Configuration index %u\n\n", cfg_index); 348eabe30fcSAlfred Perlstein cdesc = &(pcfg->desc); 349eabe30fcSAlfred Perlstein LIBUSB20_CONFIG_DESC(DUMP1, cdesc); 350eabe30fcSAlfred Perlstein dump_extra(&(pcfg->extra), " " " "); 351eabe30fcSAlfred Perlstein 352eabe30fcSAlfred Perlstein for (x = 0; x != pcfg->num_interface; x++) { 353eabe30fcSAlfred Perlstein printf("\n Interface %u\n", x); 354eabe30fcSAlfred Perlstein dump_iface(pdev, pcfg->interface + x); 355eabe30fcSAlfred Perlstein printf("\n"); 356eabe30fcSAlfred Perlstein for (y = 0; y != (pcfg->interface + x)->num_altsetting; y++) { 357eabe30fcSAlfred Perlstein printf("\n Interface %u Alt %u\n", x, y + 1); 358eabe30fcSAlfred Perlstein dump_iface(pdev, 359eabe30fcSAlfred Perlstein (pcfg->interface + x)->altsetting + y); 360eabe30fcSAlfred Perlstein printf("\n"); 361eabe30fcSAlfred Perlstein } 362eabe30fcSAlfred Perlstein } 363eabe30fcSAlfred Perlstein printf("\n"); 364eabe30fcSAlfred Perlstein free(pcfg); 365eabe30fcSAlfred Perlstein } 366eabe30fcSAlfred Perlstein return; 367eabe30fcSAlfred Perlstein } 368cf109686SAndrew Thompson 369cf109686SAndrew Thompson void 370cf109686SAndrew Thompson dump_string_by_index(struct libusb20_device *pdev, uint8_t str_index) 371cf109686SAndrew Thompson { 372cf109686SAndrew Thompson char *pbuf; 373cf109686SAndrew Thompson uint8_t n; 374cf109686SAndrew Thompson uint8_t len; 375cf109686SAndrew Thompson 376cf109686SAndrew Thompson pbuf = malloc(256); 377cf109686SAndrew Thompson if (pbuf == NULL) 378cf109686SAndrew Thompson err(1, "out of memory"); 379cf109686SAndrew Thompson 380cf109686SAndrew Thompson if (str_index == 0) { 381cf109686SAndrew Thompson /* language table */ 382cf109686SAndrew Thompson if (libusb20_dev_req_string_sync(pdev, 383cf109686SAndrew Thompson str_index, 0, pbuf, 256)) { 384cf109686SAndrew Thompson printf("STRING_0x%02x = <read error>\n", str_index); 385cf109686SAndrew Thompson } else { 386cf109686SAndrew Thompson printf("STRING_0x%02x = ", str_index); 387cf109686SAndrew Thompson len = (uint8_t)pbuf[0]; 388cf109686SAndrew Thompson for (n = 0; n != len; n++) { 389cf109686SAndrew Thompson printf("0x%02x%s", (uint8_t)pbuf[n], 390cf109686SAndrew Thompson (n != (len-1)) ? ", " : ""); 391cf109686SAndrew Thompson } 392cf109686SAndrew Thompson printf("\n"); 393cf109686SAndrew Thompson } 394cf109686SAndrew Thompson } else { 395cf109686SAndrew Thompson /* ordinary string */ 396cf109686SAndrew Thompson if (libusb20_dev_req_string_simple_sync(pdev, 397cf109686SAndrew Thompson str_index, pbuf, 256)) { 398cf109686SAndrew Thompson printf("STRING_0x%02x = <read error>\n", str_index); 399cf109686SAndrew Thompson } else { 400cf109686SAndrew Thompson printf("STRING_0x%02x = <%s>\n", str_index, pbuf); 401cf109686SAndrew Thompson } 402cf109686SAndrew Thompson } 403cf109686SAndrew Thompson free(pbuf); 404cf109686SAndrew Thompson } 405