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("%-8s : %s\n", "-v", "print all descriptors"); 519 mdb_printf("%-8s : %s\n", "-t", "print device trees"); 520 mdb_printf("%-8s : %s\n", "-i index", "print the device by index"); 521 } 522 523 /* the entry of ::prtusb */ 524 int 525 prtusb(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 526 { 527 static int count = 1; 528 uint64_t sel_num = 0; 529 uint_t usb_flag = 0; 530 usba_device_t usb_dev; 531 usb_dev_descr_t dev_desc; 532 struct dev_info usb_dip; 533 char strbuf[STRLEN]; 534 535 /* print all usba devices if no address assigned */ 536 if (!(flags & DCMD_ADDRSPEC)) { 537 if (mdb_walk_dcmd("usba_device", "prtusb", argc, argv) == -1) { 538 mdb_warn("failed to walk usba_device"); 539 540 return (DCMD_ERR); 541 } 542 543 return (DCMD_OK); 544 } 545 546 /* for the first device, print head */ 547 if (DCMD_HDRSPEC(flags)) { 548 count = 1; 549 mdb_printf("%<u>%-8s%-12s%-6s%-16s%-12s%-20s%</u>\n", 550 "INDEX", "DRIVER", "INST", "NODE", "VID.PID", "PRODUCT"); 551 } 552 553 if (mdb_getopts(argc, argv, 554 'i', MDB_OPT_UINT64, &sel_num, 555 't', MDB_OPT_SETBITS, OPT_TREE, &usb_flag, 556 'v', MDB_OPT_SETBITS, OPT_VERB, &usb_flag, NULL) != argc) { 557 558 return (DCMD_USAGE); 559 } 560 561 if (mdb_vread(&usb_dev, sizeof (usba_device_t), addr) == -1) { 562 mdb_warn("Failed to read usba_device!\n"); 563 564 return (DCMD_ERR); 565 } 566 567 if (mdb_vread(&usb_dip, sizeof (struct dev_info), 568 (uintptr_t)usb_dev.usb_dip) == -1) { 569 mdb_warn("Failed to read dev_info!\n"); 570 571 return (DCMD_ERR); 572 } 573 574 /* process the "-i" */ 575 if (sel_num && sel_num != count) { 576 count++; 577 578 return (DCMD_OK); 579 } 580 581 /* index number of device node */ 582 mdb_printf("%-8x", count++); 583 584 /* driver and instance */ 585 mdb_devinfo2driver((uintptr_t)usb_dev.usb_dip, strbuf, STRLEN); 586 mdb_printf("%-12s%-6d", strbuf, usb_dip.devi_instance); 587 588 /* node name */ 589 if (mdb_readstr(strbuf, STRLEN, 590 (uintptr_t)usb_dip.devi_node_name) != -1) { 591 592 mdb_printf("%-16s", strbuf); 593 } else { 594 595 mdb_printf("%-16s", "No Node Name"); 596 } 597 598 /* vid.pid */ 599 if (mdb_vread(&dev_desc, sizeof (usb_dev_descr_t), 600 (uintptr_t)usb_dev.usb_dev_descr) != -1) { 601 602 mdb_printf("%04x.%04x ", 603 dev_desc.idVendor, dev_desc.idProduct); 604 } 605 606 /* product string */ 607 if (mdb_readstr(strbuf, STRLEN, 608 (uintptr_t)usb_dev.usb_product_str) != -1) { 609 610 mdb_printf("%s\n", strbuf); 611 } else { 612 613 mdb_printf("%s\n", "No Product String"); 614 } 615 616 /* tree, print usb device tree info */ 617 if (usb_flag & OPT_TREE) { 618 619 mdb_printf("\nusba_device: 0x%x\n", addr); 620 621 mdb_printf("mfg_prod_sn: "); 622 if (mdb_readstr(strbuf, STRLEN, 623 (uintptr_t)usb_dev.usb_mfg_str) != -1) { 624 mdb_printf("%s - ", strbuf); 625 } else { 626 mdb_printf("NULL - "); 627 } 628 if (mdb_readstr(strbuf, STRLEN, 629 (uintptr_t)usb_dev.usb_product_str) != -1) { 630 mdb_printf("%s - ", strbuf); 631 } else { 632 mdb_printf("NULL -"); 633 } 634 if (mdb_readstr(strbuf, STRLEN, 635 (uintptr_t)usb_dev.usb_serialno_str) != -1) { 636 mdb_printf("%s", strbuf); 637 } else { 638 mdb_printf("NULL"); 639 } 640 641 mdb_printf("\n\n"); 642 prt_usb_tree((uintptr_t)usb_dev.usb_dip, 0); 643 } 644 645 /* verbose, print all descriptors */ 646 if (usb_flag & OPT_VERB) { 647 int i; 648 uintptr_t cfg_buf; 649 uint16_t cfg_len; 650 651 mdb_printf("\n"); 652 653 /* device descriptor */ 654 prt_usb_desc((uintptr_t)usb_dev.usb_dev_descr, 18); 655 656 /* config cloud descriptors */ 657 if (usb_dev.usb_n_cfgs == 1) { 658 mdb_inc_indent(4); 659 mdb_printf("-- Active Config Index 0\n"); 660 mdb_dec_indent(4); 661 prt_usb_desc((uintptr_t)usb_dev.usb_cfg, 662 usb_dev.usb_cfg_length); 663 } else { 664 /* multiple configs */ 665 for (i = 0; i < usb_dev.usb_n_cfgs; i++) { 666 667 if ((mdb_vread(&cfg_len, sizeof (uint16_t), 668 (uintptr_t)(usb_dev.usb_cfg_array_len + i)) 669 != -1) && 670 (mdb_vread(&cfg_buf, sizeof (uintptr_t), 671 (uintptr_t)(usb_dev.usb_cfg_array + i)) 672 != -1)) { 673 mdb_inc_indent(4); 674 if (cfg_buf == 675 (uintptr_t)usb_dev.usb_cfg) { 676 mdb_printf("-- Active Config" 677 " Index %x\n", i); 678 } else { 679 mdb_printf("-- Inactive Config" 680 " Index %x\n", i); 681 } 682 mdb_dec_indent(4); 683 684 prt_usb_desc(cfg_buf, cfg_len); 685 } 686 } 687 } 688 } 689 690 if (usb_flag) { 691 692 mdb_printf("%<u>%-72s%</u>\n", " "); 693 } 694 695 return (DCMD_OK); 696 } 697 698 /* print the info required by "-t" */ 699 static int 700 prt_usb_tree(uintptr_t paddr, uint_t flag) 701 { 702 struct dev_info usb_dip; 703 704 if (mdb_vread(&usb_dip, sizeof (struct dev_info), paddr) == -1) { 705 mdb_warn("prt_usb_tree: Failed to read dev_info!\n"); 706 707 return (DCMD_ERR); 708 } 709 710 prt_usb_tree_node(paddr); 711 712 if (usb_dip.devi_child) { 713 714 mdb_printf("{\n"); 715 mdb_inc_indent(4); 716 prt_usb_tree((uintptr_t)usb_dip.devi_child, 1); 717 mdb_dec_indent(4); 718 mdb_printf("}\n\n"); 719 } 720 721 if (usb_dip.devi_sibling && flag == 1) { 722 /* print the sibling if flag == 1 */ 723 724 prt_usb_tree((uintptr_t)usb_dip.devi_sibling, 1); 725 } 726 727 return (DCMD_OK); 728 } 729 730 static int 731 prt_usb_tree_node(uintptr_t paddr) 732 { 733 struct dev_info usb_dip; 734 uintptr_t statep; 735 uint_t errlevel; 736 char driver_name[STRLEN] = ""; 737 char strbuf[STRLEN] = ""; 738 739 if (mdb_vread(&usb_dip, sizeof (struct dev_info), paddr) == -1) { 740 mdb_warn("prt_usb_tree_node: Failed to read dev_info!\n"); 741 742 return (DCMD_ERR); 743 } 744 745 /* node name */ 746 if (mdb_readstr(strbuf, STRLEN, 747 (uintptr_t)usb_dip.devi_node_name) != -1) { 748 mdb_printf("%s, ", strbuf); 749 } else { 750 mdb_printf("%s, ", "node_name"); 751 } 752 753 /* instance */ 754 mdb_printf("instance #%d ", usb_dip.devi_instance); 755 756 /* driver name */ 757 if (DDI_CF2(&usb_dip)) { 758 759 mdb_devinfo2driver(paddr, driver_name, STRLEN); 760 mdb_printf("(driver name: %s)\n", driver_name); 761 } else { 762 763 mdb_printf("(driver not attached)\n"); 764 } 765 766 /* device path */ 767 mdb_ddi_pathname(paddr, strbuf, STRLEN); 768 mdb_printf(" %s\n", strbuf); 769 770 /* dip addr */ 771 mdb_printf(" dip: 0x%x\n", paddr); 772 773 /* softe_sate */ 774 mdb_snprintf(strbuf, STRLEN, "%s_statep", driver_name); 775 if (mdb_devinfo2statep(paddr, strbuf, &statep) != -1) { 776 mdb_printf(" %s: 0x%x\n", strbuf, statep); 777 } 778 779 /* error level */ 780 mdb_snprintf(strbuf, STRLEN, "%s_errlevel", driver_name); 781 if (mdb_readvar(&errlevel, strbuf) != -1) { 782 mdb_printf(" %s: 0x%x\n", strbuf, errlevel); 783 } 784 785 if (strcmp(driver_name, "ehci") == 0) { 786 mdb_arg_t argv[] = { 787 {MDB_TYPE_STRING, {"ehci_state_t"}}, 788 {MDB_TYPE_STRING, {"ehci_root_hub.rh_descr"}} 789 }; 790 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 791 } 792 793 if (strcmp(driver_name, "ohci") == 0) { 794 mdb_arg_t argv[] = { 795 {MDB_TYPE_STRING, {"ohci_state_t"}}, 796 {MDB_TYPE_STRING, {"ohci_root_hub.rh_descr"}} 797 }; 798 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 799 } 800 801 if (strcmp(driver_name, "uhci") == 0) { 802 mdb_arg_t argv[] = { 803 {MDB_TYPE_STRING, {"uhci_state_t"}}, 804 {MDB_TYPE_STRING, {"uhci_root_hub.rh_descr"}} 805 }; 806 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 807 } 808 809 if (strcmp(driver_name, "hubd") == 0) { 810 mdb_arg_t argv[] = { 811 {MDB_TYPE_STRING, {"hubd_t"}}, 812 {MDB_TYPE_STRING, {"h_hub_descr"}} 813 }; 814 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 815 } 816 817 if (strcmp(driver_name, "hid") == 0) { 818 hid_state_t hidp; 819 820 if (mdb_vread(&hidp, sizeof (hid_state_t), statep) != -1) { 821 hidparser_handle hid_report; 822 823 if (mdb_vread(&hid_report, sizeof (hidparser_handle), 824 (uintptr_t)hidp.hid_report_descr) != -1) { 825 826 mdb_inc_indent(2); 827 828 mdb_printf("\n"); 829 prt_usb_hid_item((uintptr_t) 830 hid_report.hidparser_handle_parse_tree); 831 832 mdb_dec_indent(2); 833 } 834 } 835 } 836 837 mdb_printf("\n"); 838 839 return (DCMD_OK); 840 } 841 842 /* print hid report descriptor */ 843 static void 844 prt_usb_hid_item(uintptr_t paddr) 845 { 846 entity_item_t item; 847 if (mdb_vread(&item, sizeof (entity_item_t), paddr) != -1) { 848 849 prt_usb_hid_item_attrs((uintptr_t)item.entity_item_attributes); 850 prt_usb_hid_item_params(&item); 851 852 if (item.info.child) { 853 mdb_inc_indent(4); 854 prt_usb_hid_item((uintptr_t)item.info.child); 855 mdb_dec_indent(4); 856 } 857 858 if (item.entity_item_right_sibling) { 859 prt_usb_hid_item((uintptr_t) 860 item.entity_item_right_sibling); 861 } 862 } 863 } 864 865 static void 866 prt_usb_hid_item_params(entity_item_t *item) 867 { 868 switch (item->entity_item_type) { 869 case 0x80: 870 mdb_printf("INPUT "); 871 872 break; 873 case 0x90: 874 mdb_printf("OUTPUT "); 875 876 break; 877 case 0xA0: 878 mdb_printf("COLLECTION "); 879 880 break; 881 case 0xB0: 882 mdb_printf("FEATURE "); 883 884 break; 885 case 0xC0: 886 mdb_printf("END_COLLECTION "); 887 888 break; 889 default: 890 mdb_printf("MAIN_ITEM "); 891 892 break; 893 } 894 895 prt_usb_hid_item_data((uintptr_t)item->entity_item_params, 896 item->entity_item_params_leng); 897 898 mdb_printf("\n"); 899 } 900 901 static void 902 prt_usb_hid_item_attrs(uintptr_t paddr) 903 { 904 entity_attribute_t attr; 905 906 if (mdb_vread(&attr, sizeof (entity_attribute_t), paddr) != -1) { 907 908 prt_usb_hid_item_tags(attr.entity_attribute_tag); 909 prt_usb_hid_item_data((uintptr_t)attr.entity_attribute_value, 910 attr.entity_attribute_length); 911 912 mdb_printf("\n"); 913 914 if (attr.entity_attribute_next) { 915 prt_usb_hid_item_attrs((uintptr_t) 916 attr.entity_attribute_next); 917 } 918 } 919 } 920 921 static void 922 prt_usb_hid_item_data(uintptr_t paddr, uint_t len) 923 { 924 char data[4]; 925 int i; 926 927 if (len > 4) { 928 mdb_warn("Incorrect entity_item_length: 0x%x\n", len); 929 930 return; 931 } 932 933 if (mdb_vread(data, len, paddr) != -1) { 934 935 mdb_printf("( "); 936 for (i = 0; i < len; i++) { 937 mdb_printf("0x%02x ", data[i] & 0xff); 938 } 939 mdb_printf(")"); 940 } 941 } 942 943 static void 944 prt_usb_hid_item_tags(uint_t tag) 945 { 946 switch (tag) { 947 case 0x04: 948 mdb_printf("usage page "); 949 950 break; 951 case 0x14: 952 mdb_printf("logical minimum "); 953 954 break; 955 case 0x24: 956 mdb_printf("logical maximum "); 957 958 break; 959 case 0x34: 960 mdb_printf("physical minimum "); 961 962 break; 963 case 0x44: 964 mdb_printf("physical maximum "); 965 966 break; 967 case 0x54: 968 mdb_printf("exponent "); 969 970 break; 971 case 0x64: 972 mdb_printf("unit "); 973 974 break; 975 case 0x74: 976 mdb_printf("report size "); 977 978 break; 979 case 0x84: 980 mdb_printf("report id "); 981 982 break; 983 case 0x94: 984 mdb_printf("report count "); 985 986 break; 987 case 0x08: 988 mdb_printf("usage "); 989 990 break; 991 case 0x18: 992 mdb_printf("usage min "); 993 994 break; 995 case 0x28: 996 mdb_printf("usage max "); 997 998 break; 999 1000 default: 1001 mdb_printf("tag "); 1002 } 1003 } 1004 1005 /* print the info required by "-v" */ 1006 static int 1007 prt_usb_desc(uintptr_t usb_cfg, uint_t cfg_len) 1008 { 1009 uintptr_t paddr = usb_cfg; 1010 uintptr_t pend = usb_cfg + cfg_len; 1011 uchar_t desc_type, nlen; 1012 usb_if_descr_t usb_if; 1013 ulong_t indent = 0; 1014 1015 mdb_arg_t argv = {MDB_TYPE_STRING, {"usb_dev_descr_t"}}; 1016 1017 if (mdb_vread(&nlen, 1, paddr) == -1) { 1018 1019 return (DCMD_ERR); 1020 } 1021 while ((paddr + nlen <= pend) && (nlen > 0)) { 1022 if (mdb_vread(&desc_type, 1, paddr + 1) == -1) { 1023 1024 return (DCMD_ERR); 1025 } 1026 1027 switch (desc_type) { 1028 case USB_DESCR_TYPE_DEV: 1029 mdb_printf("Device Descriptor\n"); 1030 print_struct(paddr, nlen, &argv); 1031 1032 break; 1033 case USB_DESCR_TYPE_CFG: 1034 indent = 4; 1035 mdb_inc_indent(indent); 1036 mdb_printf("Configuration Descriptor\n"); 1037 print_descr(paddr, nlen, usb_cfg_descr, usb_cfg_item); 1038 mdb_dec_indent(indent); 1039 1040 break; 1041 case USB_DESCR_TYPE_STRING: 1042 mdb_printf("String Descriptor\n"); 1043 print_descr(paddr, nlen, usb_str_descr, usb_str_item); 1044 1045 break; 1046 case USB_DESCR_TYPE_IF: 1047 indent = 8; 1048 mdb_inc_indent(indent); 1049 mdb_printf("Interface Descriptor\n"); 1050 print_descr(paddr, nlen, usb_if_descr, usb_if_item); 1051 mdb_dec_indent(indent); 1052 mdb_vread(&usb_if, sizeof (usb_if_descr_t), paddr); 1053 1054 break; 1055 case USB_DESCR_TYPE_EP: 1056 indent = 8; 1057 mdb_inc_indent(indent); 1058 mdb_printf("Endpoint Descriptor\n"); 1059 print_descr(paddr, nlen, usb_ep_descr, usb_ep_item); 1060 mdb_dec_indent(indent); 1061 1062 break; 1063 case USB_DESCR_TYPE_DEV_QLF: 1064 mdb_printf("Device_Qualifier Descriptor\n"); 1065 print_descr(paddr, nlen, usb_qlf_descr, usb_qlf_item); 1066 1067 break; 1068 case USB_DESCR_TYPE_OTHER_SPEED_CFG: 1069 indent = 4; 1070 mdb_inc_indent(indent); 1071 mdb_printf("Other_Speed_Configuration Descriptor\n"); 1072 print_descr(paddr, nlen, usb_cfg_descr, usb_cfg_item); 1073 mdb_dec_indent(indent); 1074 1075 break; 1076 case USB_DESCR_TYPE_IA: 1077 indent = 6; 1078 mdb_inc_indent(indent); 1079 mdb_printf("Interface_Association Descriptor\n"); 1080 print_descr(paddr, nlen, usb_ia_descr, usb_ia_item); 1081 mdb_dec_indent(indent); 1082 1083 break; 1084 case 0x21: /* hid descriptor */ 1085 indent = 12; 1086 mdb_inc_indent(indent); 1087 mdb_printf("HID Descriptor\n"); 1088 print_descr(paddr, nlen, usb_hid_descr, usb_hid_item); 1089 mdb_dec_indent(indent); 1090 1091 break; 1092 case 0x24: /* class specific interfce descriptor */ 1093 indent = 12; 1094 mdb_inc_indent(indent); 1095 if (usb_if.bInterfaceClass == 1 && 1096 usb_if.bInterfaceSubClass == 1) { 1097 mdb_printf("AudioControl_Interface: "); 1098 prt_usb_ac_desc(paddr, nlen); 1099 1100 } else if (usb_if.bInterfaceClass == 1 && 1101 usb_if.bInterfaceSubClass == 2) { 1102 mdb_printf("AudioStream_Interface: "); 1103 prt_usb_as_desc(paddr, nlen); 1104 1105 } else if (usb_if.bInterfaceClass == 0x0E && 1106 usb_if.bInterfaceSubClass == 1) { 1107 mdb_printf("VideoControl_Interface: "); 1108 prt_usb_vc_desc(paddr, nlen); 1109 1110 1111 } else if (usb_if.bInterfaceClass == 0x0E && 1112 usb_if.bInterfaceSubClass == 2) { 1113 mdb_printf("VideoStream_Interface: "); 1114 prt_usb_vs_desc(paddr, nlen); 1115 1116 } else { 1117 mdb_printf("Unknown_Interface:" 1118 "0x%x\n", desc_type); 1119 prt_usb_buf(paddr, nlen); 1120 } 1121 mdb_dec_indent(indent); 1122 1123 break; 1124 case 0x25: /* class specific endpoint descriptor */ 1125 indent = 12; 1126 mdb_inc_indent(indent); 1127 if (usb_if.bInterfaceClass == 0x01) { 1128 mdb_printf("AudioEndpoint:\n"); 1129 print_descr(paddr, nlen, 1130 usb_as_ep_descr, usb_as_ep_item); 1131 1132 } else if (usb_if.bInterfaceClass == 0x0E) { 1133 mdb_printf("VideoEndpoint:\n"); 1134 print_descr(paddr, nlen, 1135 usb_ep_descr, usb_ep_item); 1136 1137 } else { 1138 mdb_printf("Unknown_Endpoint:" 1139 "0x%x\n", desc_type); 1140 prt_usb_buf(paddr, nlen); 1141 } 1142 mdb_dec_indent(indent); 1143 1144 break; 1145 default: 1146 mdb_inc_indent(indent); 1147 mdb_printf("Unknown Descriptor: 0x%x\n", desc_type); 1148 prt_usb_buf(paddr, nlen); 1149 mdb_dec_indent(indent); 1150 1151 break; 1152 } 1153 1154 paddr += nlen; 1155 if (mdb_vread(&nlen, 1, paddr) == -1) { 1156 1157 return (DCMD_ERR); 1158 } 1159 }; 1160 1161 return (DCMD_OK); 1162 } 1163 1164 1165 /* print audio class specific control descriptor */ 1166 static int 1167 prt_usb_ac_desc(uintptr_t addr, uint_t nlen) 1168 { 1169 uchar_t sub_type; 1170 1171 if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 1172 1173 return (DCMD_ERR); 1174 } 1175 switch (sub_type) { 1176 case 0x01: 1177 mdb_printf("header Descriptor\n"); 1178 print_descr(addr, nlen, 1179 usb_ac_header_descr, usb_ac_header_item); 1180 1181 break; 1182 case 0x02: 1183 mdb_printf("input_terminal Descriptor\n"); 1184 print_descr(addr, nlen, 1185 usb_ac_input_term_descr, usb_ac_input_term_item); 1186 1187 break; 1188 case 0x03: 1189 mdb_printf("output_terminal Descriptor\n"); 1190 print_descr(addr, nlen, 1191 usb_ac_output_term_descr, usb_ac_output_term_item); 1192 1193 break; 1194 case 0x04: 1195 mdb_printf("mixer_unit Descriptor\n"); 1196 print_descr(addr, nlen, 1197 usb_ac_mixer_descr, usb_ac_mixer_item); 1198 1199 break; 1200 case 0x05: 1201 mdb_printf("selector_unit Descriptor\n"); 1202 print_descr(addr, nlen, 1203 usb_ac_selector_descr, usb_ac_selector_item); 1204 1205 break; 1206 case 0x06: 1207 mdb_printf("feature_unit Descriptor\n"); 1208 print_descr(addr, nlen, 1209 usb_ac_feature_descr, usb_ac_feature_item); 1210 1211 break; 1212 case 0x07: 1213 mdb_printf("processing_unit Descriptor\n"); 1214 print_descr(addr, nlen, 1215 usb_ac_processing_descr, usb_ac_processing_item); 1216 1217 break; 1218 case 0x08: 1219 mdb_printf("extension_unit Descriptor\n"); 1220 print_descr(addr, nlen, 1221 usb_ac_extension_descr, usb_ac_extension_item); 1222 1223 break; 1224 default: 1225 mdb_printf("Unknown AC sub-descriptor 0x%x\n", sub_type); 1226 prt_usb_buf(addr, nlen); 1227 1228 break; 1229 } 1230 1231 return (DCMD_OK); 1232 } 1233 1234 /* print audio class specific stream descriptor */ 1235 static int 1236 prt_usb_as_desc(uintptr_t addr, uint_t nlen) 1237 { 1238 uchar_t sub_type; 1239 1240 if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 1241 1242 return (DCMD_ERR); 1243 } 1244 switch (sub_type) { 1245 case 0x01: 1246 mdb_printf("general_interface Descriptor\n"); 1247 print_descr(addr, nlen, 1248 usb_as_if_descr, usb_as_if_item); 1249 1250 break; 1251 case 0x02: 1252 mdb_printf("format_type Descriptor\n"); 1253 print_descr(addr, nlen, 1254 usb_as_format_descr, usb_as_format_item); 1255 1256 break; 1257 default: 1258 mdb_printf("Unknown AS sub-descriptor 0x%x\n", sub_type); 1259 prt_usb_buf(addr, nlen); 1260 1261 break; 1262 } 1263 1264 return (DCMD_OK); 1265 } 1266 1267 /* print video class specific control descriptor */ 1268 static int 1269 prt_usb_vc_desc(uintptr_t addr, uint_t nlen) 1270 { 1271 uchar_t sub_type; 1272 1273 if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 1274 1275 return (DCMD_ERR); 1276 } 1277 switch (sub_type) { 1278 case 0x01: 1279 mdb_printf("header Descriptor\n"); 1280 print_descr(addr, nlen, 1281 usb_vc_header_descr, usb_vc_header_item); 1282 1283 break; 1284 case 0x02: 1285 mdb_printf("input_terminal Descriptor\n"); 1286 print_descr(addr, nlen, 1287 usb_vc_input_term_descr, usb_vc_input_term_item); 1288 1289 break; 1290 case 0x03: 1291 mdb_printf("output_terminal Descriptor\n"); 1292 print_descr(addr, nlen, 1293 usb_vc_output_term_descr, usb_vc_output_term_item); 1294 1295 break; 1296 case 0x04: 1297 mdb_printf("selector_unit Descriptor\n"); 1298 print_descr(addr, nlen, 1299 usb_vc_selector_descr, usb_vc_selector_item); 1300 1301 break; 1302 case 0x05: 1303 mdb_printf("processing_unit Descriptor\n"); 1304 print_descr(addr, nlen, 1305 usb_vc_processing_descr, usb_vc_processing_item); 1306 1307 break; 1308 case 0x06: 1309 mdb_printf("extension_unit Descriptor\n"); 1310 print_descr(addr, nlen, 1311 usb_vc_extension_descr, usb_vc_extension_item); 1312 1313 break; 1314 default: 1315 mdb_printf("Unknown VC sub-descriptor 0x%x\n", sub_type); 1316 prt_usb_buf(addr, nlen); 1317 1318 break; 1319 } 1320 1321 return (DCMD_OK); 1322 } 1323 1324 /* print video class specific stream descriptor */ 1325 static int 1326 prt_usb_vs_desc(uintptr_t addr, uint_t nlen) 1327 { 1328 uchar_t sub_type; 1329 1330 if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 1331 1332 return (DCMD_ERR); 1333 } 1334 switch (sub_type) { 1335 case 0x01: 1336 mdb_printf("input_header Descriptor\n"); 1337 print_descr(addr, nlen, 1338 usb_vs_input_header_descr, usb_vs_input_header_item); 1339 1340 break; 1341 case 0x02: 1342 mdb_printf("output_header Descriptor\n"); 1343 print_descr(addr, nlen, 1344 usb_vs_output_header_descr, usb_vs_output_header_item); 1345 1346 break; 1347 case 0x03: 1348 mdb_printf("still_image_frame Descriptor\n"); 1349 print_descr(addr, nlen, 1350 usb_vs_still_image_descr, usb_vs_still_image_item); 1351 1352 break; 1353 case 0x04: 1354 mdb_printf("format_uncompressed Descriptor\n"); 1355 print_descr(addr, nlen, 1356 usb_vs_format_uncps_descr, usb_vs_format_uncps_item); 1357 1358 break; 1359 case 0x05: 1360 mdb_printf("frame_uncompressed Descriptor\n"); 1361 print_descr(addr, nlen, 1362 usb_vs_2frame_descr, usb_vs_2frame_item); 1363 1364 break; 1365 case 0x06: 1366 mdb_printf("format_mjpeg Descriptor\n"); 1367 print_descr(addr, nlen, 1368 usb_vs_format_mjpeg_descr, usb_vs_format_mjpeg_item); 1369 1370 break; 1371 case 0x07: 1372 mdb_printf("frame_mjpeg Descriptor\n"); 1373 print_descr(addr, nlen, 1374 usb_vs_2frame_descr, usb_vs_2frame_item); 1375 1376 break; 1377 case 0x0A: 1378 mdb_printf("format_mpeg2ts Descriptor\n"); 1379 print_descr(addr, nlen, 1380 usb_vs_format_mp2ts_descr, usb_vs_format_mp2ts_item); 1381 1382 break; 1383 case 0x0C: 1384 mdb_printf("format_dv Descriptor\n"); 1385 print_descr(addr, nlen, 1386 usb_vs_format_dv_descr, usb_vs_format_dv_item); 1387 1388 break; 1389 case 0x0D: 1390 mdb_printf("color_matching Descriptor\n"); 1391 print_descr(addr, nlen, 1392 usb_vs_color_matching_descr, usb_vs_color_matching_item); 1393 1394 break; 1395 default: 1396 mdb_printf("Unknown VS sub-descriptor 0x%x\n", sub_type); 1397 prt_usb_buf(addr, nlen); 1398 1399 break; 1400 } 1401 1402 return (DCMD_OK); 1403 } 1404 1405 /* parse and print the descriptor items */ 1406 static int 1407 print_descr(uintptr_t addr, uint_t nlen, usb_descr_item_t *item, uint_t nitem) 1408 { 1409 int i, j; 1410 uint8_t buf[8]; 1411 uint64_t value; 1412 uintptr_t paddr = addr; 1413 usb_descr_item_t *p = item; 1414 1415 mdb_printf("{"); 1416 for (i = 0; (i < nitem) && (paddr < addr + nlen); i++) { 1417 mdb_printf("\n %s =", p->name); 1418 switch (p->nlen) { 1419 case 1: /* uint8_t */ 1420 if (mdb_vread(buf, 1, paddr) == -1) { 1421 1422 return (DCMD_ERR); 1423 } 1424 value = buf[0]; 1425 1426 break; 1427 case 2: /* uint16_t */ 1428 if (mdb_vread(buf, 2, paddr) == -1) { 1429 1430 return (DCMD_ERR); 1431 } 1432 value = buf[0] | (buf[1] << 8); 1433 1434 break; 1435 case 4: /* uint32_t */ 1436 if (mdb_vread(buf, 4, paddr) == -1) { 1437 1438 return (DCMD_ERR); 1439 } 1440 value = buf[0] | (buf[1] << 8) | 1441 (buf[2] << 16) | (buf[3] << 24); 1442 1443 break; 1444 case 8: /* uint64_t */ 1445 if (mdb_vread(buf, 8, paddr) == -1) { 1446 1447 return (DCMD_ERR); 1448 } 1449 value = buf[4] | (buf[5] << 8) | 1450 (buf[6] << 16) | (buf[7] << 24); 1451 value = buf[0] | (buf[1] << 8) | 1452 (buf[2] << 16) | (buf[3] << 24) | 1453 (value << 32); 1454 1455 break; 1456 default: /* byte array */ 1457 value = 0; 1458 /* print an array instead of a value */ 1459 for (j = 0; j < p->nlen - BYTE_OFFSET; j++) { 1460 if (mdb_vread(buf, 1, paddr + j) == -1) { 1461 1462 break; 1463 } 1464 mdb_printf(" 0x%x", buf[0]); 1465 } 1466 1467 break; 1468 } 1469 1470 if (p->nlen > BYTE_OFFSET) { 1471 paddr += p->nlen - BYTE_OFFSET; 1472 } else { 1473 mdb_printf(" 0x%x", value); 1474 paddr += p->nlen; 1475 } 1476 1477 p++; 1478 } 1479 1480 /* print the unresolved bytes */ 1481 if (paddr < addr + nlen) { 1482 mdb_printf("\n ... ="); 1483 } 1484 while (paddr < addr + nlen) { 1485 if (mdb_vread(buf, 1, paddr++) == -1) { 1486 1487 break; 1488 } 1489 mdb_printf(" 0x%x", buf[0]); 1490 } 1491 mdb_printf("\n}\n"); 1492 1493 return (DCMD_OK); 1494 } 1495 1496 /* print the buffer as a struct */ 1497 static int 1498 print_struct(uintptr_t addr, uint_t nlen, mdb_arg_t *arg) 1499 { 1500 mdb_ctf_id_t id; 1501 if (mdb_ctf_lookup_by_name(arg->a_un.a_str, &id) == 0) { 1502 1503 mdb_call_dcmd("print", addr, DCMD_ADDRSPEC, 1, arg); 1504 } else { 1505 1506 prt_usb_buf(addr, nlen); 1507 } 1508 1509 return (DCMD_OK); 1510 } 1511 1512 /* print the buffer as a byte array */ 1513 static int 1514 prt_usb_buf(uintptr_t addr, uint_t nlen) 1515 { 1516 int i; 1517 uchar_t val; 1518 1519 mdb_printf("{\n"); 1520 for (i = 0; i < nlen; i++) { 1521 if (mdb_vread(&val, 1, addr + i) == -1) { 1522 1523 break; 1524 } 1525 mdb_printf("%02x ", val); 1526 } 1527 if (nlen) { 1528 mdb_printf("\n"); 1529 } 1530 mdb_printf("}\n"); 1531 1532 return (DCMD_OK); 1533 } 1534