1eabe30fcSAlfred Perlstein /* $FreeBSD$ */ 2eabe30fcSAlfred Perlstein /*- 31de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 41de7b4b8SPedro F. Giffuni * 5eabe30fcSAlfred Perlstein * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 6eabe30fcSAlfred Perlstein * 7eabe30fcSAlfred Perlstein * Redistribution and use in source and binary forms, with or without 8eabe30fcSAlfred Perlstein * modification, are permitted provided that the following conditions 9eabe30fcSAlfred Perlstein * are met: 10eabe30fcSAlfred Perlstein * 1. Redistributions of source code must retain the above copyright 11eabe30fcSAlfred Perlstein * notice, this list of conditions and the following disclaimer. 12eabe30fcSAlfred Perlstein * 2. Redistributions in binary form must reproduce the above copyright 13eabe30fcSAlfred Perlstein * notice, this list of conditions and the following disclaimer in the 14eabe30fcSAlfred Perlstein * documentation and/or other materials provided with the distribution. 15eabe30fcSAlfred Perlstein * 16eabe30fcSAlfred Perlstein * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17eabe30fcSAlfred Perlstein * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18eabe30fcSAlfred Perlstein * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19eabe30fcSAlfred Perlstein * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20eabe30fcSAlfred Perlstein * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21eabe30fcSAlfred Perlstein * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22eabe30fcSAlfred Perlstein * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23eabe30fcSAlfred Perlstein * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24eabe30fcSAlfred Perlstein * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25eabe30fcSAlfred Perlstein * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26eabe30fcSAlfred Perlstein * SUCH DAMAGE. 27eabe30fcSAlfred Perlstein */ 28eabe30fcSAlfred Perlstein 29eabe30fcSAlfred Perlstein #include <stdio.h> 30eabe30fcSAlfred Perlstein #include <stdlib.h> 31eabe30fcSAlfred Perlstein #include <stdint.h> 32eabe30fcSAlfred Perlstein #include <err.h> 33eabe30fcSAlfred Perlstein #include <string.h> 34eabe30fcSAlfred Perlstein #include <pwd.h> 35eabe30fcSAlfred Perlstein #include <grp.h> 36eabe30fcSAlfred Perlstein #include <ctype.h> 37eabe30fcSAlfred Perlstein 38eabe30fcSAlfred Perlstein #include <libusb20.h> 39eabe30fcSAlfred Perlstein #include <libusb20_desc.h> 40eabe30fcSAlfred Perlstein 41eabe30fcSAlfred Perlstein #include "dump.h" 42eabe30fcSAlfred Perlstein 43eabe30fcSAlfred Perlstein #define DUMP0(n,type,field,...) dump_field(pdev, " ", #field, n->field); 44eabe30fcSAlfred Perlstein #define DUMP1(n,type,field,...) dump_field(pdev, " ", #field, n->field); 45eabe30fcSAlfred Perlstein #define DUMP2(n,type,field,...) dump_field(pdev, " ", #field, n->field); 46eabe30fcSAlfred Perlstein #define DUMP3(n,type,field,...) dump_field(pdev, " ", #field, n->field); 47eabe30fcSAlfred Perlstein 48eabe30fcSAlfred Perlstein const char * 49eabe30fcSAlfred Perlstein dump_mode(uint8_t value) 50eabe30fcSAlfred Perlstein { 51eabe30fcSAlfred Perlstein if (value == LIBUSB20_MODE_HOST) 52eabe30fcSAlfred Perlstein return ("HOST"); 53eabe30fcSAlfred Perlstein return ("DEVICE"); 54eabe30fcSAlfred Perlstein } 55eabe30fcSAlfred Perlstein 56eabe30fcSAlfred Perlstein const char * 57eabe30fcSAlfred Perlstein dump_speed(uint8_t value) 58eabe30fcSAlfred Perlstein { 59eabe30fcSAlfred Perlstein ; /* style fix */ 60eabe30fcSAlfred Perlstein switch (value) { 61eabe30fcSAlfred Perlstein case LIBUSB20_SPEED_LOW: 62eabe30fcSAlfred Perlstein return ("LOW (1.5Mbps)"); 63eabe30fcSAlfred Perlstein case LIBUSB20_SPEED_FULL: 64eabe30fcSAlfred Perlstein return ("FULL (12Mbps)"); 65eabe30fcSAlfred Perlstein case LIBUSB20_SPEED_HIGH: 66eabe30fcSAlfred Perlstein return ("HIGH (480Mbps)"); 67eabe30fcSAlfred Perlstein case LIBUSB20_SPEED_VARIABLE: 68eabe30fcSAlfred Perlstein return ("VARIABLE (52-480Mbps)"); 69eabe30fcSAlfred Perlstein case LIBUSB20_SPEED_SUPER: 70ccac019aSHans Petter Selasky return ("SUPER (5.0Gbps)"); 71eabe30fcSAlfred Perlstein default: 72eabe30fcSAlfred Perlstein break; 73eabe30fcSAlfred Perlstein } 74ccac019aSHans Petter Selasky return ("UNKNOWN ()"); 75eabe30fcSAlfred Perlstein } 76eabe30fcSAlfred Perlstein 77eabe30fcSAlfred Perlstein const char * 78eabe30fcSAlfred Perlstein dump_power_mode(uint8_t value) 79eabe30fcSAlfred Perlstein { 80eabe30fcSAlfred Perlstein ; /* style fix */ 81eabe30fcSAlfred Perlstein switch (value) { 82eabe30fcSAlfred Perlstein case LIBUSB20_POWER_OFF: 83eabe30fcSAlfred Perlstein return ("OFF"); 84eabe30fcSAlfred Perlstein case LIBUSB20_POWER_ON: 85eabe30fcSAlfred Perlstein return ("ON"); 86eabe30fcSAlfred Perlstein case LIBUSB20_POWER_SAVE: 87eabe30fcSAlfred Perlstein return ("SAVE"); 88eabe30fcSAlfred Perlstein case LIBUSB20_POWER_SUSPEND: 89eabe30fcSAlfred Perlstein return ("SUSPEND"); 90eabe30fcSAlfred Perlstein case LIBUSB20_POWER_RESUME: 91eabe30fcSAlfred Perlstein return ("RESUME"); 92eabe30fcSAlfred Perlstein default: 93eabe30fcSAlfred Perlstein return ("UNKNOWN"); 94eabe30fcSAlfred Perlstein } 95eabe30fcSAlfred Perlstein } 96eabe30fcSAlfred Perlstein 97eabe30fcSAlfred Perlstein static void 98eabe30fcSAlfred Perlstein dump_field(struct libusb20_device *pdev, const char *plevel, 99eabe30fcSAlfred Perlstein const char *field, uint32_t value) 100eabe30fcSAlfred Perlstein { 101eabe30fcSAlfred Perlstein uint8_t temp_string[256]; 102eabe30fcSAlfred Perlstein 103eabe30fcSAlfred Perlstein printf("%s%s = 0x%04x ", plevel, field, value); 104eabe30fcSAlfred Perlstein 105e975f97cSAndrew Thompson if (strlen(plevel) == 8) { 106e975f97cSAndrew Thompson /* Endpoint Descriptor */ 107e975f97cSAndrew Thompson 108e975f97cSAndrew Thompson if (strcmp(field, "bEndpointAddress") == 0) { 109e975f97cSAndrew Thompson if (value & 0x80) 110e975f97cSAndrew Thompson printf(" <IN>\n"); 111e975f97cSAndrew Thompson else 112e975f97cSAndrew Thompson printf(" <OUT>\n"); 113eabe30fcSAlfred Perlstein return; 114eabe30fcSAlfred Perlstein } 115e975f97cSAndrew Thompson if (strcmp(field, "bmAttributes") == 0) { 116e975f97cSAndrew Thompson switch (value & 0x03) { 117e975f97cSAndrew Thompson case 0: 118e975f97cSAndrew Thompson printf(" <CONTROL>\n"); 119e975f97cSAndrew Thompson break; 120e975f97cSAndrew Thompson case 1: 121e975f97cSAndrew Thompson switch (value & 0x0C) { 122e975f97cSAndrew Thompson case 0x00: 123e975f97cSAndrew Thompson printf(" <ISOCHRONOUS>\n"); 124e975f97cSAndrew Thompson break; 125e975f97cSAndrew Thompson case 0x04: 126e975f97cSAndrew Thompson printf(" <ASYNC-ISOCHRONOUS>\n"); 127e975f97cSAndrew Thompson break; 128e975f97cSAndrew Thompson case 0x08: 129e975f97cSAndrew Thompson printf(" <ADAPT-ISOCHRONOUS>\n"); 130e975f97cSAndrew Thompson break; 131e975f97cSAndrew Thompson default: 132e975f97cSAndrew Thompson printf(" <SYNC-ISOCHRONOUS>\n"); 133e975f97cSAndrew Thompson break; 134e975f97cSAndrew Thompson } 135e975f97cSAndrew Thompson break; 136e975f97cSAndrew Thompson case 2: 137e975f97cSAndrew Thompson printf(" <BULK>\n"); 138e975f97cSAndrew Thompson break; 139e975f97cSAndrew Thompson default: 140e975f97cSAndrew Thompson printf(" <INTERRUPT>\n"); 141e975f97cSAndrew Thompson break; 142e975f97cSAndrew Thompson } 143e975f97cSAndrew Thompson return; 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 } 1605bd38bcaSHans Petter Selasky if (strlen(plevel) == 2 || strlen(plevel) == 6) { 161eabe30fcSAlfred Perlstein 1625bd38bcaSHans Petter Selasky /* Device and Interface Descriptor class codes */ 1635bd38bcaSHans Petter Selasky 1645bd38bcaSHans Petter Selasky if (strcmp(field, "bInterfaceClass") == 0 || 1655bd38bcaSHans Petter Selasky strcmp(field, "bDeviceClass") == 0) { 1665bd38bcaSHans Petter Selasky 1675bd38bcaSHans Petter Selasky switch (value) { 1685bd38bcaSHans Petter Selasky case 0x00: 1695bd38bcaSHans Petter Selasky printf(" <Probed by interface class>\n"); 1705bd38bcaSHans Petter Selasky break; 1715bd38bcaSHans Petter Selasky case 0x01: 1725bd38bcaSHans Petter Selasky printf(" <Audio device>\n"); 1735bd38bcaSHans Petter Selasky break; 1745bd38bcaSHans Petter Selasky case 0x02: 1755bd38bcaSHans Petter Selasky printf(" <Communication device>\n"); 1765bd38bcaSHans Petter Selasky break; 1775bd38bcaSHans Petter Selasky case 0x03: 1785bd38bcaSHans Petter Selasky printf(" <HID device>\n"); 1795bd38bcaSHans Petter Selasky break; 1805bd38bcaSHans Petter Selasky case 0x05: 1815bd38bcaSHans Petter Selasky printf(" <Physical device>\n"); 1825bd38bcaSHans Petter Selasky break; 1835bd38bcaSHans Petter Selasky case 0x06: 1845bd38bcaSHans Petter Selasky printf(" <Still imaging>\n"); 1855bd38bcaSHans Petter Selasky break; 1865bd38bcaSHans Petter Selasky case 0x07: 1875bd38bcaSHans Petter Selasky printf(" <Printer device>\n"); 1885bd38bcaSHans Petter Selasky break; 1895bd38bcaSHans Petter Selasky case 0x08: 1905bd38bcaSHans Petter Selasky printf(" <Mass storage>\n"); 1915bd38bcaSHans Petter Selasky break; 1925bd38bcaSHans Petter Selasky case 0x09: 1935bd38bcaSHans Petter Selasky printf(" <HUB>\n"); 1945bd38bcaSHans Petter Selasky break; 1955bd38bcaSHans Petter Selasky case 0x0A: 1965bd38bcaSHans Petter Selasky printf(" <CDC-data>\n"); 1975bd38bcaSHans Petter Selasky break; 1985bd38bcaSHans Petter Selasky case 0x0B: 1995bd38bcaSHans Petter Selasky printf(" <Smart card>\n"); 2005bd38bcaSHans Petter Selasky break; 2015bd38bcaSHans Petter Selasky case 0x0D: 2025bd38bcaSHans Petter Selasky printf(" <Content security>\n"); 2035bd38bcaSHans Petter Selasky break; 2045bd38bcaSHans Petter Selasky case 0x0E: 2055bd38bcaSHans Petter Selasky printf(" <Video device>\n"); 2065bd38bcaSHans Petter Selasky break; 2075bd38bcaSHans Petter Selasky case 0x0F: 2085bd38bcaSHans Petter Selasky printf(" <Personal healthcare>\n"); 2095bd38bcaSHans Petter Selasky break; 2105bd38bcaSHans Petter Selasky case 0x10: 2115bd38bcaSHans Petter Selasky printf(" <Audio and video device>\n"); 2125bd38bcaSHans Petter Selasky break; 2135bd38bcaSHans Petter Selasky case 0x11: 2145bd38bcaSHans Petter Selasky printf(" <Billboard device>\n"); 2155bd38bcaSHans Petter Selasky break; 2165bd38bcaSHans Petter Selasky case 0xDC: 2175bd38bcaSHans Petter Selasky printf(" <Diagnostic device>\n"); 2185bd38bcaSHans Petter Selasky break; 2195bd38bcaSHans Petter Selasky case 0xE0: 2205bd38bcaSHans Petter Selasky printf(" <Wireless controller>\n"); 2215bd38bcaSHans Petter Selasky break; 2225bd38bcaSHans Petter Selasky case 0xEF: 2235bd38bcaSHans Petter Selasky printf(" <Miscellaneous device>\n"); 2245bd38bcaSHans Petter Selasky break; 2255bd38bcaSHans Petter Selasky case 0xFE: 2265bd38bcaSHans Petter Selasky printf(" <Application specific>\n"); 2275bd38bcaSHans Petter Selasky break; 2285bd38bcaSHans Petter Selasky case 0xFF: 2295bd38bcaSHans Petter Selasky printf(" <Vendor specific>\n"); 2305bd38bcaSHans Petter Selasky break; 2315bd38bcaSHans Petter Selasky default: 2325bd38bcaSHans Petter Selasky printf(" <Unknown>\n"); 2335bd38bcaSHans Petter Selasky break; 2345bd38bcaSHans Petter Selasky } 2355bd38bcaSHans Petter Selasky return; 2365bd38bcaSHans Petter Selasky } 2375bd38bcaSHans Petter Selasky } 238e975f97cSAndrew Thompson /* No additional information */ 239e975f97cSAndrew Thompson printf("\n"); 240e975f97cSAndrew Thompson } 241e975f97cSAndrew Thompson 242eabe30fcSAlfred Perlstein static void 243eabe30fcSAlfred Perlstein dump_extra(struct libusb20_me_struct *str, const char *plevel) 244eabe30fcSAlfred Perlstein { 245eabe30fcSAlfred Perlstein const uint8_t *ptr; 246eabe30fcSAlfred Perlstein uint8_t x; 247eabe30fcSAlfred Perlstein 248eabe30fcSAlfred Perlstein ptr = NULL; 249eabe30fcSAlfred Perlstein 250eabe30fcSAlfred Perlstein while ((ptr = libusb20_desc_foreach(str, ptr))) { 251eabe30fcSAlfred Perlstein printf("\n" "%sAdditional Descriptor\n\n", plevel); 252eabe30fcSAlfred Perlstein printf("%sbLength = 0x%02x\n", plevel, ptr[0]); 253eabe30fcSAlfred Perlstein printf("%sbDescriptorType = 0x%02x\n", plevel, ptr[1]); 254eabe30fcSAlfred Perlstein if (ptr[0] > 1) 255eabe30fcSAlfred Perlstein printf("%sbDescriptorSubType = 0x%02x\n", 256eabe30fcSAlfred Perlstein plevel, ptr[2]); 257eabe30fcSAlfred Perlstein printf("%s RAW dump: ", plevel); 258eabe30fcSAlfred Perlstein for (x = 0; x != ptr[0]; x++) { 259eabe30fcSAlfred Perlstein if ((x % 8) == 0) { 260eabe30fcSAlfred Perlstein printf("\n%s 0x%02x | ", plevel, x); 261eabe30fcSAlfred Perlstein } 262eabe30fcSAlfred Perlstein printf("0x%02x%s", ptr[x], 263eabe30fcSAlfred Perlstein (x != (ptr[0] - 1)) ? ", " : (x % 8) ? "\n" : ""); 264eabe30fcSAlfred Perlstein } 265eabe30fcSAlfred Perlstein printf("\n"); 266eabe30fcSAlfred Perlstein } 267eabe30fcSAlfred Perlstein return; 268eabe30fcSAlfred Perlstein } 269eabe30fcSAlfred Perlstein 270eabe30fcSAlfred Perlstein static void 271eabe30fcSAlfred Perlstein dump_endpoint(struct libusb20_device *pdev, 272eabe30fcSAlfred Perlstein struct libusb20_endpoint *ep) 273eabe30fcSAlfred Perlstein { 274eabe30fcSAlfred Perlstein struct LIBUSB20_ENDPOINT_DESC_DECODED *edesc; 275eabe30fcSAlfred Perlstein 276eabe30fcSAlfred Perlstein edesc = &ep->desc; 277eabe30fcSAlfred Perlstein LIBUSB20_ENDPOINT_DESC(DUMP3, edesc); 278eabe30fcSAlfred Perlstein dump_extra(&ep->extra, " " " " " "); 279eabe30fcSAlfred Perlstein return; 280eabe30fcSAlfred Perlstein } 281eabe30fcSAlfred Perlstein 282eabe30fcSAlfred Perlstein static void 283eabe30fcSAlfred Perlstein dump_iface(struct libusb20_device *pdev, 284eabe30fcSAlfred Perlstein struct libusb20_interface *iface) 285eabe30fcSAlfred Perlstein { 286eabe30fcSAlfred Perlstein struct LIBUSB20_INTERFACE_DESC_DECODED *idesc; 287eabe30fcSAlfred Perlstein uint8_t z; 288eabe30fcSAlfred Perlstein 289eabe30fcSAlfred Perlstein idesc = &iface->desc; 290eabe30fcSAlfred Perlstein LIBUSB20_INTERFACE_DESC(DUMP2, idesc); 291eabe30fcSAlfred Perlstein dump_extra(&iface->extra, " " " " " "); 292eabe30fcSAlfred Perlstein 293eabe30fcSAlfred Perlstein for (z = 0; z != iface->num_endpoints; z++) { 294eabe30fcSAlfred Perlstein printf("\n Endpoint %u\n", z); 295eabe30fcSAlfred Perlstein dump_endpoint(pdev, iface->endpoints + z); 296eabe30fcSAlfred Perlstein } 297eabe30fcSAlfred Perlstein return; 298eabe30fcSAlfred Perlstein } 299eabe30fcSAlfred Perlstein 300eabe30fcSAlfred Perlstein void 30106d497c1SAndrew Thompson dump_device_info(struct libusb20_device *pdev, uint8_t show_ifdrv) 302eabe30fcSAlfred Perlstein { 30306d497c1SAndrew Thompson char buf[128]; 30406d497c1SAndrew Thompson uint8_t n; 305aafcb732SHans Petter Selasky unsigned int usage; 30606d497c1SAndrew Thompson 307aafcb732SHans Petter Selasky usage = libusb20_dev_get_power_usage(pdev); 308aafcb732SHans Petter Selasky 309aafcb732SHans Petter Selasky printf("%s, cfg=%u md=%s spd=%s pwr=%s (%umA)\n", 310eabe30fcSAlfred Perlstein libusb20_dev_get_desc(pdev), 311eabe30fcSAlfred Perlstein libusb20_dev_get_config_index(pdev), 312eabe30fcSAlfred Perlstein dump_mode(libusb20_dev_get_mode(pdev)), 313eabe30fcSAlfred Perlstein dump_speed(libusb20_dev_get_speed(pdev)), 314aafcb732SHans Petter Selasky dump_power_mode(libusb20_dev_get_power_mode(pdev)), 315aafcb732SHans Petter Selasky usage); 31606d497c1SAndrew Thompson 31706d497c1SAndrew Thompson if (!show_ifdrv) 318eabe30fcSAlfred Perlstein return; 31906d497c1SAndrew Thompson 32006d497c1SAndrew Thompson for (n = 0; n != 255; n++) { 32106d497c1SAndrew Thompson if (libusb20_dev_get_iface_desc(pdev, n, buf, sizeof(buf))) 32206d497c1SAndrew Thompson break; 32306d497c1SAndrew Thompson if (buf[0] == 0) 32406d497c1SAndrew Thompson continue; 32506d497c1SAndrew Thompson printf("ugen%u.%u.%u: %s\n", 32606d497c1SAndrew Thompson libusb20_dev_get_bus_number(pdev), 32706d497c1SAndrew Thompson libusb20_dev_get_address(pdev), n, buf); 32806d497c1SAndrew Thompson } 329eabe30fcSAlfred Perlstein } 330eabe30fcSAlfred Perlstein 331eabe30fcSAlfred Perlstein void 332eabe30fcSAlfred Perlstein dump_be_quirk_names(struct libusb20_backend *pbe) 333eabe30fcSAlfred Perlstein { 334eabe30fcSAlfred Perlstein struct libusb20_quirk q; 335eabe30fcSAlfred Perlstein uint16_t x; 3366f0e1ffdSAlfred Perlstein int error; 337eabe30fcSAlfred Perlstein 338eabe30fcSAlfred Perlstein memset(&q, 0, sizeof(q)); 339eabe30fcSAlfred Perlstein 340eabe30fcSAlfred Perlstein printf("\nDumping list of supported quirks:\n\n"); 341eabe30fcSAlfred Perlstein 342eabe30fcSAlfred Perlstein for (x = 0; x != 0xFFFF; x++) { 343eabe30fcSAlfred Perlstein 3446f0e1ffdSAlfred Perlstein error = libusb20_be_get_quirk_name(pbe, x, &q); 3456f0e1ffdSAlfred Perlstein if (error) { 346eabe30fcSAlfred Perlstein if (x == 0) { 347eabe30fcSAlfred Perlstein printf("No quirk names - maybe the USB quirk " 348eabe30fcSAlfred Perlstein "module has not been loaded.\n"); 349eabe30fcSAlfred Perlstein } 350eabe30fcSAlfred Perlstein break; 351eabe30fcSAlfred Perlstein } 352eabe30fcSAlfred Perlstein if (strcmp(q.quirkname, "UQ_NONE")) 353eabe30fcSAlfred Perlstein printf("%s\n", q.quirkname); 354eabe30fcSAlfred Perlstein } 355eabe30fcSAlfred Perlstein printf("\n"); 356eabe30fcSAlfred Perlstein return; 357eabe30fcSAlfred Perlstein } 358eabe30fcSAlfred Perlstein 359eabe30fcSAlfred Perlstein void 360eabe30fcSAlfred Perlstein dump_be_dev_quirks(struct libusb20_backend *pbe) 361eabe30fcSAlfred Perlstein { 362eabe30fcSAlfred Perlstein struct libusb20_quirk q; 363eabe30fcSAlfred Perlstein uint16_t x; 3646f0e1ffdSAlfred Perlstein int error; 365eabe30fcSAlfred Perlstein 366eabe30fcSAlfred Perlstein memset(&q, 0, sizeof(q)); 367eabe30fcSAlfred Perlstein 368eabe30fcSAlfred Perlstein printf("\nDumping current device quirks:\n\n"); 369eabe30fcSAlfred Perlstein 370eabe30fcSAlfred Perlstein for (x = 0; x != 0xFFFF; x++) { 371eabe30fcSAlfred Perlstein 3726f0e1ffdSAlfred Perlstein error = libusb20_be_get_dev_quirk(pbe, x, &q); 3736f0e1ffdSAlfred Perlstein if (error) { 374eabe30fcSAlfred Perlstein if (x == 0) { 375eabe30fcSAlfred Perlstein printf("No device quirks - maybe the USB quirk " 376eabe30fcSAlfred Perlstein "module has not been loaded.\n"); 377eabe30fcSAlfred Perlstein } 378eabe30fcSAlfred Perlstein break; 379eabe30fcSAlfred Perlstein } 380eabe30fcSAlfred Perlstein if (strcmp(q.quirkname, "UQ_NONE")) { 381eabe30fcSAlfred Perlstein printf("VID=0x%04x PID=0x%04x REVLO=0x%04x " 382eabe30fcSAlfred Perlstein "REVHI=0x%04x QUIRK=%s\n", 383eabe30fcSAlfred Perlstein q.vid, q.pid, q.bcdDeviceLow, 384eabe30fcSAlfred Perlstein q.bcdDeviceHigh, q.quirkname); 385eabe30fcSAlfred Perlstein } 386eabe30fcSAlfred Perlstein } 387eabe30fcSAlfred Perlstein printf("\n"); 388eabe30fcSAlfred Perlstein return; 389eabe30fcSAlfred Perlstein } 390eabe30fcSAlfred Perlstein 391eabe30fcSAlfred Perlstein void 392eabe30fcSAlfred Perlstein dump_device_desc(struct libusb20_device *pdev) 393eabe30fcSAlfred Perlstein { 394eabe30fcSAlfred Perlstein struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 395eabe30fcSAlfred Perlstein 396eabe30fcSAlfred Perlstein ddesc = libusb20_dev_get_device_desc(pdev); 397eabe30fcSAlfred Perlstein LIBUSB20_DEVICE_DESC(DUMP0, ddesc); 398eabe30fcSAlfred Perlstein return; 399eabe30fcSAlfred Perlstein } 400eabe30fcSAlfred Perlstein 401eabe30fcSAlfred Perlstein void 402eabe30fcSAlfred Perlstein dump_config(struct libusb20_device *pdev, uint8_t all_cfg) 403eabe30fcSAlfred Perlstein { 404eabe30fcSAlfred Perlstein struct LIBUSB20_CONFIG_DESC_DECODED *cdesc; 405eabe30fcSAlfred Perlstein struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 406eabe30fcSAlfred Perlstein struct libusb20_config *pcfg = NULL; 407eabe30fcSAlfred Perlstein uint8_t cfg_index; 408eabe30fcSAlfred Perlstein uint8_t cfg_index_end; 409eabe30fcSAlfred Perlstein uint8_t x; 410eabe30fcSAlfred Perlstein uint8_t y; 411eabe30fcSAlfred Perlstein 412eabe30fcSAlfred Perlstein ddesc = libusb20_dev_get_device_desc(pdev); 413eabe30fcSAlfred Perlstein 414eabe30fcSAlfred Perlstein if (all_cfg) { 415eabe30fcSAlfred Perlstein cfg_index = 0; 416eabe30fcSAlfred Perlstein cfg_index_end = ddesc->bNumConfigurations; 417eabe30fcSAlfred Perlstein } else { 418eabe30fcSAlfred Perlstein cfg_index = libusb20_dev_get_config_index(pdev); 419eabe30fcSAlfred Perlstein cfg_index_end = cfg_index + 1; 420eabe30fcSAlfred Perlstein } 421eabe30fcSAlfred Perlstein 422eabe30fcSAlfred Perlstein for (; cfg_index != cfg_index_end; cfg_index++) { 423eabe30fcSAlfred Perlstein 424eabe30fcSAlfred Perlstein pcfg = libusb20_dev_alloc_config(pdev, cfg_index); 425eabe30fcSAlfred Perlstein if (!pcfg) { 426eabe30fcSAlfred Perlstein continue; 427eabe30fcSAlfred Perlstein } 428eabe30fcSAlfred Perlstein printf("\n Configuration index %u\n\n", cfg_index); 429eabe30fcSAlfred Perlstein cdesc = &(pcfg->desc); 430eabe30fcSAlfred Perlstein LIBUSB20_CONFIG_DESC(DUMP1, cdesc); 431eabe30fcSAlfred Perlstein dump_extra(&(pcfg->extra), " " " "); 432eabe30fcSAlfred Perlstein 433eabe30fcSAlfred Perlstein for (x = 0; x != pcfg->num_interface; x++) { 434eabe30fcSAlfred Perlstein printf("\n Interface %u\n", x); 435eabe30fcSAlfred Perlstein dump_iface(pdev, pcfg->interface + x); 436eabe30fcSAlfred Perlstein printf("\n"); 437eabe30fcSAlfred Perlstein for (y = 0; y != (pcfg->interface + x)->num_altsetting; y++) { 438eabe30fcSAlfred Perlstein printf("\n Interface %u Alt %u\n", x, y + 1); 439eabe30fcSAlfred Perlstein dump_iface(pdev, 440eabe30fcSAlfred Perlstein (pcfg->interface + x)->altsetting + y); 441eabe30fcSAlfred Perlstein printf("\n"); 442eabe30fcSAlfred Perlstein } 443eabe30fcSAlfred Perlstein } 444eabe30fcSAlfred Perlstein printf("\n"); 445eabe30fcSAlfred Perlstein free(pcfg); 446eabe30fcSAlfred Perlstein } 447eabe30fcSAlfred Perlstein return; 448eabe30fcSAlfred Perlstein } 449cf109686SAndrew Thompson 450cf109686SAndrew Thompson void 451cf109686SAndrew Thompson dump_string_by_index(struct libusb20_device *pdev, uint8_t str_index) 452cf109686SAndrew Thompson { 453cf109686SAndrew Thompson char *pbuf; 454cf109686SAndrew Thompson uint8_t n; 455cf109686SAndrew Thompson uint8_t len; 456cf109686SAndrew Thompson 457cf109686SAndrew Thompson pbuf = malloc(256); 458cf109686SAndrew Thompson if (pbuf == NULL) 459cf109686SAndrew Thompson err(1, "out of memory"); 460cf109686SAndrew Thompson 461cf109686SAndrew Thompson if (str_index == 0) { 462cf109686SAndrew Thompson /* language table */ 463cf109686SAndrew Thompson if (libusb20_dev_req_string_sync(pdev, 464cf109686SAndrew Thompson str_index, 0, pbuf, 256)) { 465cf109686SAndrew Thompson printf("STRING_0x%02x = <read error>\n", str_index); 466cf109686SAndrew Thompson } else { 467cf109686SAndrew Thompson printf("STRING_0x%02x = ", str_index); 468cf109686SAndrew Thompson len = (uint8_t)pbuf[0]; 469cf109686SAndrew Thompson for (n = 0; n != len; n++) { 470cf109686SAndrew Thompson printf("0x%02x%s", (uint8_t)pbuf[n], 471cf109686SAndrew Thompson (n != (len - 1)) ? ", " : ""); 472cf109686SAndrew Thompson } 473cf109686SAndrew Thompson printf("\n"); 474cf109686SAndrew Thompson } 475cf109686SAndrew Thompson } else { 476cf109686SAndrew Thompson /* ordinary string */ 477cf109686SAndrew Thompson if (libusb20_dev_req_string_simple_sync(pdev, 478cf109686SAndrew Thompson str_index, pbuf, 256)) { 479cf109686SAndrew Thompson printf("STRING_0x%02x = <read error>\n", str_index); 480cf109686SAndrew Thompson } else { 481cf109686SAndrew Thompson printf("STRING_0x%02x = <%s>\n", str_index, pbuf); 482cf109686SAndrew Thompson } 483cf109686SAndrew Thompson } 484cf109686SAndrew Thompson free(pbuf); 485cf109686SAndrew Thompson } 486*fa6d8b65SHans Petter Selasky 487*fa6d8b65SHans Petter Selasky void 488*fa6d8b65SHans Petter Selasky dump_device_stats(struct libusb20_device *pdev) 489*fa6d8b65SHans Petter Selasky { 490*fa6d8b65SHans Petter Selasky struct libusb20_device_stats st; 491*fa6d8b65SHans Petter Selasky 492*fa6d8b65SHans Petter Selasky if (libusb20_dev_get_stats(pdev, &st)) { 493*fa6d8b65SHans Petter Selasky printf("{}\n"); 494*fa6d8b65SHans Petter Selasky } else { 495*fa6d8b65SHans Petter Selasky printf("{\n" 496*fa6d8b65SHans Petter Selasky " UE_CONTROL_OK : %llu\n" 497*fa6d8b65SHans Petter Selasky " UE_ISOCHRONOUS_OK : %llu\n" 498*fa6d8b65SHans Petter Selasky " UE_BULK_OK : %llu\n" 499*fa6d8b65SHans Petter Selasky " UE_INTERRUPT_OK : %llu\n" 500*fa6d8b65SHans Petter Selasky " UE_CONTROL_FAIL : %llu\n" 501*fa6d8b65SHans Petter Selasky " UE_ISOCHRONOUS_FAIL : %llu\n" 502*fa6d8b65SHans Petter Selasky " UE_BULK_FAIL : %llu\n" 503*fa6d8b65SHans Petter Selasky " UE_INTERRUPT_FAIL : %llu\n" 504*fa6d8b65SHans Petter Selasky "}\n", 505*fa6d8b65SHans Petter Selasky (unsigned long long)st.xfer_ok[0], 506*fa6d8b65SHans Petter Selasky (unsigned long long)st.xfer_ok[1], 507*fa6d8b65SHans Petter Selasky (unsigned long long)st.xfer_ok[2], 508*fa6d8b65SHans Petter Selasky (unsigned long long)st.xfer_ok[3], 509*fa6d8b65SHans Petter Selasky (unsigned long long)st.xfer_fail[0], 510*fa6d8b65SHans Petter Selasky (unsigned long long)st.xfer_fail[1], 511*fa6d8b65SHans Petter Selasky (unsigned long long)st.xfer_fail[2], 512*fa6d8b65SHans Petter Selasky (unsigned long long)st.xfer_fail[3]); 513*fa6d8b65SHans Petter Selasky } 514*fa6d8b65SHans Petter Selasky } 515