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