1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * Copyright 2016 Joyent, Inc. 26 */ 27 28 29 #include <sys/mdb_modapi.h> 30 31 32 #include <sys/usb/usba.h> 33 #include <sys/usb/usba/usba_types.h> 34 #include <sys/usb/clients/hid/hid.h> 35 #include <sys/usb/clients/hidparser/hidparser.h> 36 #include <sys/usb/clients/hidparser/hidparser_impl.h> 37 #include <sys/usb/usba/genconsole.h> 38 #include <sys/usb/clients/hid/hidvar.h> 39 40 41 /* ****************************************************************** */ 42 43 /* extenal definition */ 44 45 typedef struct mdb_ctf_id { 46 void *_opaque[2]; 47 } mdb_ctf_id_t; 48 49 extern int mdb_ctf_lookup_by_name(const char *, mdb_ctf_id_t *); 50 51 extern int mdb_devinfo2driver(uintptr_t, char *, size_t); 52 53 extern int mdb_devinfo2statep(uintptr_t, char *, uintptr_t *); 54 55 extern char *mdb_ddi_pathname(uintptr_t, char *, size_t); 56 57 58 /* ****************************************************************** */ 59 60 /* internal definition */ 61 62 #define OPT_TREE 0x01 63 #define OPT_VERB 0x02 64 65 #define STRLEN 256 66 #define BYTE_OFFSET 8 67 68 69 typedef struct usb_descr_item { 70 uint_t nlen; /* if it's an byte array, nlen += BYTE_OFFSET */ 71 char *name; /* descriptor item name */ 72 } usb_descr_item_t; 73 74 /* define the known descriptor items */ 75 static usb_descr_item_t usb_cfg_descr[] = { 76 {1, "bLength"}, 77 {1, "bDescriptorType"}, 78 {2, "wTotalLength"}, 79 {1, "bNumInterfaces"}, 80 {1, "bConfigurationValue"}, 81 {1, "iConfiguration"}, 82 {1, "bmAttributes"}, 83 {1, "bMaxPower"}, 84 }; 85 static uint_t usb_cfg_item = 8; 86 87 static usb_descr_item_t usb_ia_descr[] = { 88 {1, "bLength"}, 89 {1, "bDescriptorType"}, 90 {1, "bFirstInterface"}, 91 {1, "bInterfaceCount"}, 92 {1, "bFunctionClass"}, 93 {1, "bFunctionSubClass"}, 94 {1, "bFunctionProtocol"}, 95 {1, "iFunction"}, 96 }; 97 static uint_t usb_ia_item = 8; 98 99 static usb_descr_item_t usb_if_descr[] = { 100 {1, "bLength"}, 101 {1, "bDescriptorType"}, 102 {1, "bInterfaceNumber"}, 103 {1, "bAlternateSetting"}, 104 {1, "bNumEndpoints"}, 105 {1, "bInterfaceClass"}, 106 {1, "bInterfaceSubClass"}, 107 {1, "bInterfaceProtocol"}, 108 {1, "iInterface"}, 109 }; 110 static uint_t usb_if_item = 9; 111 112 static usb_descr_item_t usb_ep_descr[] = { 113 {1, "bLength"}, 114 {1, "bDescriptorType"}, 115 {1, "bEndpointAddress"}, 116 {1, "bmAttributes"}, 117 {2, "wMaxPacketSize"}, 118 {1, "bInterval"}, 119 }; 120 static uint_t usb_ep_item = 6; 121 122 static usb_descr_item_t usb_ep_ss_comp_descr[] = { 123 {1, "bLength"}, 124 {1, "bDescriptorType"}, 125 {1, "bMaxBurst"}, 126 {1, "bmAttributes"}, 127 {2, "wBytesPerInterval"} 128 }; 129 static uint_t usb_ep_ss_comp_item = 5; 130 131 static usb_descr_item_t usb_qlf_descr[] = { 132 {1, "bLength"}, 133 {1, "bDescriptorType"}, 134 {2, "bcdUSB"}, 135 {1, "bDeviceClass"}, 136 {1, "bDeviceSubClass"}, 137 {1, "bDeviceProtocol"}, 138 {1, "bMaxPacketSize0"}, 139 {1, "bNumConfigurations"}, 140 {1, "bReserved"}, 141 }; 142 static uint_t usb_qlf_item = 9; 143 144 static usb_descr_item_t usb_str_descr[] = { 145 {1, "bLength"}, 146 {1, "bDescriptorType"}, 147 {1, "bString"}, 148 }; 149 static uint_t usb_str_item = 3; 150 151 static usb_descr_item_t usb_wa_descr[] = { 152 {1, "bLength"}, 153 {1, "bDescriptorType"}, 154 {2, "bcdWAVersion"}, 155 {1, "bNumPorts"}, 156 {1, "bmAttributes"}, 157 {2, "wNumRPipes"}, 158 {2, "wRPipeMaxBlock"}, 159 {1, "bRPipeBlockSize"}, 160 {1, "bPwrOn2PwrGood"}, 161 {1, "bNumMMCIEs"}, 162 {1, "DeviceRemovable"}, 163 }; 164 165 static uint_t usb_wa_item = 11; 166 167 static usb_descr_item_t usb_hid_descr[] = { 168 {1, "bLength"}, 169 {1, "bDescriptorType"}, 170 {2, "bcdHID"}, 171 {1, "bCountryCode"}, 172 {1, "bNumDescriptors"}, 173 {1, "bReportDescriptorType"}, 174 {2, "wReportDescriptorLength"}, 175 }; 176 static uint_t usb_hid_item = 7; 177 178 static usb_descr_item_t usb_ac_header_descr[] = { 179 {1, "bLength"}, 180 {1, "bDescriptorType"}, 181 {1, "bDescriptorSubType"}, 182 {2, "bcdADC"}, 183 {2, "wTotalLength"}, 184 {1, "blnCollection"}, 185 {1, "baInterfaceNr"}, 186 }; 187 static uint_t usb_ac_header_item = 7; 188 189 static usb_descr_item_t usb_ac_input_term_descr[] = { 190 {1, "bLength"}, 191 {1, "bDescriptorType"}, 192 {1, "bDescriptorSubType"}, 193 {1, "bTerminalID"}, 194 {2, "wTerminalType"}, 195 {1, "bAssocTerminal"}, 196 {1, "bNrChannels"}, 197 {2, "wChannelConfig"}, 198 {1, "iChannelNames"}, 199 {1, "iTerminal"}, 200 }; 201 static uint_t usb_ac_input_term_item = 10; 202 203 static usb_descr_item_t usb_ac_output_term_descr[] = { 204 {1, "bLength"}, 205 {1, "bDescriptorType"}, 206 {1, "bDescriptorSubType"}, 207 {1, "bTerminalID"}, 208 {2, "wTerminalType"}, 209 {1, "bAssocTerminal"}, 210 {1, "bSourceID"}, 211 {1, "iTerminal"}, 212 }; 213 static uint_t usb_ac_output_term_item = 8; 214 215 static usb_descr_item_t usb_ac_mixer_descr[] = { 216 {1, "bLength"}, 217 {1, "bDescriptorType"}, 218 {1, "bDescriptorSubType"}, 219 {1, "bUnitID"}, 220 {1, "bNrInPins"}, 221 {1, "baSourceID"}, 222 }; 223 static uint_t usb_ac_mixer_item = 6; 224 225 static usb_descr_item_t usb_ac_selector_descr[] = { 226 {1, "bLength"}, 227 {1, "bDescriptorType"}, 228 {1, "bDescriptorSubType"}, 229 {1, "bUnitID"}, 230 {1, "bNrInPins"}, 231 {1, "baSourceID"}, 232 }; 233 static uint_t usb_ac_selector_item = 6; 234 235 static usb_descr_item_t usb_ac_feature_descr[] = { 236 {1, "bLength"}, 237 {1, "bDescriptorType"}, 238 {1, "bDescriptorSubType"}, 239 {1, "bUnitID"}, 240 {1, "bSourceID"}, 241 {1, "bControlSize"}, 242 {1, "bmaControls"}, 243 }; 244 static uint_t usb_ac_feature_item = 7; 245 246 static usb_descr_item_t usb_ac_processing_descr[] = { 247 {1, "bLength"}, 248 {1, "bDescriptorType"}, 249 {1, "bDescriptorSubType"}, 250 {1, "bUnitID"}, 251 {1, "wProcessType"}, 252 {1, "bNrInPins"}, 253 {1, "baSourceID"}, 254 }; 255 static uint_t usb_ac_processing_item = 7; 256 257 static usb_descr_item_t usb_ac_extension_descr[] = { 258 {1, "bLength"}, 259 {1, "bDescriptorType"}, 260 {1, "bDescriptorSubType"}, 261 {1, "wExtensionCode"}, 262 {1, "bUnitID"}, 263 {1, "bNrInPins"}, 264 {1, "baSourceID"}, 265 }; 266 static uint_t usb_ac_extension_item = 7; 267 268 static usb_descr_item_t usb_as_ep_descr[] = { 269 {1, "blength"}, 270 {1, "bDescriptorType"}, 271 {1, "bDescriptorSubType"}, 272 {1, "bmAttributes"}, 273 {1, "bLockDelayUnits"}, 274 {2, "wLockDelay"}, 275 }; 276 static uint_t usb_as_ep_item = 6; 277 278 static usb_descr_item_t usb_as_if_descr[] = { 279 {1, "blength"}, 280 {1, "bDescriptorType"}, 281 {1, "bDescriptorSubType"}, 282 {1, "bTerminalLink"}, 283 {1, "bDelay"}, 284 {2, "wFormatTag"}, 285 }; 286 static uint_t usb_as_if_item = 6; 287 288 static usb_descr_item_t usb_as_format_descr[] = { 289 {1, "blength"}, 290 {1, "bDescriptorType"}, 291 {1, "bDescriptorSubType"}, 292 {1, "bFormatType"}, 293 {1, "bNrChannels"}, 294 {1, "bSubFrameSize"}, 295 {1, "bBitResolution"}, 296 {1, "bSamFreqType"}, 297 {1, "bSamFreqs"}, 298 }; 299 static uint_t usb_as_format_item = 9; 300 301 static usb_descr_item_t usb_vc_header_descr[] = { 302 {1, "bLength"}, 303 {1, "bDescriptorType"}, 304 {1, "bDescriptorSubtype"}, 305 {2, "bcdUVC"}, 306 {2, "wTotalLength"}, 307 {4, "dwClockFrequency"}, 308 {1, "bInCollection"}, 309 }; 310 static uint_t usb_vc_header_item = 7; 311 312 static usb_descr_item_t usb_vc_input_term_descr[] = { 313 {1, "bLength"}, 314 {1, "bDescriptorType"}, 315 {1, "bDescriptorSubType"}, 316 {1, "bTerminalID"}, 317 {2, "wTerminalType"}, 318 {1, "AssocTerminal"}, 319 {1, "iTerminal"}, 320 }; 321 static uint_t usb_vc_input_term_item = 7; 322 323 static usb_descr_item_t usb_vc_output_term_descr[] = { 324 {1, "bLength"}, 325 {1, "bDescriptorType"}, 326 {1, "bDescriptorSubType"}, 327 {1, "bTerminalID"}, 328 {2, "wTerminalType"}, 329 {1, "AssocTerminal"}, 330 {1, "bSourceID"}, 331 {1, "iTerminal"}, 332 }; 333 static uint_t usb_vc_output_term_item = 8; 334 335 static usb_descr_item_t usb_vc_processing_descr[] = { 336 {1, "bLength"}, 337 {1, "bDescriptorType"}, 338 {1, "bDescriptorSubType"}, 339 {1, "bUnitID"}, 340 {1, "bSourceID"}, 341 {2, "wMaxMultiplier"}, 342 {1, "bControlSize"}, 343 {1, "bmControls"}, 344 }; 345 static uint_t usb_vc_processing_item = 8; 346 347 static usb_descr_item_t usb_vc_selector_descr[] = { 348 {1, "bLength"}, 349 {1, "bDescriptorType"}, 350 {1, "bDescriptorSubType"}, 351 {1, "bUnitID"}, 352 {1, "bNrInPins"}, 353 }; 354 static uint_t usb_vc_selector_item = 5; 355 356 static usb_descr_item_t usb_vc_extension_descr[] = { 357 {1, "bLength"}, 358 {1, "bDescriptorType"}, 359 {1, "bDescriptorSubType"}, 360 {1, "bUnitID"}, 361 {16 + BYTE_OFFSET, "guidExtensionCode[16]"}, 362 {1, "bNumControls"}, 363 {1, "bNrInPins"}, 364 }; 365 static uint_t usb_vc_extension_item = 7; 366 367 static usb_descr_item_t usb_vs_input_header_descr[] = { 368 {1, "bLength"}, 369 {1, "bDescriptorType"}, 370 {1, "bDescriptorSubType"}, 371 {1, "bNumFormats"}, 372 {2, "wTotalLength"}, 373 {1, "bEndpointAddress"}, 374 {1, "bmInfo"}, 375 {1, "bTerminalLink"}, 376 {1, "bStillCaptureMethod"}, 377 {1, "bTriggerSupport"}, 378 {1, "bTriggerUsage"}, 379 {1, "bControlSize"}, 380 {1, "bmaControls"}, 381 }; 382 static uint_t usb_vs_input_header_item = 13; 383 384 static usb_descr_item_t usb_vs_output_header_descr[] = { 385 {1, "bLength"}, 386 {1, "bDescriptorType"}, 387 {1, "bDescriptorSubType"}, 388 {1, "bNumFormats"}, 389 {2, "wTotalLength"}, 390 {1, "bEndpointAddress"}, 391 {1, "bTerminalLink"}, 392 {1, "bControlSize"}, 393 {1, "bmaControls"}, 394 }; 395 static uint_t usb_vs_output_header_item = 9; 396 397 static usb_descr_item_t usb_vs_still_image_descr[] = { 398 {1, "bLength"}, 399 {1, "bDescriptorType"}, 400 {1, "bDescriptorSubType"}, 401 {1, "bEndpointAddress"}, 402 {1, "bNumImageSizePatterns"}, 403 {2, "wWidth"}, 404 {2, "wHeight"}, 405 }; 406 static uint_t usb_vs_still_image_item = 7; 407 408 static usb_descr_item_t usb_vs_color_matching_descr[] = { 409 {1, "bLength"}, 410 {1, "bDescriptorType"}, 411 {1, "bDescriptorSubtype"}, 412 {1, "bColorPrimaries"}, 413 {1, "bTransferCharacteristics"}, 414 {1, "bMatrixCoefficients"}, 415 }; 416 static uint_t usb_vs_color_matching_item = 6; 417 418 static usb_descr_item_t usb_vs_2frame_descr[] = { 419 {1, "bLength"}, 420 {1, "bDescriptorType"}, 421 {1, "bDescriptorSubType"}, 422 {1, "bFrameIndex"}, 423 {1, "bmCapabilities"}, 424 {2, "wWidth"}, 425 {2, "wHeight"}, 426 {4, "dwMinBitRate"}, 427 {4, "dwMaxBitRate"}, 428 {4, "dwMaxVideoFrameBufferSize"}, 429 {4, "dwDefaultFrameInterval"}, 430 {1, "bFrameIntervalType"}, 431 }; 432 static uint_t usb_vs_2frame_item = 12; 433 434 static usb_descr_item_t usb_vs_format_mjpeg_descr[] = { 435 {1, "bLength"}, 436 {1, "bDescriptorType"}, 437 {1, "bDescriptorSubType"}, 438 {1, "bFormatIndex"}, 439 {1, "bNumFrameDescriptors"}, 440 {1, "bmFlags"}, 441 {1, "bDefaultFrameIndex"}, 442 {1, "bAspectRatioX"}, 443 {1, "bAspectRatioY"}, 444 {1, "bmInterlaceFlags"}, 445 {1, "bCopyProtect"}, 446 }; 447 static uint_t usb_vs_format_mjpeg_item = 11; 448 449 static usb_descr_item_t usb_vs_format_uncps_descr[] = { 450 {1, "bLength"}, 451 {1, "bDescriptorType"}, 452 {1, "bDescriptorSubType"}, 453 {1, "bFormatIndex"}, 454 {1, "bNumFrameDescriptors"}, 455 {16 + BYTE_OFFSET, "guidFormat[16]"}, 456 {1, "bBitsPerPixel"}, 457 {1, "bDefaultFrameIndex"}, 458 {1, "bAspectRatioX"}, 459 {1, "bAspectRatioY"}, 460 {1, "bmInterlaceFlags"}, 461 {1, "bCopyProtect"}, 462 }; 463 static uint_t usb_vs_format_uncps_item = 12; 464 465 static usb_descr_item_t usb_vs_format_mp2ts_descr[] = { 466 {1, "bLength"}, 467 {1, "bDescriptorType"}, 468 {1, "bDescriptorSubType"}, 469 {1, "bFormatIndex"}, 470 {1, "bDataOffset"}, 471 {1, "bPacketLength"}, 472 {1, "bStrideLength"}, 473 {16 + BYTE_OFFSET, "guidStrideFormat[16]"}, 474 }; 475 static uint_t usb_vs_format_mp2ts_item = 8; 476 477 static usb_descr_item_t usb_vs_format_dv_descr[] = { 478 {1, "bLength"}, 479 {1, "bDescriptorType"}, 480 {1, "bDescriptorSubType"}, 481 {1, "bFormatIndex"}, 482 {4, "dwMaxVideoFrameBufferSize"}, 483 {1, "bFormatType"}, 484 }; 485 static uint_t usb_vs_format_dv_item = 6; 486 487 488 /* ****************************************************************** */ 489 490 typedef struct hci_state { 491 void *hci_dip; 492 uint_t hci_instance; 493 void *hci_hcdi_ops; 494 uint_t hci_flags; 495 uint16_t vendor_id; 496 uint16_t device_id; 497 } hci_state_t; 498 499 static int prt_usb_tree(uintptr_t paddr, uint_t flag); 500 501 static int prt_usb_tree_node(uintptr_t paddr); 502 503 static void prt_usb_hid_item(uintptr_t paddr); 504 505 static void prt_usb_hid_item_params(entity_item_t *item); 506 507 static void prt_usb_hid_item_attrs(uintptr_t paddr); 508 509 static void prt_usb_hid_item_tags(uint_t tag); 510 511 static void prt_usb_hid_item_data(uintptr_t paddr, uint_t len); 512 513 static int prt_usb_desc(uintptr_t usb_cfg, uint_t cfg_len); 514 515 static int prt_usb_ac_desc(uintptr_t paddr, uint_t nlen); 516 517 static int prt_usb_as_desc(uintptr_t paddr, uint_t nlen); 518 519 static int prt_usb_vc_desc(uintptr_t paddr, uint_t nlen); 520 521 static int prt_usb_vs_desc(uintptr_t paddr, uint_t nlen); 522 523 static int print_descr(uintptr_t, uint_t, usb_descr_item_t *, uint_t); 524 525 static int print_struct(uintptr_t, uint_t, mdb_arg_t *); 526 527 static int prt_usb_buf(uintptr_t, uint_t); 528 529 530 /* ****************************************************************** */ 531 532 /* exported functions */ 533 534 void prt_usb_usage(void); 535 536 int prtusb(uintptr_t, uint_t, int, const mdb_arg_t *); 537 538 /* ****************************************************************** */ 539 540 /* help of prtusb */ 541 void 542 prt_usb_usage(void) 543 { 544 mdb_printf("%-8s : %s\n", "-v", "print all descriptors"); 545 mdb_printf("%-8s : %s\n", "-t", "print device trees"); 546 mdb_printf("%-8s : %s\n", "-i index", "print the device by index"); 547 } 548 549 /* the entry of ::prtusb */ 550 int 551 prtusb(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 552 { 553 static int count = 1; 554 uint64_t sel_num = 0; 555 uint_t usb_flag = 0; 556 usba_device_t usb_dev; 557 usb_dev_descr_t dev_desc; 558 struct dev_info usb_dip; 559 char strbuf[STRLEN]; 560 561 /* print all usba devices if no address assigned */ 562 if (!(flags & DCMD_ADDRSPEC)) { 563 if (mdb_walk_dcmd("usba_device", "prtusb", argc, argv) == -1) { 564 mdb_warn("failed to walk usba_device"); 565 566 return (DCMD_ERR); 567 } 568 569 return (DCMD_OK); 570 } 571 572 /* for the first device, print head */ 573 if (DCMD_HDRSPEC(flags)) { 574 count = 1; 575 mdb_printf("%<u>%-8s%-12s%-6s%-14s%-5s%-12s%-20s%</u>\n", 576 "INDEX", "DRIVER", "INST", "NODE", "GEN", "VID.PID", 577 "PRODUCT"); 578 } 579 580 if (mdb_getopts(argc, argv, 581 'i', MDB_OPT_UINT64, &sel_num, 582 't', MDB_OPT_SETBITS, OPT_TREE, &usb_flag, 583 'v', MDB_OPT_SETBITS, OPT_VERB, &usb_flag, NULL) != argc) { 584 585 return (DCMD_USAGE); 586 } 587 588 if (mdb_vread(&usb_dev, sizeof (usba_device_t), addr) == -1) { 589 mdb_warn("Failed to read usba_device!\n"); 590 591 return (DCMD_ERR); 592 } 593 594 if (mdb_vread(&usb_dip, sizeof (struct dev_info), 595 (uintptr_t)usb_dev.usb_dip) == -1) { 596 mdb_warn("Failed to read dev_info!\n"); 597 598 return (DCMD_ERR); 599 } 600 601 /* process the "-i" */ 602 if (sel_num && sel_num != count) { 603 count++; 604 605 return (DCMD_OK); 606 } 607 608 /* index number of device node */ 609 mdb_printf("%-8x", count++); 610 611 /* driver and instance */ 612 mdb_devinfo2driver((uintptr_t)usb_dev.usb_dip, strbuf, STRLEN); 613 mdb_printf("%-12s%-6d", strbuf, usb_dip.devi_instance); 614 615 /* node name */ 616 if (mdb_readstr(strbuf, STRLEN, 617 (uintptr_t)usb_dip.devi_node_name) != -1) { 618 619 mdb_printf("%-14s", strbuf); 620 } else { 621 622 mdb_printf("%-14s", "No Node Name"); 623 } 624 625 626 if (mdb_vread(&dev_desc, sizeof (usb_dev_descr_t), 627 (uintptr_t)usb_dev.usb_dev_descr) != -1) { 628 629 /* gen (note we read this from the bcd) */ 630 mdb_printf("%01x.%01x ", dev_desc.bcdUSB >> 8, 631 (dev_desc.bcdUSB & 0xf0) >> 4); 632 633 /* vid.pid */ 634 mdb_printf("%04x.%04x ", 635 dev_desc.idVendor, dev_desc.idProduct); 636 } 637 638 /* product string */ 639 if (mdb_readstr(strbuf, STRLEN, 640 (uintptr_t)usb_dev.usb_product_str) != -1) { 641 642 mdb_printf("%s\n", strbuf); 643 } else { 644 645 mdb_printf("%s\n", "No Product String"); 646 } 647 648 /* tree, print usb device tree info */ 649 if (usb_flag & OPT_TREE) { 650 651 mdb_printf("\nusba_device: 0x%x\n", addr); 652 653 mdb_printf("mfg_prod_sn: "); 654 if (mdb_readstr(strbuf, STRLEN, 655 (uintptr_t)usb_dev.usb_mfg_str) != -1) { 656 mdb_printf("%s - ", strbuf); 657 } else { 658 mdb_printf("NULL - "); 659 } 660 if (mdb_readstr(strbuf, STRLEN, 661 (uintptr_t)usb_dev.usb_product_str) != -1) { 662 mdb_printf("%s - ", strbuf); 663 } else { 664 mdb_printf("NULL -"); 665 } 666 if (mdb_readstr(strbuf, STRLEN, 667 (uintptr_t)usb_dev.usb_serialno_str) != -1) { 668 mdb_printf("%s", strbuf); 669 } else { 670 mdb_printf("NULL"); 671 } 672 673 mdb_printf("\n\n"); 674 prt_usb_tree((uintptr_t)usb_dev.usb_dip, 0); 675 } 676 677 /* verbose, print all descriptors */ 678 if (usb_flag & OPT_VERB) { 679 int i; 680 uintptr_t cfg_buf; 681 uint16_t cfg_len; 682 683 mdb_printf("\n"); 684 685 /* device descriptor */ 686 prt_usb_desc((uintptr_t)usb_dev.usb_dev_descr, 18); 687 688 /* config cloud descriptors */ 689 if (usb_dev.usb_n_cfgs == 1) { 690 mdb_inc_indent(4); 691 mdb_printf("-- Active Config Index 0\n"); 692 mdb_dec_indent(4); 693 prt_usb_desc((uintptr_t)usb_dev.usb_cfg, 694 usb_dev.usb_cfg_length); 695 } else { 696 /* multiple configs */ 697 for (i = 0; i < usb_dev.usb_n_cfgs; i++) { 698 699 if ((mdb_vread(&cfg_len, sizeof (uint16_t), 700 (uintptr_t)(usb_dev.usb_cfg_array_len + i)) 701 != -1) && 702 (mdb_vread(&cfg_buf, sizeof (uintptr_t), 703 (uintptr_t)(usb_dev.usb_cfg_array + i)) 704 != -1)) { 705 mdb_inc_indent(4); 706 if (cfg_buf == 707 (uintptr_t)usb_dev.usb_cfg) { 708 mdb_printf("-- Active Config" 709 " Index %x\n", i); 710 } else { 711 mdb_printf("-- Inactive Config" 712 " Index %x\n", i); 713 } 714 mdb_dec_indent(4); 715 716 prt_usb_desc(cfg_buf, cfg_len); 717 } 718 } 719 } 720 } 721 722 if (usb_flag) { 723 724 mdb_printf("%<u>%-72s%</u>\n", " "); 725 } 726 727 return (DCMD_OK); 728 } 729 730 /* print the info required by "-t" */ 731 static int 732 prt_usb_tree(uintptr_t paddr, uint_t flag) 733 { 734 struct dev_info usb_dip; 735 736 if (mdb_vread(&usb_dip, sizeof (struct dev_info), paddr) == -1) { 737 mdb_warn("prt_usb_tree: Failed to read dev_info!\n"); 738 739 return (DCMD_ERR); 740 } 741 742 prt_usb_tree_node(paddr); 743 744 if (usb_dip.devi_child) { 745 746 mdb_printf("{\n"); 747 mdb_inc_indent(4); 748 prt_usb_tree((uintptr_t)usb_dip.devi_child, 1); 749 mdb_dec_indent(4); 750 mdb_printf("}\n\n"); 751 } 752 753 if (usb_dip.devi_sibling && flag == 1) { 754 /* print the sibling if flag == 1 */ 755 756 prt_usb_tree((uintptr_t)usb_dip.devi_sibling, 1); 757 } 758 759 return (DCMD_OK); 760 } 761 762 static int 763 prt_usb_tree_node(uintptr_t paddr) 764 { 765 struct dev_info usb_dip; 766 uintptr_t statep; 767 uint_t errlevel; 768 char driver_name[STRLEN] = ""; 769 char strbuf[STRLEN] = ""; 770 771 if (mdb_vread(&usb_dip, sizeof (struct dev_info), paddr) == -1) { 772 mdb_warn("prt_usb_tree_node: Failed to read dev_info!\n"); 773 774 return (DCMD_ERR); 775 } 776 777 /* node name */ 778 if (mdb_readstr(strbuf, STRLEN, 779 (uintptr_t)usb_dip.devi_node_name) != -1) { 780 mdb_printf("%s, ", strbuf); 781 } else { 782 mdb_printf("%s, ", "node_name"); 783 } 784 785 /* instance */ 786 mdb_printf("instance #%d ", usb_dip.devi_instance); 787 788 /* driver name */ 789 if (DDI_CF2(&usb_dip)) { 790 791 mdb_devinfo2driver(paddr, driver_name, STRLEN); 792 mdb_printf("(driver name: %s)\n", driver_name); 793 } else { 794 795 mdb_printf("(driver not attached)\n"); 796 } 797 798 /* device path */ 799 mdb_ddi_pathname(paddr, strbuf, STRLEN); 800 mdb_printf(" %s\n", strbuf); 801 802 /* dip addr */ 803 mdb_printf(" dip: 0x%x\n", paddr); 804 805 /* softe_sate */ 806 mdb_snprintf(strbuf, STRLEN, "%s_statep", driver_name); 807 if (mdb_devinfo2statep(paddr, strbuf, &statep) != -1) { 808 mdb_printf(" %s: 0x%x\n", strbuf, statep); 809 } 810 811 /* error level */ 812 mdb_snprintf(strbuf, STRLEN, "%s_errlevel", driver_name); 813 if (mdb_readvar(&errlevel, strbuf) != -1) { 814 mdb_printf(" %s: 0x%x\n", strbuf, errlevel); 815 } 816 817 if (strcmp(driver_name, "ehci") == 0) { 818 mdb_arg_t argv[] = { 819 {MDB_TYPE_STRING, {"ehci_state_t"}}, 820 {MDB_TYPE_STRING, {"ehci_root_hub.rh_descr"}} 821 }; 822 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 823 } 824 825 if (strcmp(driver_name, "ohci") == 0) { 826 mdb_arg_t argv[] = { 827 {MDB_TYPE_STRING, {"ohci_state_t"}}, 828 {MDB_TYPE_STRING, {"ohci_root_hub.rh_descr"}} 829 }; 830 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 831 } 832 833 if (strcmp(driver_name, "uhci") == 0) { 834 mdb_arg_t argv[] = { 835 {MDB_TYPE_STRING, {"uhci_state_t"}}, 836 {MDB_TYPE_STRING, {"uhci_root_hub.rh_descr"}} 837 }; 838 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 839 } 840 841 if (strcmp(driver_name, "hubd") == 0) { 842 mdb_arg_t argv[] = { 843 {MDB_TYPE_STRING, {"hubd_t"}}, 844 {MDB_TYPE_STRING, {"h_ep1_xdescr.uex_ep"}} 845 }; 846 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 847 } 848 849 if (strcmp(driver_name, "hid") == 0) { 850 hid_state_t hidp; 851 852 if (mdb_vread(&hidp, sizeof (hid_state_t), statep) != -1) { 853 hidparser_handle hid_report; 854 855 if (mdb_vread(&hid_report, sizeof (hidparser_handle), 856 (uintptr_t)hidp.hid_report_descr) != -1) { 857 858 mdb_inc_indent(2); 859 860 mdb_printf("\n"); 861 prt_usb_hid_item((uintptr_t) 862 hid_report.hidparser_handle_parse_tree); 863 864 mdb_dec_indent(2); 865 } 866 } 867 } 868 869 mdb_printf("\n"); 870 871 return (DCMD_OK); 872 } 873 874 /* print hid report descriptor */ 875 static void 876 prt_usb_hid_item(uintptr_t paddr) 877 { 878 entity_item_t item; 879 if (mdb_vread(&item, sizeof (entity_item_t), paddr) != -1) { 880 881 prt_usb_hid_item_attrs((uintptr_t)item.entity_item_attributes); 882 prt_usb_hid_item_params(&item); 883 884 if (item.info.child) { 885 mdb_inc_indent(4); 886 prt_usb_hid_item((uintptr_t)item.info.child); 887 mdb_dec_indent(4); 888 } 889 890 if (item.entity_item_right_sibling) { 891 prt_usb_hid_item((uintptr_t) 892 item.entity_item_right_sibling); 893 } 894 } 895 } 896 897 static void 898 prt_usb_hid_item_params(entity_item_t *item) 899 { 900 switch (item->entity_item_type) { 901 case 0x80: 902 mdb_printf("INPUT "); 903 904 break; 905 case 0x90: 906 mdb_printf("OUTPUT "); 907 908 break; 909 case 0xA0: 910 mdb_printf("COLLECTION "); 911 912 break; 913 case 0xB0: 914 mdb_printf("FEATURE "); 915 916 break; 917 case 0xC0: 918 mdb_printf("END_COLLECTION "); 919 920 break; 921 default: 922 mdb_printf("MAIN_ITEM "); 923 924 break; 925 } 926 927 prt_usb_hid_item_data((uintptr_t)item->entity_item_params, 928 item->entity_item_params_leng); 929 930 mdb_printf("\n"); 931 } 932 933 static void 934 prt_usb_hid_item_attrs(uintptr_t paddr) 935 { 936 entity_attribute_t attr; 937 938 if (mdb_vread(&attr, sizeof (entity_attribute_t), paddr) != -1) { 939 940 prt_usb_hid_item_tags(attr.entity_attribute_tag); 941 prt_usb_hid_item_data((uintptr_t)attr.entity_attribute_value, 942 attr.entity_attribute_length); 943 944 mdb_printf("\n"); 945 946 if (attr.entity_attribute_next) { 947 prt_usb_hid_item_attrs((uintptr_t) 948 attr.entity_attribute_next); 949 } 950 } 951 } 952 953 static void 954 prt_usb_hid_item_data(uintptr_t paddr, uint_t len) 955 { 956 char data[4]; 957 int i; 958 959 if (len > 4) { 960 mdb_warn("Incorrect entity_item_length: 0x%x\n", len); 961 962 return; 963 } 964 965 if (mdb_vread(data, len, paddr) != -1) { 966 967 mdb_printf("( "); 968 for (i = 0; i < len; i++) { 969 mdb_printf("0x%02x ", data[i] & 0xff); 970 } 971 mdb_printf(")"); 972 } 973 } 974 975 static void 976 prt_usb_hid_item_tags(uint_t tag) 977 { 978 switch (tag) { 979 case 0x04: 980 mdb_printf("usage page "); 981 982 break; 983 case 0x14: 984 mdb_printf("logical minimum "); 985 986 break; 987 case 0x24: 988 mdb_printf("logical maximum "); 989 990 break; 991 case 0x34: 992 mdb_printf("physical minimum "); 993 994 break; 995 case 0x44: 996 mdb_printf("physical maximum "); 997 998 break; 999 case 0x54: 1000 mdb_printf("exponent "); 1001 1002 break; 1003 case 0x64: 1004 mdb_printf("unit "); 1005 1006 break; 1007 case 0x74: 1008 mdb_printf("report size "); 1009 1010 break; 1011 case 0x84: 1012 mdb_printf("report id "); 1013 1014 break; 1015 case 0x94: 1016 mdb_printf("report count "); 1017 1018 break; 1019 case 0x08: 1020 mdb_printf("usage "); 1021 1022 break; 1023 case 0x18: 1024 mdb_printf("usage min "); 1025 1026 break; 1027 case 0x28: 1028 mdb_printf("usage max "); 1029 1030 break; 1031 1032 default: 1033 mdb_printf("tag "); 1034 } 1035 } 1036 1037 /* print the info required by "-v" */ 1038 static int 1039 prt_usb_desc(uintptr_t usb_cfg, uint_t cfg_len) 1040 { 1041 uintptr_t paddr = usb_cfg; 1042 uintptr_t pend = usb_cfg + cfg_len; 1043 uchar_t desc_type, nlen; 1044 usb_if_descr_t usb_if; 1045 ulong_t indent = 0; 1046 1047 mdb_arg_t argv = {MDB_TYPE_STRING, {"usb_dev_descr_t"}}; 1048 1049 if (mdb_vread(&nlen, 1, paddr) == -1) { 1050 1051 return (DCMD_ERR); 1052 } 1053 while ((paddr + nlen <= pend) && (nlen > 0)) { 1054 if (mdb_vread(&desc_type, 1, paddr + 1) == -1) { 1055 1056 return (DCMD_ERR); 1057 } 1058 1059 switch (desc_type) { 1060 case USB_DESCR_TYPE_DEV: 1061 mdb_printf("Device Descriptor\n"); 1062 print_struct(paddr, nlen, &argv); 1063 1064 break; 1065 case USB_DESCR_TYPE_CFG: 1066 indent = 4; 1067 mdb_inc_indent(indent); 1068 mdb_printf("Configuration Descriptor\n"); 1069 print_descr(paddr, nlen, usb_cfg_descr, usb_cfg_item); 1070 mdb_dec_indent(indent); 1071 1072 break; 1073 case USB_DESCR_TYPE_STRING: 1074 mdb_printf("String Descriptor\n"); 1075 print_descr(paddr, nlen, usb_str_descr, usb_str_item); 1076 1077 break; 1078 case USB_DESCR_TYPE_IF: 1079 indent = 8; 1080 mdb_inc_indent(indent); 1081 mdb_printf("Interface Descriptor\n"); 1082 print_descr(paddr, nlen, usb_if_descr, usb_if_item); 1083 mdb_dec_indent(indent); 1084 mdb_vread(&usb_if, sizeof (usb_if_descr_t), paddr); 1085 1086 break; 1087 case USB_DESCR_TYPE_EP: 1088 indent = 8; 1089 mdb_inc_indent(indent); 1090 mdb_printf("Endpoint Descriptor\n"); 1091 print_descr(paddr, nlen, usb_ep_descr, usb_ep_item); 1092 mdb_dec_indent(indent); 1093 1094 break; 1095 case USB_DESCR_TYPE_SS_EP_COMP: 1096 indent = 12; 1097 mdb_inc_indent(indent); 1098 mdb_printf("SuperSpeed Endpoint Companion " 1099 "Descriptor\n"); 1100 print_descr(paddr, nlen, usb_ep_ss_comp_descr, 1101 usb_ep_ss_comp_item); 1102 mdb_dec_indent(indent); 1103 1104 break; 1105 case USB_DESCR_TYPE_DEV_QLF: 1106 mdb_printf("Device_Qualifier Descriptor\n"); 1107 print_descr(paddr, nlen, usb_qlf_descr, usb_qlf_item); 1108 1109 break; 1110 case USB_DESCR_TYPE_OTHER_SPEED_CFG: 1111 indent = 4; 1112 mdb_inc_indent(indent); 1113 mdb_printf("Other_Speed_Configuration Descriptor\n"); 1114 print_descr(paddr, nlen, usb_cfg_descr, usb_cfg_item); 1115 mdb_dec_indent(indent); 1116 1117 break; 1118 case USB_DESCR_TYPE_IA: 1119 indent = 6; 1120 mdb_inc_indent(indent); 1121 mdb_printf("Interface_Association Descriptor\n"); 1122 print_descr(paddr, nlen, usb_ia_descr, usb_ia_item); 1123 mdb_dec_indent(indent); 1124 1125 break; 1126 case 0x21: /* hid descriptor */ 1127 indent = 12; 1128 mdb_inc_indent(indent); 1129 if (usb_if.bInterfaceClass == 0xe0 && 1130 usb_if.bInterfaceSubClass == 0x02) { 1131 mdb_printf("WA Descriptor\n"); 1132 print_descr(paddr, nlen, usb_wa_descr, 1133 usb_wa_item); 1134 } else { 1135 mdb_printf("HID Descriptor\n"); 1136 print_descr(paddr, nlen, usb_hid_descr, 1137 usb_hid_item); 1138 } 1139 mdb_dec_indent(indent); 1140 1141 break; 1142 case 0x24: /* class specific interfce descriptor */ 1143 indent = 12; 1144 mdb_inc_indent(indent); 1145 if (usb_if.bInterfaceClass == 1 && 1146 usb_if.bInterfaceSubClass == 1) { 1147 mdb_printf("AudioControl_Interface: "); 1148 prt_usb_ac_desc(paddr, nlen); 1149 1150 } else if (usb_if.bInterfaceClass == 1 && 1151 usb_if.bInterfaceSubClass == 2) { 1152 mdb_printf("AudioStream_Interface: "); 1153 prt_usb_as_desc(paddr, nlen); 1154 1155 } else if (usb_if.bInterfaceClass == 0x0E && 1156 usb_if.bInterfaceSubClass == 1) { 1157 mdb_printf("VideoControl_Interface: "); 1158 prt_usb_vc_desc(paddr, nlen); 1159 1160 1161 } else if (usb_if.bInterfaceClass == 0x0E && 1162 usb_if.bInterfaceSubClass == 2) { 1163 mdb_printf("VideoStream_Interface: "); 1164 prt_usb_vs_desc(paddr, nlen); 1165 1166 } else { 1167 mdb_printf("Unknown_Interface:" 1168 "0x%x\n", desc_type); 1169 prt_usb_buf(paddr, nlen); 1170 } 1171 mdb_dec_indent(indent); 1172 1173 break; 1174 case 0x25: /* class specific endpoint descriptor */ 1175 indent = 12; 1176 mdb_inc_indent(indent); 1177 if (usb_if.bInterfaceClass == 0x01) { 1178 mdb_printf("AudioEndpoint:\n"); 1179 print_descr(paddr, nlen, 1180 usb_as_ep_descr, usb_as_ep_item); 1181 1182 } else if (usb_if.bInterfaceClass == 0x0E) { 1183 mdb_printf("VideoEndpoint:\n"); 1184 print_descr(paddr, nlen, 1185 usb_ep_descr, usb_ep_item); 1186 1187 } else { 1188 mdb_printf("Unknown_Endpoint:" 1189 "0x%x\n", desc_type); 1190 prt_usb_buf(paddr, nlen); 1191 } 1192 mdb_dec_indent(indent); 1193 1194 break; 1195 default: 1196 mdb_inc_indent(indent); 1197 mdb_printf("Unknown Descriptor: 0x%x\n", desc_type); 1198 prt_usb_buf(paddr, nlen); 1199 mdb_dec_indent(indent); 1200 1201 break; 1202 } 1203 1204 paddr += nlen; 1205 if (mdb_vread(&nlen, 1, paddr) == -1) { 1206 1207 return (DCMD_ERR); 1208 } 1209 }; 1210 1211 return (DCMD_OK); 1212 } 1213 1214 1215 /* print audio class specific control descriptor */ 1216 static int 1217 prt_usb_ac_desc(uintptr_t addr, uint_t nlen) 1218 { 1219 uchar_t sub_type; 1220 1221 if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 1222 1223 return (DCMD_ERR); 1224 } 1225 switch (sub_type) { 1226 case 0x01: 1227 mdb_printf("header Descriptor\n"); 1228 print_descr(addr, nlen, 1229 usb_ac_header_descr, usb_ac_header_item); 1230 1231 break; 1232 case 0x02: 1233 mdb_printf("input_terminal Descriptor\n"); 1234 print_descr(addr, nlen, 1235 usb_ac_input_term_descr, usb_ac_input_term_item); 1236 1237 break; 1238 case 0x03: 1239 mdb_printf("output_terminal Descriptor\n"); 1240 print_descr(addr, nlen, 1241 usb_ac_output_term_descr, usb_ac_output_term_item); 1242 1243 break; 1244 case 0x04: 1245 mdb_printf("mixer_unit Descriptor\n"); 1246 print_descr(addr, nlen, 1247 usb_ac_mixer_descr, usb_ac_mixer_item); 1248 1249 break; 1250 case 0x05: 1251 mdb_printf("selector_unit Descriptor\n"); 1252 print_descr(addr, nlen, 1253 usb_ac_selector_descr, usb_ac_selector_item); 1254 1255 break; 1256 case 0x06: 1257 mdb_printf("feature_unit Descriptor\n"); 1258 print_descr(addr, nlen, 1259 usb_ac_feature_descr, usb_ac_feature_item); 1260 1261 break; 1262 case 0x07: 1263 mdb_printf("processing_unit Descriptor\n"); 1264 print_descr(addr, nlen, 1265 usb_ac_processing_descr, usb_ac_processing_item); 1266 1267 break; 1268 case 0x08: 1269 mdb_printf("extension_unit Descriptor\n"); 1270 print_descr(addr, nlen, 1271 usb_ac_extension_descr, usb_ac_extension_item); 1272 1273 break; 1274 default: 1275 mdb_printf("Unknown AC sub-descriptor 0x%x\n", sub_type); 1276 prt_usb_buf(addr, nlen); 1277 1278 break; 1279 } 1280 1281 return (DCMD_OK); 1282 } 1283 1284 /* print audio class specific stream descriptor */ 1285 static int 1286 prt_usb_as_desc(uintptr_t addr, uint_t nlen) 1287 { 1288 uchar_t sub_type; 1289 1290 if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 1291 1292 return (DCMD_ERR); 1293 } 1294 switch (sub_type) { 1295 case 0x01: 1296 mdb_printf("general_interface Descriptor\n"); 1297 print_descr(addr, nlen, 1298 usb_as_if_descr, usb_as_if_item); 1299 1300 break; 1301 case 0x02: 1302 mdb_printf("format_type Descriptor\n"); 1303 print_descr(addr, nlen, 1304 usb_as_format_descr, usb_as_format_item); 1305 1306 break; 1307 default: 1308 mdb_printf("Unknown AS sub-descriptor 0x%x\n", sub_type); 1309 prt_usb_buf(addr, nlen); 1310 1311 break; 1312 } 1313 1314 return (DCMD_OK); 1315 } 1316 1317 /* print video class specific control descriptor */ 1318 static int 1319 prt_usb_vc_desc(uintptr_t addr, uint_t nlen) 1320 { 1321 uchar_t sub_type; 1322 1323 if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 1324 1325 return (DCMD_ERR); 1326 } 1327 switch (sub_type) { 1328 case 0x01: 1329 mdb_printf("header Descriptor\n"); 1330 print_descr(addr, nlen, 1331 usb_vc_header_descr, usb_vc_header_item); 1332 1333 break; 1334 case 0x02: 1335 mdb_printf("input_terminal Descriptor\n"); 1336 print_descr(addr, nlen, 1337 usb_vc_input_term_descr, usb_vc_input_term_item); 1338 1339 break; 1340 case 0x03: 1341 mdb_printf("output_terminal Descriptor\n"); 1342 print_descr(addr, nlen, 1343 usb_vc_output_term_descr, usb_vc_output_term_item); 1344 1345 break; 1346 case 0x04: 1347 mdb_printf("selector_unit Descriptor\n"); 1348 print_descr(addr, nlen, 1349 usb_vc_selector_descr, usb_vc_selector_item); 1350 1351 break; 1352 case 0x05: 1353 mdb_printf("processing_unit Descriptor\n"); 1354 print_descr(addr, nlen, 1355 usb_vc_processing_descr, usb_vc_processing_item); 1356 1357 break; 1358 case 0x06: 1359 mdb_printf("extension_unit Descriptor\n"); 1360 print_descr(addr, nlen, 1361 usb_vc_extension_descr, usb_vc_extension_item); 1362 1363 break; 1364 default: 1365 mdb_printf("Unknown VC sub-descriptor 0x%x\n", sub_type); 1366 prt_usb_buf(addr, nlen); 1367 1368 break; 1369 } 1370 1371 return (DCMD_OK); 1372 } 1373 1374 /* print video class specific stream descriptor */ 1375 static int 1376 prt_usb_vs_desc(uintptr_t addr, uint_t nlen) 1377 { 1378 uchar_t sub_type; 1379 1380 if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 1381 1382 return (DCMD_ERR); 1383 } 1384 switch (sub_type) { 1385 case 0x01: 1386 mdb_printf("input_header Descriptor\n"); 1387 print_descr(addr, nlen, 1388 usb_vs_input_header_descr, usb_vs_input_header_item); 1389 1390 break; 1391 case 0x02: 1392 mdb_printf("output_header Descriptor\n"); 1393 print_descr(addr, nlen, 1394 usb_vs_output_header_descr, usb_vs_output_header_item); 1395 1396 break; 1397 case 0x03: 1398 mdb_printf("still_image_frame Descriptor\n"); 1399 print_descr(addr, nlen, 1400 usb_vs_still_image_descr, usb_vs_still_image_item); 1401 1402 break; 1403 case 0x04: 1404 mdb_printf("format_uncompressed Descriptor\n"); 1405 print_descr(addr, nlen, 1406 usb_vs_format_uncps_descr, usb_vs_format_uncps_item); 1407 1408 break; 1409 case 0x05: 1410 mdb_printf("frame_uncompressed Descriptor\n"); 1411 print_descr(addr, nlen, 1412 usb_vs_2frame_descr, usb_vs_2frame_item); 1413 1414 break; 1415 case 0x06: 1416 mdb_printf("format_mjpeg Descriptor\n"); 1417 print_descr(addr, nlen, 1418 usb_vs_format_mjpeg_descr, usb_vs_format_mjpeg_item); 1419 1420 break; 1421 case 0x07: 1422 mdb_printf("frame_mjpeg Descriptor\n"); 1423 print_descr(addr, nlen, 1424 usb_vs_2frame_descr, usb_vs_2frame_item); 1425 1426 break; 1427 case 0x0A: 1428 mdb_printf("format_mpeg2ts Descriptor\n"); 1429 print_descr(addr, nlen, 1430 usb_vs_format_mp2ts_descr, usb_vs_format_mp2ts_item); 1431 1432 break; 1433 case 0x0C: 1434 mdb_printf("format_dv Descriptor\n"); 1435 print_descr(addr, nlen, 1436 usb_vs_format_dv_descr, usb_vs_format_dv_item); 1437 1438 break; 1439 case 0x0D: 1440 mdb_printf("color_matching Descriptor\n"); 1441 print_descr(addr, nlen, 1442 usb_vs_color_matching_descr, usb_vs_color_matching_item); 1443 1444 break; 1445 default: 1446 mdb_printf("Unknown VS sub-descriptor 0x%x\n", sub_type); 1447 prt_usb_buf(addr, nlen); 1448 1449 break; 1450 } 1451 1452 return (DCMD_OK); 1453 } 1454 1455 /* parse and print the descriptor items */ 1456 static int 1457 print_descr(uintptr_t addr, uint_t nlen, usb_descr_item_t *item, uint_t nitem) 1458 { 1459 int i, j; 1460 uint8_t buf[8]; 1461 uint64_t value; 1462 uintptr_t paddr = addr; 1463 usb_descr_item_t *p = item; 1464 1465 mdb_printf("{"); 1466 for (i = 0; (i < nitem) && (paddr < addr + nlen); i++) { 1467 mdb_printf("\n %s =", p->name); 1468 switch (p->nlen) { 1469 case 1: /* uint8_t */ 1470 if (mdb_vread(buf, 1, paddr) == -1) { 1471 1472 return (DCMD_ERR); 1473 } 1474 value = buf[0]; 1475 1476 break; 1477 case 2: /* uint16_t */ 1478 if (mdb_vread(buf, 2, paddr) == -1) { 1479 1480 return (DCMD_ERR); 1481 } 1482 value = buf[0] | (buf[1] << 8); 1483 1484 break; 1485 case 4: /* uint32_t */ 1486 if (mdb_vread(buf, 4, paddr) == -1) { 1487 1488 return (DCMD_ERR); 1489 } 1490 value = buf[0] | (buf[1] << 8) | 1491 (buf[2] << 16) | (buf[3] << 24); 1492 1493 break; 1494 case 8: /* uint64_t */ 1495 if (mdb_vread(buf, 8, paddr) == -1) { 1496 1497 return (DCMD_ERR); 1498 } 1499 value = buf[4] | (buf[5] << 8) | 1500 (buf[6] << 16) | (buf[7] << 24); 1501 value = buf[0] | (buf[1] << 8) | 1502 (buf[2] << 16) | (buf[3] << 24) | 1503 (value << 32); 1504 1505 break; 1506 default: /* byte array */ 1507 value = 0; 1508 /* print an array instead of a value */ 1509 for (j = 0; j < p->nlen - BYTE_OFFSET; j++) { 1510 if (mdb_vread(buf, 1, paddr + j) == -1) { 1511 1512 break; 1513 } 1514 mdb_printf(" 0x%x", buf[0]); 1515 } 1516 1517 break; 1518 } 1519 1520 if (p->nlen > BYTE_OFFSET) { 1521 paddr += p->nlen - BYTE_OFFSET; 1522 } else { 1523 mdb_printf(" 0x%x", value); 1524 paddr += p->nlen; 1525 } 1526 1527 p++; 1528 } 1529 1530 /* print the unresolved bytes */ 1531 if (paddr < addr + nlen) { 1532 mdb_printf("\n ... ="); 1533 } 1534 while (paddr < addr + nlen) { 1535 if (mdb_vread(buf, 1, paddr++) == -1) { 1536 1537 break; 1538 } 1539 mdb_printf(" 0x%x", buf[0]); 1540 } 1541 mdb_printf("\n}\n"); 1542 1543 return (DCMD_OK); 1544 } 1545 1546 /* print the buffer as a struct */ 1547 static int 1548 print_struct(uintptr_t addr, uint_t nlen, mdb_arg_t *arg) 1549 { 1550 mdb_ctf_id_t id; 1551 if (mdb_ctf_lookup_by_name(arg->a_un.a_str, &id) == 0) { 1552 1553 mdb_call_dcmd("print", addr, DCMD_ADDRSPEC, 1, arg); 1554 } else { 1555 1556 prt_usb_buf(addr, nlen); 1557 } 1558 1559 return (DCMD_OK); 1560 } 1561 1562 /* print the buffer as a byte array */ 1563 static int 1564 prt_usb_buf(uintptr_t addr, uint_t nlen) 1565 { 1566 int i; 1567 uchar_t val; 1568 1569 mdb_printf("{\n"); 1570 for (i = 0; i < nlen; i++) { 1571 if (mdb_vread(&val, 1, addr + i) == -1) { 1572 1573 break; 1574 } 1575 mdb_printf("%02x ", val); 1576 } 1577 if (nlen) { 1578 mdb_printf("\n"); 1579 } 1580 mdb_printf("}\n"); 1581 1582 return (DCMD_OK); 1583 } 1584