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