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: 68eabe30fcSAlfred Perlstein return ("SUPER (4.8Gbps)"); 69eabe30fcSAlfred Perlstein default: 70eabe30fcSAlfred Perlstein break; 71eabe30fcSAlfred Perlstein } 72eabe30fcSAlfred Perlstein 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 struct LIBUSB20_CONTROL_SETUP_DECODED req; 100eabe30fcSAlfred Perlstein uint16_t lang_id; 101eabe30fcSAlfred Perlstein uint8_t index; 102eabe30fcSAlfred Perlstein uint8_t temp_string[256]; 103eabe30fcSAlfred Perlstein 104eabe30fcSAlfred Perlstein printf("%s%s = 0x%04x ", plevel, field, value); 105eabe30fcSAlfred Perlstein 106eabe30fcSAlfred Perlstein if ((field[0] != 'i') || (field[1] == 'd')) { 107eabe30fcSAlfred Perlstein printf("\n"); 108eabe30fcSAlfred Perlstein return; 109eabe30fcSAlfred Perlstein } 110eabe30fcSAlfred Perlstein if (value == 0) { 111eabe30fcSAlfred Perlstein printf(" <no string> \n"); 112eabe30fcSAlfred Perlstein return; 113eabe30fcSAlfred Perlstein } 114eabe30fcSAlfred Perlstein LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req); 115eabe30fcSAlfred Perlstein 116eabe30fcSAlfred Perlstein lang_id = 0; 117eabe30fcSAlfred Perlstein index = 0; 118eabe30fcSAlfred Perlstein 119eabe30fcSAlfred Perlstein req.bmRequestType = 120eabe30fcSAlfred Perlstein LIBUSB20_REQUEST_TYPE_STANDARD | 121eabe30fcSAlfred Perlstein LIBUSB20_RECIPIENT_DEVICE | 122eabe30fcSAlfred Perlstein LIBUSB20_ENDPOINT_IN; 123eabe30fcSAlfred Perlstein req.bRequest = LIBUSB20_REQUEST_GET_DESCRIPTOR; 124eabe30fcSAlfred Perlstein req.wValue = (256 * LIBUSB20_DT_STRING) | index; 125eabe30fcSAlfred Perlstein req.wIndex = lang_id; 126eabe30fcSAlfred Perlstein req.wLength = 4; /* bytes */ 127eabe30fcSAlfred Perlstein 128eabe30fcSAlfred Perlstein if (libusb20_dev_request_sync(pdev, &req, 129eabe30fcSAlfred Perlstein temp_string, NULL, 1000, 0)) { 130eabe30fcSAlfred Perlstein goto done; 131eabe30fcSAlfred Perlstein } 132eabe30fcSAlfred Perlstein lang_id = temp_string[2] | (temp_string[3] << 8); 133eabe30fcSAlfred Perlstein 134eabe30fcSAlfred Perlstein printf(" LangId:0x%04x <", lang_id); 135eabe30fcSAlfred Perlstein 136eabe30fcSAlfred Perlstein index = value; 137eabe30fcSAlfred Perlstein 138eabe30fcSAlfred Perlstein req.wValue = (256 * LIBUSB20_DT_STRING) | index; 139eabe30fcSAlfred Perlstein req.wIndex = lang_id; 140eabe30fcSAlfred Perlstein req.wLength = 4; /* bytes */ 141eabe30fcSAlfred Perlstein 142eabe30fcSAlfred Perlstein if (libusb20_dev_request_sync(pdev, &req, 143eabe30fcSAlfred Perlstein temp_string, NULL, 1000, 0)) { 144eabe30fcSAlfred Perlstein printf("ERROR>\n"); 145eabe30fcSAlfred Perlstein goto done; 146eabe30fcSAlfred Perlstein } 147eabe30fcSAlfred Perlstein req.wValue = (256 * LIBUSB20_DT_STRING) | index; 148eabe30fcSAlfred Perlstein req.wIndex = lang_id; 149eabe30fcSAlfred Perlstein req.wLength = temp_string[0]; /* bytes */ 150eabe30fcSAlfred Perlstein 151eabe30fcSAlfred Perlstein if (libusb20_dev_request_sync(pdev, &req, 152eabe30fcSAlfred Perlstein temp_string, NULL, 1000, 0)) { 153eabe30fcSAlfred Perlstein printf("ERROR>\n"); 154eabe30fcSAlfred Perlstein goto done; 155eabe30fcSAlfred Perlstein } 156eabe30fcSAlfred Perlstein req.wLength /= 2; 157eabe30fcSAlfred Perlstein 158eabe30fcSAlfred Perlstein for (index = 1; index != req.wLength; index++) { 159eabe30fcSAlfred Perlstein if (isprint(temp_string[(2 * index) + 0])) { 160eabe30fcSAlfred Perlstein printf("%c", temp_string[(2 * index) + 0]); 161eabe30fcSAlfred Perlstein } else if (isprint(temp_string[(2 * index) + 1])) { 162eabe30fcSAlfred Perlstein printf("%c", temp_string[(2 * index) + 1]); 163eabe30fcSAlfred Perlstein } else { 164eabe30fcSAlfred Perlstein printf("?"); 165eabe30fcSAlfred Perlstein } 166eabe30fcSAlfred Perlstein } 167eabe30fcSAlfred Perlstein printf(">\n"); 168eabe30fcSAlfred Perlstein done: 169eabe30fcSAlfred Perlstein return; 170eabe30fcSAlfred Perlstein } 171eabe30fcSAlfred Perlstein 172eabe30fcSAlfred Perlstein static void 173eabe30fcSAlfred Perlstein dump_extra(struct libusb20_me_struct *str, const char *plevel) 174eabe30fcSAlfred Perlstein { 175eabe30fcSAlfred Perlstein const uint8_t *ptr; 176eabe30fcSAlfred Perlstein uint8_t x; 177eabe30fcSAlfred Perlstein 178eabe30fcSAlfred Perlstein ptr = NULL; 179eabe30fcSAlfred Perlstein 180eabe30fcSAlfred Perlstein while ((ptr = libusb20_desc_foreach(str, ptr))) { 181eabe30fcSAlfred Perlstein printf("\n" "%sAdditional Descriptor\n\n", plevel); 182eabe30fcSAlfred Perlstein printf("%sbLength = 0x%02x\n", plevel, ptr[0]); 183eabe30fcSAlfred Perlstein printf("%sbDescriptorType = 0x%02x\n", plevel, ptr[1]); 184eabe30fcSAlfred Perlstein if (ptr[0] > 1) 185eabe30fcSAlfred Perlstein printf("%sbDescriptorSubType = 0x%02x\n", 186eabe30fcSAlfred Perlstein plevel, ptr[2]); 187eabe30fcSAlfred Perlstein printf("%s RAW dump: ", plevel); 188eabe30fcSAlfred Perlstein for (x = 0; x != ptr[0]; x++) { 189eabe30fcSAlfred Perlstein if ((x % 8) == 0) { 190eabe30fcSAlfred Perlstein printf("\n%s 0x%02x | ", plevel, x); 191eabe30fcSAlfred Perlstein } 192eabe30fcSAlfred Perlstein printf("0x%02x%s", ptr[x], 193eabe30fcSAlfred Perlstein (x != (ptr[0] - 1)) ? ", " : (x % 8) ? "\n" : ""); 194eabe30fcSAlfred Perlstein } 195eabe30fcSAlfred Perlstein printf("\n"); 196eabe30fcSAlfred Perlstein } 197eabe30fcSAlfred Perlstein return; 198eabe30fcSAlfred Perlstein } 199eabe30fcSAlfred Perlstein 200eabe30fcSAlfred Perlstein static void 201eabe30fcSAlfred Perlstein dump_endpoint(struct libusb20_device *pdev, 202eabe30fcSAlfred Perlstein struct libusb20_endpoint *ep) 203eabe30fcSAlfred Perlstein { 204eabe30fcSAlfred Perlstein struct LIBUSB20_ENDPOINT_DESC_DECODED *edesc; 205eabe30fcSAlfred Perlstein 206eabe30fcSAlfred Perlstein edesc = &ep->desc; 207eabe30fcSAlfred Perlstein LIBUSB20_ENDPOINT_DESC(DUMP3, edesc); 208eabe30fcSAlfred Perlstein dump_extra(&ep->extra, " " " " " "); 209eabe30fcSAlfred Perlstein return; 210eabe30fcSAlfred Perlstein } 211eabe30fcSAlfred Perlstein 212eabe30fcSAlfred Perlstein static void 213eabe30fcSAlfred Perlstein dump_iface(struct libusb20_device *pdev, 214eabe30fcSAlfred Perlstein struct libusb20_interface *iface) 215eabe30fcSAlfred Perlstein { 216eabe30fcSAlfred Perlstein struct LIBUSB20_INTERFACE_DESC_DECODED *idesc; 217eabe30fcSAlfred Perlstein uint8_t z; 218eabe30fcSAlfred Perlstein 219eabe30fcSAlfred Perlstein idesc = &iface->desc; 220eabe30fcSAlfred Perlstein LIBUSB20_INTERFACE_DESC(DUMP2, idesc); 221eabe30fcSAlfred Perlstein dump_extra(&iface->extra, " " " " " "); 222eabe30fcSAlfred Perlstein 223eabe30fcSAlfred Perlstein for (z = 0; z != iface->num_endpoints; z++) { 224eabe30fcSAlfred Perlstein printf("\n Endpoint %u\n", z); 225eabe30fcSAlfred Perlstein dump_endpoint(pdev, iface->endpoints + z); 226eabe30fcSAlfred Perlstein } 227eabe30fcSAlfred Perlstein return; 228eabe30fcSAlfred Perlstein } 229eabe30fcSAlfred Perlstein 230eabe30fcSAlfred Perlstein void 231eabe30fcSAlfred Perlstein dump_device_info(struct libusb20_device *pdev) 232eabe30fcSAlfred Perlstein { 233eabe30fcSAlfred Perlstein printf("%s, cfg=%u md=%s spd=%s pwr=%s\n", 234eabe30fcSAlfred Perlstein libusb20_dev_get_desc(pdev), 235eabe30fcSAlfred Perlstein libusb20_dev_get_config_index(pdev), 236eabe30fcSAlfred Perlstein dump_mode(libusb20_dev_get_mode(pdev)), 237eabe30fcSAlfred Perlstein dump_speed(libusb20_dev_get_speed(pdev)), 238eabe30fcSAlfred Perlstein dump_power_mode(libusb20_dev_get_power_mode(pdev))); 239eabe30fcSAlfred Perlstein return; 240eabe30fcSAlfred Perlstein } 241eabe30fcSAlfred Perlstein 242eabe30fcSAlfred Perlstein void 243eabe30fcSAlfred Perlstein dump_be_quirk_names(struct libusb20_backend *pbe) 244eabe30fcSAlfred Perlstein { 245eabe30fcSAlfred Perlstein struct libusb20_quirk q; 246eabe30fcSAlfred Perlstein uint16_t x; 247eabe30fcSAlfred Perlstein int err; 248eabe30fcSAlfred Perlstein 249eabe30fcSAlfred Perlstein memset(&q, 0, sizeof(q)); 250eabe30fcSAlfred Perlstein 251eabe30fcSAlfred Perlstein printf("\nDumping list of supported quirks:\n\n"); 252eabe30fcSAlfred Perlstein 253eabe30fcSAlfred Perlstein for (x = 0; x != 0xFFFF; x++) { 254eabe30fcSAlfred Perlstein 255eabe30fcSAlfred Perlstein err = libusb20_be_get_quirk_name(pbe, x, &q); 256eabe30fcSAlfred Perlstein if (err) { 257eabe30fcSAlfred Perlstein if (x == 0) { 258eabe30fcSAlfred Perlstein printf("No quirk names - maybe the USB quirk " 259eabe30fcSAlfred Perlstein "module has not been loaded.\n"); 260eabe30fcSAlfred Perlstein } 261eabe30fcSAlfred Perlstein break; 262eabe30fcSAlfred Perlstein } 263eabe30fcSAlfred Perlstein if (strcmp(q.quirkname, "UQ_NONE")) 264eabe30fcSAlfred Perlstein printf("%s\n", q.quirkname); 265eabe30fcSAlfred Perlstein } 266eabe30fcSAlfred Perlstein printf("\n"); 267eabe30fcSAlfred Perlstein return; 268eabe30fcSAlfred Perlstein } 269eabe30fcSAlfred Perlstein 270eabe30fcSAlfred Perlstein void 271eabe30fcSAlfred Perlstein dump_be_dev_quirks(struct libusb20_backend *pbe) 272eabe30fcSAlfred Perlstein { 273eabe30fcSAlfred Perlstein struct libusb20_quirk q; 274eabe30fcSAlfred Perlstein uint16_t x; 275eabe30fcSAlfred Perlstein int err; 276eabe30fcSAlfred Perlstein 277eabe30fcSAlfred Perlstein memset(&q, 0, sizeof(q)); 278eabe30fcSAlfred Perlstein 279eabe30fcSAlfred Perlstein printf("\nDumping current device quirks:\n\n"); 280eabe30fcSAlfred Perlstein 281eabe30fcSAlfred Perlstein for (x = 0; x != 0xFFFF; x++) { 282eabe30fcSAlfred Perlstein 283eabe30fcSAlfred Perlstein err = libusb20_be_get_dev_quirk(pbe, x, &q); 284eabe30fcSAlfred Perlstein if (err) { 285eabe30fcSAlfred Perlstein if (x == 0) { 286eabe30fcSAlfred Perlstein printf("No device quirks - maybe the USB quirk " 287eabe30fcSAlfred Perlstein "module has not been loaded.\n"); 288eabe30fcSAlfred Perlstein } 289eabe30fcSAlfred Perlstein break; 290eabe30fcSAlfred Perlstein } 291eabe30fcSAlfred Perlstein if (strcmp(q.quirkname, "UQ_NONE")) { 292eabe30fcSAlfred Perlstein printf("VID=0x%04x PID=0x%04x REVLO=0x%04x " 293eabe30fcSAlfred Perlstein "REVHI=0x%04x QUIRK=%s\n", 294eabe30fcSAlfred Perlstein q.vid, q.pid, q.bcdDeviceLow, 295eabe30fcSAlfred Perlstein q.bcdDeviceHigh, q.quirkname); 296eabe30fcSAlfred Perlstein } 297eabe30fcSAlfred Perlstein } 298eabe30fcSAlfred Perlstein printf("\n"); 299eabe30fcSAlfred Perlstein return; 300eabe30fcSAlfred Perlstein } 301eabe30fcSAlfred Perlstein 302eabe30fcSAlfred Perlstein void 303eabe30fcSAlfred Perlstein dump_be_access(struct libusb20_backend *pbe) 304eabe30fcSAlfred Perlstein { 305eabe30fcSAlfred Perlstein struct group *gr; 306eabe30fcSAlfred Perlstein struct passwd *pw; 307eabe30fcSAlfred Perlstein const char *owner; 308eabe30fcSAlfred Perlstein const char *group; 309eabe30fcSAlfred Perlstein uid_t uid; 310eabe30fcSAlfred Perlstein gid_t gid; 311eabe30fcSAlfred Perlstein mode_t mode; 312eabe30fcSAlfred Perlstein 313eabe30fcSAlfred Perlstein if (libusb20_be_get_owner(pbe, &uid, &gid)) { 314eabe30fcSAlfred Perlstein err(1, "could not get owner"); 315eabe30fcSAlfred Perlstein } 316eabe30fcSAlfred Perlstein if (libusb20_be_get_perm(pbe, &mode)) { 317eabe30fcSAlfred Perlstein err(1, "could not get permission"); 318eabe30fcSAlfred Perlstein } 319eabe30fcSAlfred Perlstein owner = (pw = getpwuid(uid)) ? pw->pw_name : "UNKNOWN"; 320eabe30fcSAlfred Perlstein group = (gr = getgrgid(gid)) ? gr->gr_name : "UNKNOWN"; 321eabe30fcSAlfred Perlstein 322eabe30fcSAlfred Perlstein if (mode || 1) { 323eabe30fcSAlfred Perlstein printf("Global Access: %s:%s 0%o\n", owner, group, mode); 324eabe30fcSAlfred Perlstein } else { 325eabe30fcSAlfred Perlstein printf("Global Access: <not set>\n"); 326eabe30fcSAlfred Perlstein } 327eabe30fcSAlfred Perlstein return; 328eabe30fcSAlfred Perlstein } 329eabe30fcSAlfred Perlstein 330eabe30fcSAlfred Perlstein void 331eabe30fcSAlfred Perlstein dump_device_access(struct libusb20_device *pdev, uint8_t iface) 332eabe30fcSAlfred Perlstein { 333eabe30fcSAlfred Perlstein struct group *gr; 334eabe30fcSAlfred Perlstein struct passwd *pw; 335eabe30fcSAlfred Perlstein const char *owner; 336eabe30fcSAlfred Perlstein const char *group; 337eabe30fcSAlfred Perlstein uid_t uid; 338eabe30fcSAlfred Perlstein gid_t gid; 339eabe30fcSAlfred Perlstein mode_t mode; 340eabe30fcSAlfred Perlstein 341eabe30fcSAlfred Perlstein if (libusb20_dev_get_owner(pdev, &uid, &gid)) { 342eabe30fcSAlfred Perlstein err(1, "could not get owner"); 343eabe30fcSAlfred Perlstein } 344eabe30fcSAlfred Perlstein if (libusb20_dev_get_perm(pdev, &mode)) { 345eabe30fcSAlfred Perlstein err(1, "could not get permission"); 346eabe30fcSAlfred Perlstein } 347eabe30fcSAlfred Perlstein if (mode) { 348eabe30fcSAlfred Perlstein owner = (pw = getpwuid(uid)) ? pw->pw_name : "UNKNOWN"; 349eabe30fcSAlfred Perlstein group = (gr = getgrgid(gid)) ? gr->gr_name : "UNKNOWN"; 350eabe30fcSAlfred Perlstein 351eabe30fcSAlfred Perlstein printf(" " "Device Access: %s:%s 0%o\n", owner, group, mode); 352eabe30fcSAlfred Perlstein 353eabe30fcSAlfred Perlstein } else { 354eabe30fcSAlfred Perlstein printf(" " "Device Access: <not set>\n"); 355eabe30fcSAlfred Perlstein } 356eabe30fcSAlfred Perlstein 357eabe30fcSAlfred Perlstein if (iface == 0xFF) { 358eabe30fcSAlfred Perlstein for (iface = 0; iface != 0xFF; iface++) { 359eabe30fcSAlfred Perlstein if (dump_device_iface_access(pdev, iface)) { 360eabe30fcSAlfred Perlstein break; 361eabe30fcSAlfred Perlstein } 362eabe30fcSAlfred Perlstein } 363eabe30fcSAlfred Perlstein } else { 364eabe30fcSAlfred Perlstein if (dump_device_iface_access(pdev, iface)) { 365eabe30fcSAlfred Perlstein err(1, "could not get interface access info"); 366eabe30fcSAlfred Perlstein } 367eabe30fcSAlfred Perlstein } 368eabe30fcSAlfred Perlstein return; 369eabe30fcSAlfred Perlstein } 370eabe30fcSAlfred Perlstein 371eabe30fcSAlfred Perlstein int 372eabe30fcSAlfred Perlstein dump_device_iface_access(struct libusb20_device *pdev, uint8_t iface) 373eabe30fcSAlfred Perlstein { 374eabe30fcSAlfred Perlstein struct group *gr; 375eabe30fcSAlfred Perlstein struct passwd *pw; 376eabe30fcSAlfred Perlstein const char *owner; 377eabe30fcSAlfred Perlstein const char *group; 378eabe30fcSAlfred Perlstein uid_t uid; 379eabe30fcSAlfred Perlstein gid_t gid; 380eabe30fcSAlfred Perlstein mode_t mode; 381eabe30fcSAlfred Perlstein int error; 382eabe30fcSAlfred Perlstein 383eabe30fcSAlfred Perlstein if ((error = libusb20_dev_get_iface_owner(pdev, iface, &uid, &gid))) { 384eabe30fcSAlfred Perlstein return (error); 385eabe30fcSAlfred Perlstein } 386eabe30fcSAlfred Perlstein if ((error = libusb20_dev_get_iface_perm(pdev, iface, &mode))) { 387eabe30fcSAlfred Perlstein return (error); 388eabe30fcSAlfred Perlstein } 389eabe30fcSAlfred Perlstein if (mode) { 390eabe30fcSAlfred Perlstein 391eabe30fcSAlfred Perlstein owner = (pw = getpwuid(uid)) ? pw->pw_name : "UNKNOWN"; 392eabe30fcSAlfred Perlstein group = (gr = getgrgid(gid)) ? gr->gr_name : "UNKNOWN"; 393eabe30fcSAlfred Perlstein 394eabe30fcSAlfred Perlstein printf(" " "Interface %u Access: %s:%s 0%o\n", iface, owner, group, mode); 395eabe30fcSAlfred Perlstein } else { 396eabe30fcSAlfred Perlstein printf(" " "Interface %u Access: <not set>\n", iface); 397eabe30fcSAlfred Perlstein } 398eabe30fcSAlfred Perlstein 399eabe30fcSAlfred Perlstein return (0); 400eabe30fcSAlfred Perlstein } 401eabe30fcSAlfred Perlstein 402eabe30fcSAlfred Perlstein void 403eabe30fcSAlfred Perlstein dump_device_desc(struct libusb20_device *pdev) 404eabe30fcSAlfred Perlstein { 405eabe30fcSAlfred Perlstein struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 406eabe30fcSAlfred Perlstein 407eabe30fcSAlfred Perlstein ddesc = libusb20_dev_get_device_desc(pdev); 408eabe30fcSAlfred Perlstein LIBUSB20_DEVICE_DESC(DUMP0, ddesc); 409eabe30fcSAlfred Perlstein return; 410eabe30fcSAlfred Perlstein } 411eabe30fcSAlfred Perlstein 412eabe30fcSAlfred Perlstein void 413eabe30fcSAlfred Perlstein dump_config(struct libusb20_device *pdev, uint8_t all_cfg) 414eabe30fcSAlfred Perlstein { 415eabe30fcSAlfred Perlstein struct LIBUSB20_CONFIG_DESC_DECODED *cdesc; 416eabe30fcSAlfred Perlstein struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 417eabe30fcSAlfred Perlstein struct libusb20_config *pcfg = NULL; 418eabe30fcSAlfred Perlstein uint8_t cfg_index; 419eabe30fcSAlfred Perlstein uint8_t cfg_index_end; 420eabe30fcSAlfred Perlstein uint8_t x; 421eabe30fcSAlfred Perlstein uint8_t y; 422eabe30fcSAlfred Perlstein 423eabe30fcSAlfred Perlstein ddesc = libusb20_dev_get_device_desc(pdev); 424eabe30fcSAlfred Perlstein 425eabe30fcSAlfred Perlstein if (all_cfg) { 426eabe30fcSAlfred Perlstein cfg_index = 0; 427eabe30fcSAlfred Perlstein cfg_index_end = ddesc->bNumConfigurations; 428eabe30fcSAlfred Perlstein } else { 429eabe30fcSAlfred Perlstein cfg_index = libusb20_dev_get_config_index(pdev); 430eabe30fcSAlfred Perlstein cfg_index_end = cfg_index + 1; 431eabe30fcSAlfred Perlstein } 432eabe30fcSAlfred Perlstein 433eabe30fcSAlfred Perlstein for (; cfg_index != cfg_index_end; cfg_index++) { 434eabe30fcSAlfred Perlstein 435eabe30fcSAlfred Perlstein pcfg = libusb20_dev_alloc_config(pdev, cfg_index); 436eabe30fcSAlfred Perlstein if (!pcfg) { 437eabe30fcSAlfred Perlstein continue; 438eabe30fcSAlfred Perlstein } 439eabe30fcSAlfred Perlstein printf("\n Configuration index %u\n\n", cfg_index); 440eabe30fcSAlfred Perlstein cdesc = &(pcfg->desc); 441eabe30fcSAlfred Perlstein LIBUSB20_CONFIG_DESC(DUMP1, cdesc); 442eabe30fcSAlfred Perlstein dump_extra(&(pcfg->extra), " " " "); 443eabe30fcSAlfred Perlstein 444eabe30fcSAlfred Perlstein for (x = 0; x != pcfg->num_interface; x++) { 445eabe30fcSAlfred Perlstein printf("\n Interface %u\n", x); 446eabe30fcSAlfred Perlstein dump_iface(pdev, pcfg->interface + x); 447eabe30fcSAlfred Perlstein printf("\n"); 448eabe30fcSAlfred Perlstein for (y = 0; y != (pcfg->interface + x)->num_altsetting; y++) { 449eabe30fcSAlfred Perlstein printf("\n Interface %u Alt %u\n", x, y + 1); 450eabe30fcSAlfred Perlstein dump_iface(pdev, 451eabe30fcSAlfred Perlstein (pcfg->interface + x)->altsetting + y); 452eabe30fcSAlfred Perlstein printf("\n"); 453eabe30fcSAlfred Perlstein } 454eabe30fcSAlfred Perlstein } 455eabe30fcSAlfred Perlstein printf("\n"); 456eabe30fcSAlfred Perlstein free(pcfg); 457eabe30fcSAlfred Perlstein } 458eabe30fcSAlfred Perlstein return; 459eabe30fcSAlfred Perlstein } 460