Print this page
Merge fixes for Illumos issue 4819, fix mpt_sas command timeout handling.
Add rolling buffer for *all* debug messages.
Improve mdb module and seperate out into mpt_sas3.


 133                         mdb_printf(" online");
 134                         break;
 135                 case MDI_PATHINFO_STATE_STANDBY:
 136                         mdb_printf(" standby");
 137                         break;
 138                 case MDI_PATHINFO_STATE_FAULT:
 139                         mdb_printf(" fault");
 140                         break;
 141                 case MDI_PATHINFO_STATE_OFFLINE:
 142                         mdb_printf(" offline");
 143                         break;
 144                 default:
 145                         mdb_printf(" invalid state");
 146                         break;
 147         }
 148         mdb_printf("\n");
 149         return (0);
 150 }
 151 
 152 void
 153 mdi_info(struct mptsas m, int target)
 154 {
 155         struct  dev_info        d;
 156         struct  mdi_phci        p;
 157 
 158         if (mdb_vread(&d, sizeof (d), (uintptr_t)m.m_dip) == -1) {
 159                 mdb_warn("couldn't read m_dip");
 160                 return;
 161         }
 162 
 163         if (MDI_PHCI(&d)) {
 164                 if (mdb_vread(&p, sizeof (p), (uintptr_t)d.devi_mdi_xhci)
 165                     == -1) {
 166                         mdb_warn("couldn't read m_dip.devi_mdi_xhci");
 167                         return;
 168                 }
 169                 if (p.ph_path_head)
 170                         mdb_pwalk("mdipi_phci_list", (mdb_walk_cb_t)mdi_info_cb,
 171                             &target, (uintptr_t)p.ph_path_head);
 172                 return;
 173         }
 174 }
 175 
 176 void
 177 print_cdb(mptsas_cmd_t *m)
 178 {


 284             khp + offsetof(refhash_t, rh_objs), &ml)) != NULL) {
 285                 mdb_vread(&ml, sizeof (ml), klp);
 286                 if (!(ml.rhl_flags & RHL_F_DEAD))
 287                         break;
 288         }
 289 
 290         if (klp == 0) {
 291                 mdb_free(prev, mh.rh_obj_size);
 292                 return (NULL);
 293         }
 294 
 295         kop = klp - mh.rh_link_off;
 296         rp = mdb_alloc(mh.rh_obj_size, UM_SLEEP);
 297         mdb_vread(rp, mh.rh_obj_size, kop);
 298 
 299         mdb_free(prev, mh.rh_obj_size);
 300         return (rp);
 301 }
 302 
 303 void
 304 display_targets(struct mptsas *mp)
 305 {
 306         mptsas_target_t *ptgt;
 307         mptsas_smp_t *psmp;

 308 
 309         mdb_printf("\n");
 310         mdb_printf("The SCSI target information\n");
 311         for (ptgt = (mptsas_target_t *)krefhash_first((uintptr_t)mp->m_targets);
 312             ptgt != NULL;
 313             ptgt = krefhash_next((uintptr_t)mp->m_targets, ptgt)) {
 314                 mdb_printf("\n");
 315                 mdb_printf("devhdl %x, sasaddress %"PRIx64", phymask %x,"
 316                     "devinfo %x\n", ptgt->m_devhdl, ptgt->m_addr.mta_wwn,
 317                     ptgt->m_addr.mta_phymask, ptgt->m_deviceinfo);
 318                 mdb_printf("throttle %x, dr_flag %x, m_t_ncmds %x, "
 319                     "enclosure %x, slot_num %x\n", ptgt->m_t_throttle,
 320                     ptgt->m_dr_flag, ptgt->m_t_ncmds, ptgt->m_enclosure,
 321                     ptgt->m_slot_num);
 322         }
 323 
 324         mdb_printf("\n");
 325         mdb_printf("The smp child information\n");
 326         for (psmp = (mptsas_smp_t *)krefhash_first(
 327             (uintptr_t)mp->m_smp_targets);
 328             psmp != NULL;
 329             psmp = krefhash_next((uintptr_t)mp->m_smp_targets, psmp)) {
 330                 mdb_printf("\n");
 331                 mdb_printf("devhdl %x, sasaddress %"PRIx64", phymask %x \n",
 332                     psmp->m_devhdl, psmp->m_addr.mta_wwn,
 333                     psmp->m_addr.mta_phymask);
 334         }
 335         mdb_printf("\n");
 336 #if 0
 337         mdb_printf("targ         wwn      ncmds throttle "
 338             "dr_flag  timeout  dups\n");
 339         mdb_printf("-------------------------------"
 340             "--------------------------------\n");
 341         for (i = 0; i < MPTSAS_MAX_TARGETS; i++) {
 342                 if (s->m_target[i].m_addr.mta_wwn ||
 343                     s->m_target[i].m_deviceinfo) {
 344                         mdb_printf("%4d ", i);
 345                         if (s->m_target[i].m_addr.mta_wwn)




 346                                 mdb_printf("%"PRIx64" ",
 347                                     s->m_target[i].m_addr.mta_wwn);
 348                         mdb_printf("%3d", s->m_target[i].m_t_ncmds);
 349                         switch (s->m_target[i].m_t_throttle) {
 350                                 case QFULL_THROTTLE:
 351                                         mdb_printf("   QFULL ");
 352                                         break;
 353                                 case DRAIN_THROTTLE:
 354                                         mdb_printf("   DRAIN ");
 355                                         break;
 356                                 case HOLD_THROTTLE:
 357                                         mdb_printf("    HOLD ");
 358                                         break;
 359                                 case MAX_THROTTLE:
 360                                         mdb_printf("     MAX ");
 361                                         break;
 362                                 case CHOKE_THROTTLE:
 363                                         mdb_printf("   CHOKE ");
 364                                         break;
 365                                 default:
 366                                         mdb_printf("%8d ",
 367                                             s->m_target[i].m_t_throttle);
 368                         }
 369                         switch (s->m_target[i].m_dr_flag) {
 370                                 case MPTSAS_DR_INACTIVE:
 371                                         mdb_printf("  INACTIVE ");
 372                                         break;
 373                                 case MPTSAS_DR_PRE_OFFLINE_TIMEOUT:
 374                                         mdb_printf("   TIMEOUT ");
 375                                         break;
 376                                 case MPTSAS_DR_PRE_OFFLINE_TIMEOUT_NO_CANCEL:
 377                                         mdb_printf("TIMEOUT_NC ");
 378                                         break;
 379                                 case MPTSAS_DR_OFFLINE_IN_PROGRESS:
 380                                         mdb_printf(" OFFLINING ");
 381                                         break;
 382                                 case MPTSAS_DR_ONLINE_IN_PROGRESS:
 383                                         mdb_printf("  ONLINING ");
 384                                         break;
 385                                 default:
 386                                         mdb_printf("   UNKNOWN ");
 387                                         break;
 388                                 }
 389                         mdb_printf("%3d/%-3d   %d/%d\n",
 390                             s->m_target[i].m_dr_timeout, m.m_offline_delay,
 391                             s->m_target[i].m_dr_online_dups,
 392                             s->m_target[i].m_dr_offline_dups);
 393 
 394                         if (verbose) {
 395                                 mdb_inc_indent(5);
 396                                 if ((s->m_target[i].m_deviceinfo &
 397                                     MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
 398                                     MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
 399                                         mdb_printf("Fanout expander: ");
 400                                 if ((s->m_target[i].m_deviceinfo &
 401                                     MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
 402                                     MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER)
 403                                         mdb_printf("Edge expander: ");
 404                                 if ((s->m_target[i].m_deviceinfo &
 405                                     MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
 406                                     MPI2_SAS_DEVICE_INFO_END_DEVICE)
 407                                         mdb_printf("End device: ");
 408                                 if ((s->m_target[i].m_deviceinfo &
 409                                     MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
 410                                     MPI2_SAS_DEVICE_INFO_NO_DEVICE)
 411                                         mdb_printf("No device ");
 412 
 413                                 for (loop = 0, comma = 0;
 414                                     loop < (sizeof (devinfo_array) /
 415                                     sizeof (devinfo_array[0])); loop++) {
 416                                         if (s->m_target[i].m_deviceinfo &
 417                                             devinfo_array[loop].value) {
 418                                                 mdb_printf("%s%s",
 419                                                     (comma ? ", " : ""),
 420                                                     devinfo_array[loop].text);
 421                                                 comma++;
 422                                         }
 423                                 }
 424                                 mdb_printf("\n");
 425 
 426                                 if (s->m_target[i].m_tgt_dip) {

 427                                         *target_path = 0;
 428                                         if (construct_path((uintptr_t)
 429                                             s->m_target[i].m_tgt_dip,
 430                                             target_path)
 431                                             == DCMD_OK)
 432                                                 mdb_printf("%s\n", target_path);
 433                                 }
 434                                 mdi_info(m, i);

 435                                 mdb_dec_indent(5);
 436                         }
 437                 }
 438         }
 439 #endif











 440 }
 441 
 442 int
 443 display_slotinfo()
 444 {
 445 #if 0
 446         int     i, nslots;
 447         struct  mptsas_cmd              c, *q, *slots;

 448         int     header_output = 0;
 449         int     rv = DCMD_OK;
 450         int     slots_in_use = 0;
 451         int     tcmds = 0;
 452         int     mismatch = 0;
 453         int     wq, dq;
 454         int     ncmds = 0;
 455         ulong_t saved_indent;
 456 
 457         nslots = s->m_n_normal;
 458 
 459         slots = mdb_alloc(sizeof (mptsas_cmd_t) * nslots, UM_SLEEP);
 460 
 461         for (i = 0; i < nslots; i++)
 462                 if (s->m_slot[i]) {
 463                         slots_in_use++;
 464                         if (mdb_vread(&slots[i], sizeof (mptsas_cmd_t),
 465                             (uintptr_t)s->m_slot[i]) == -1) {
 466                                 mdb_warn("couldn't read slot");
 467                                 s->m_slot[i] = NULL;
 468                         }
 469                         if ((slots[i].cmd_flags & CFLAG_CMDIOC) == 0)
 470                                 tcmds++;
 471                         if (i != slots[i].cmd_slot)
 472                                 mismatch++;
 473                 }
 474 
 475         for (q = m.m_waitq, wq = 0; q; q = c.cmd_linkp, wq++)
 476                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
 477                         mdb_warn("couldn't follow m_waitq");
 478                         rv = DCMD_ERR;
 479                         goto exit;
 480                 }
 481 
 482         for (q = m.m_doneq, dq = 0; q; q = c.cmd_linkp, dq++)
 483                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
 484                         mdb_warn("couldn't follow m_doneq");
 485                         rv = DCMD_ERR;
 486                         goto exit;
 487                 }
 488 
 489         for (i = 0; i < MPTSAS_MAX_TARGETS; i++)
 490                 ncmds += s->m_target[i].m_t_ncmds;







 491 
 492         mdb_printf("\n");
 493         mdb_printf("   mpt.  slot               mptsas_slots     slot");
 494         mdb_printf("\n");
 495         mdb_printf("m_ncmds total"
 496             " targ throttle m_t_ncmds targ_tot wq dq");
 497         mdb_printf("\n");
 498         mdb_printf("----------------------------------------------------");
 499         mdb_printf("\n");
 500 
 501         mdb_printf("%7d ", m.m_ncmds);
 502         mdb_printf("%s", (m.m_ncmds == slots_in_use ? "  " : "!="));
 503         mdb_printf("%3d               total %3d ", slots_in_use, ncmds);
 504         mdb_printf("%s", (tcmds == ncmds ? "     " : "   !="));
 505         mdb_printf("%3d %2d %2d\n", tcmds, wq, dq);
 506 
 507         saved_indent = mdb_dec_indent(0);
 508         mdb_dec_indent(saved_indent);
 509 
 510         for (i = 0; i < s->m_n_normal; i++)
 511                 if (s->m_slot[i]) {
 512                         if (!header_output) {
 513                                 mdb_printf("\n");
 514                                 mdb_printf("mptsas_cmd          slot cmd_slot "
 515                                     "cmd_flags cmd_pkt_flags scsi_pkt      "
 516                                     "  targ,lun [ pkt_cdbp ...\n");
 517                                 mdb_printf("-------------------------------"
 518                                     "--------------------------------------"
 519                                     "--------------------------------------"
 520                                     "------\n");
 521                                 header_output = 1;
 522                         }
 523                         mdb_printf("%16p %4d %s %4d  %8x      %8x %16p ",
 524                             s->m_slot[i], i,
 525                             (i == slots[i].cmd_slot?"   ":"BAD"),
 526                             slots[i].cmd_slot,
 527                             slots[i].cmd_flags,
 528                             slots[i].cmd_pkt_flags,
 529                             slots[i].cmd_pkt);
 530                         (void) print_cdb(&slots[i]);
 531                 }
 532 
 533         /* print the wait queue */
 534 
 535         for (q = m.m_waitq; q; q = c.cmd_linkp) {
 536                 if (q == m.m_waitq)
 537                         mdb_printf("\n");
 538                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
 539                     == -1) {
 540                         mdb_warn("couldn't follow m_waitq");
 541                         rv = DCMD_ERR;
 542                         goto exit;
 543                 }
 544                 mdb_printf("%16p wait n/a %4d  %8x      %8x %16p ",
 545                     q, c.cmd_slot, c.cmd_flags, c.cmd_pkt_flags,
 546                     c.cmd_pkt);
 547                 print_cdb(&c);
 548         }
 549 
 550         /* print the done queue */
 551 
 552         for (q = m.m_doneq; q; q = c.cmd_linkp) {
 553                 if (q == m.m_doneq)
 554                         mdb_printf("\n");
 555                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
 556                     == -1) {
 557                         mdb_warn("couldn't follow m_doneq");
 558                         rv = DCMD_ERR;
 559                         goto exit;
 560                 }
 561                 mdb_printf("%16p done  n/a %4d  %8x      %8x %16p ",
 562                     q, c.cmd_slot, c.cmd_flags, c.cmd_pkt_flags,
 563                     c.cmd_pkt);
 564                 print_cdb(&c);
 565         }
 566 
 567         mdb_inc_indent(saved_indent);
 568 
 569         if (m.m_ncmds != slots_in_use)
 570                 mdb_printf("WARNING: mpt.m_ncmds does not match the number of "
 571                     "slots in use\n");
 572 
 573         if (tcmds != ncmds)
 574                 mdb_printf("WARNING: the total of m_target[].m_t_ncmds does "
 575                     "not match the slots in use\n");
 576 
 577         if (mismatch)
 578                 mdb_printf("WARNING: corruption in slot table, "
 579                     "m_slot[].cmd_slot incorrect\n");
 580 
 581         /* now check for corruptions */
 582 
 583         for (q = m.m_waitq; q; q = c.cmd_linkp) {
 584                 for (i = 0; i < nslots; i++)
 585                         if (s->m_slot[i] == q)
 586                                 mdb_printf("WARNING: m_waitq entry"
 587                                     "(mptsas_cmd_t) %p is in m_slot[%i]\n",
 588                                     q, i);
 589 
 590                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
 591                         mdb_warn("couldn't follow m_waitq");
 592                         rv = DCMD_ERR;
 593                         goto exit;
 594                 }
 595         }
 596 
 597         for (q = m.m_doneq; q; q = c.cmd_linkp) {
 598                 for (i = 0; i < nslots; i++)
 599                         if (s->m_slot[i] == q)
 600                                 mdb_printf("WARNING: m_doneq entry "
 601                                 "(mptsas_cmd_t) %p is in m_slot[%i]\n", q, i);
 602 
 603                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
 604                         mdb_warn("couldn't follow m_doneq");
 605                         rv = DCMD_ERR;
 606                         goto exit;
 607                 }
 608                 if ((c.cmd_flags & CFLAG_FINISHED) == 0)
 609                         mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
 610                             "should have CFLAG_FINISHED set\n", q);
 611                 if (c.cmd_flags & CFLAG_IN_TRANSPORT)
 612                         mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
 613                             "should not have CFLAG_IN_TRANSPORT set\n", q);
 614                 if (c.cmd_flags & CFLAG_CMDARQ)
 615                         mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
 616                             "should not have CFLAG_CMDARQ set\n", q);
 617                 if (c.cmd_flags & CFLAG_COMPLETED)
 618                         mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
 619                             "should not have CFLAG_COMPLETED set\n", q);
 620         }
 621 
 622 exit:
 623         mdb_free(slots, sizeof (mptsas_cmd_t) * nslots);
 624         return (rv);
 625 #endif
 626         mdb_printf("\n");
 627         mdb_printf("The slot information is not implemented yet\n");
 628         return (0);
 629 }
 630 
 631 void
 632 display_deviceinfo(struct mptsas *mp)
 633 {
 634         char    device_path[PATH_MAX];
 635 
 636         *device_path = 0;
 637         if (construct_path((uintptr_t)mp->m_dip, device_path) != DCMD_OK) {
 638                 strcpy(device_path, "couldn't determine device path");
 639         }
 640 
 641         mdb_printf("\n");
 642         mdb_printf("Path in device tree %s\n", device_path);
 643 #if 0
 644         mdb_printf("base_wwid          phys "
 645             "mptid prodid  devid        revid   ssid\n");
 646         mdb_printf("-----------------------------"
 647             "----------------------------------\n");
 648         mdb_printf("%"PRIx64"     %2d   %3d "
 649             "0x%04x 0x%04x ", m.un.m_base_wwid, m.m_num_phys, m.m_mptid,
 650             m.m_productid, m.m_devid);
 651         switch (m.m_devid) {
 652                 case MPTSAS_909:
 653                         mdb_printf("(909)   ");
 654                         break;
 655                 case MPTSAS_929:
 656                         mdb_printf("(929)   ");
 657                         break;
 658                 case MPTSAS_919:
 659                         mdb_printf("(919)   ");
 660                         break;
 661                 case MPTSAS_1030:
 662                         mdb_printf("(1030)  ");
 663                         break;
 664                 case MPTSAS_1064:
 665                         mdb_printf("(1064)  ");
 666                         break;
 667                 case MPTSAS_1068:
 668                         mdb_printf("(1068)  ");
 669                         break;
 670                 case MPTSAS_1064E:
 671                         mdb_printf("(1064E) ");
 672                         break;
 673                 case MPTSAS_1068E:
 674                         mdb_printf("(1068E) ");




 675                         break;
 676                 default:
 677                         mdb_printf("(?????) ");
 678                         break;
 679         }
 680         mdb_printf("0x%02x 0x%04x\n", m.m_revid, m.m_ssid);
 681         mdb_printf("%s\n", device_path);
 682 

 683         for (i = 0; i < MAX_MPI2_PORTS; i++) {
 684                 if (i%4 == 0)
 685                         mdb_printf("\n");
 686 
 687                 mdb_printf("%d:", i);
 688 
 689                 switch (m.m_port_type[i]) {
 690                         case MPI2_PORTFACTS_PORTTYPE_INACTIVE:
 691                                 mdb_printf("inactive     ",
 692                                     m.m_protocol_flags[i]);
 693                                 break;
 694                         case MPI2_PORTFACTS_PORTTYPE_SCSI:
 695                                 mdb_printf("SCSI (0x%1x)   ",
 696                                     m.m_protocol_flags[i]);
 697                                 break;
 698                         case MPI2_PORTFACTS_PORTTYPE_FC:
 699                                 mdb_printf("FC (0x%1x)     ",
 700                                     m.m_protocol_flags[i]);
 701                                 break;
 702                         case MPI2_PORTFACTS_PORTTYPE_ISCSI:
 703                                 mdb_printf("iSCSI (0x%1x)  ",
 704                                     m.m_protocol_flags[i]);
 705                                 break;
 706                         case MPI2_PORTFACTS_PORTTYPE_SAS:
 707                                 mdb_printf("SAS (0x%1x)    ",
 708                                     m.m_protocol_flags[i]);
 709                                 break;
 710                         default:
 711                                 mdb_printf("unknown      ");
 712                 }
 713         }

 714 #endif

























 715         mdb_printf("\n");






 716 }
 717 
 718 static int
 719 mptsas_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 720 {
 721         struct mptsas           m;
 722         struct mptsas_slots     *s;
 723 
 724         int                     nslots;
 725         int                     slot_size = 0;
 726         uint_t                  verbose = FALSE;
 727         uint_t                  target_info = FALSE;
 728         uint_t                  slot_info = FALSE;
 729         uint_t                  device_info = FALSE;
 730         uint_t                  port_info = FALSE;

 731         int                     rv = DCMD_OK;
 732         void                    *mptsas_state;
 733 
 734         if (!(flags & DCMD_ADDRSPEC)) {
 735                 mptsas_state = NULL;

 736                 if (mdb_readvar(&mptsas_state, "mptsas_state") == -1) {
 737                         mdb_warn("can't read mptsas_state");
 738                         return (DCMD_ERR);
 739                 }
 740                 if (mdb_pwalk_dcmd("genunix`softstate", "mpt_sas`mptsas", argc,

 741                     argv, (uintptr_t)mptsas_state) == -1) {
 742                         mdb_warn("mdb_pwalk_dcmd failed");
 743                         return (DCMD_ERR);
 744                 }
 745                 return (DCMD_OK);
 746         }
 747 
 748         if (mdb_getopts(argc, argv,
 749             's', MDB_OPT_SETBITS, TRUE, &slot_info,
 750             'd', MDB_OPT_SETBITS, TRUE, &device_info,
 751             't', MDB_OPT_SETBITS, TRUE, &target_info,
 752             'p', MDB_OPT_SETBITS, TRUE, &port_info,
 753             'v', MDB_OPT_SETBITS, TRUE, &verbose,

 754             NULL) != argc)
 755                 return (DCMD_USAGE);
 756 
 757 
 758         if (mdb_vread(&m, sizeof (m), addr) == -1) {
 759                 mdb_warn("couldn't read mpt struct at 0x%p", addr);
 760                 return (DCMD_ERR);
 761         }
 762 
 763         s = mdb_alloc(sizeof (mptsas_slots_t), UM_SLEEP);
 764 
 765         if (mdb_vread(s, sizeof (mptsas_slots_t),
 766             (uintptr_t)m.m_active) == -1) {
 767                 mdb_warn("couldn't read small mptsas_slots_t at 0x%p",
 768                     m.m_active);
 769                 mdb_free(s, sizeof (mptsas_slots_t));
 770                 return (DCMD_ERR);
 771         }
 772 
 773         nslots = s->m_n_normal;


 806                 case PM_LEVEL_D0:
 807                         mdb_printf(" ON=D0 ");
 808                         break;
 809                 case PM_LEVEL_D1:
 810                         mdb_printf("    D1 ");
 811                         break;
 812                 case PM_LEVEL_D2:
 813                         mdb_printf("    D2 ");
 814                         break;
 815                 case PM_LEVEL_D3:
 816                         mdb_printf("OFF=D3 ");
 817                         break;
 818                 default:
 819                         mdb_printf("INVALD ");
 820         }
 821         mdb_printf("\n");
 822 
 823         mdb_inc_indent(17);
 824 
 825         if (target_info)
 826                 display_targets(&m);
 827 
 828         if (port_info)
 829                 display_ports(&m);
 830 
 831         if (device_info)
 832                 display_deviceinfo(&m);
 833 
 834         if (slot_info)
 835                 display_slotinfo();



 836 
 837         mdb_dec_indent(17);
 838 
 839         mdb_free(s, slot_size);
 840 
 841         return (rv);
 842 }
 843 
 844 void
 845 mptsas_help()
 846 {
 847         mdb_printf("Prints summary information about each mpt_sas instance, "
 848             "including warning\nmessages when slot usage doesn't match "
 849             "summary information.\n"
 850             "Without the address of a \"struct mptsas\", prints every "
 851             "instance.\n\n"
 852             "Switches:\n"
 853             "  -t   includes information about targets\n"
 854             "  -p   includes information about port\n"
 855             "  -d   includes information about the hardware\n");


 856 }
 857 
 858 static const mdb_dcmd_t dcmds[] = {
 859         { "mptsas", "?[-tpd]", "print mpt_sas information", mptsas_dcmd,
 860             mptsas_help}, { NULL }
 861 };
 862 
 863 static const mdb_modinfo_t modinfo = {
 864         MDB_API_VERSION, dcmds, NULL
 865 };
 866 
 867 const mdb_modinfo_t *
 868 _mdb_init(void)
 869 {
 870         return (&modinfo);
 871 }


 133                         mdb_printf(" online");
 134                         break;
 135                 case MDI_PATHINFO_STATE_STANDBY:
 136                         mdb_printf(" standby");
 137                         break;
 138                 case MDI_PATHINFO_STATE_FAULT:
 139                         mdb_printf(" fault");
 140                         break;
 141                 case MDI_PATHINFO_STATE_OFFLINE:
 142                         mdb_printf(" offline");
 143                         break;
 144                 default:
 145                         mdb_printf(" invalid state");
 146                         break;
 147         }
 148         mdb_printf("\n");
 149         return (0);
 150 }
 151 
 152 void
 153 mdi_info(struct mptsas *mp, int target)
 154 {
 155         struct  dev_info        d;
 156         struct  mdi_phci        p;
 157 
 158         if (mdb_vread(&d, sizeof (d), (uintptr_t)mp->m_dip) == -1) {
 159                 mdb_warn("couldn't read m_dip");
 160                 return;
 161         }
 162 
 163         if (MDI_PHCI(&d)) {
 164                 if (mdb_vread(&p, sizeof (p), (uintptr_t)d.devi_mdi_xhci)
 165                     == -1) {
 166                         mdb_warn("couldn't read m_dip.devi_mdi_xhci");
 167                         return;
 168                 }
 169                 if (p.ph_path_head)
 170                         mdb_pwalk("mdipi_phci_list", (mdb_walk_cb_t)mdi_info_cb,
 171                             &target, (uintptr_t)p.ph_path_head);
 172                 return;
 173         }
 174 }
 175 
 176 void
 177 print_cdb(mptsas_cmd_t *m)
 178 {


 284             khp + offsetof(refhash_t, rh_objs), &ml)) != NULL) {
 285                 mdb_vread(&ml, sizeof (ml), klp);
 286                 if (!(ml.rhl_flags & RHL_F_DEAD))
 287                         break;
 288         }
 289 
 290         if (klp == 0) {
 291                 mdb_free(prev, mh.rh_obj_size);
 292                 return (NULL);
 293         }
 294 
 295         kop = klp - mh.rh_link_off;
 296         rp = mdb_alloc(mh.rh_obj_size, UM_SLEEP);
 297         mdb_vread(rp, mh.rh_obj_size, kop);
 298 
 299         mdb_free(prev, mh.rh_obj_size);
 300         return (rp);
 301 }
 302 
 303 void
 304 display_targets(struct mptsas *mp, uint_t verbose)
 305 {
 306         mptsas_target_t *ptgt;
 307         mptsas_smp_t *psmp;
 308         int loop, comma;
 309 
 310         mdb_printf("\n");
 311         mdb_printf("slot devhdl      wwn     ncmds throttle   "
 312             "dr_flag  dups\n");



























 313         mdb_printf("-------------------------------"
 314             "--------------------------------\n");
 315         for (ptgt = (mptsas_target_t *)krefhash_first(
 316             (uintptr_t)mp->m_targets);
 317             ptgt != NULL;
 318             ptgt = krefhash_next((uintptr_t)mp->m_targets, ptgt)) {
 319                 if (ptgt->m_addr.mta_wwn ||
 320                     ptgt->m_deviceinfo) {
 321                         mdb_printf("%4d ", ptgt->m_slot_num);
 322                         mdb_printf("%4d ", ptgt->m_devhdl);
 323                         if (ptgt->m_addr.mta_wwn)
 324                                 mdb_printf("%"PRIx64" ",
 325                                     ptgt->m_addr.mta_wwn);
 326                         mdb_printf("%3d", ptgt->m_t_ncmds);
 327                         switch (ptgt->m_t_throttle) {
 328                                 case QFULL_THROTTLE:
 329                                         mdb_printf("   QFULL ");
 330                                         break;
 331                                 case DRAIN_THROTTLE:
 332                                         mdb_printf("   DRAIN ");
 333                                         break;
 334                                 case HOLD_THROTTLE:
 335                                         mdb_printf("    HOLD ");
 336                                         break;
 337                                 case MAX_THROTTLE:
 338                                         mdb_printf("     MAX ");
 339                                         break;



 340                                 default:
 341                                         mdb_printf("%8d ",
 342                                             ptgt->m_t_throttle);
 343                         }
 344                         switch (ptgt->m_dr_flag) {
 345                                 case MPTSAS_DR_INACTIVE:
 346                                         mdb_printf("  INACTIVE ");
 347                                         break;
 348                                 case MPTSAS_DR_INTRANSITION:
 349                                         mdb_printf("TRANSITION ");









 350                                         break;
 351                                 default:
 352                                         mdb_printf("   UNKNOWN ");
 353                                         break;
 354                                 }
 355                         mdb_printf("%d\n", ptgt->m_dups);



 356 
 357                         if (verbose) {
 358                                 mdb_inc_indent(5);
 359                                 if ((ptgt->m_deviceinfo &
 360                                     MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
 361                                     MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
 362                                         mdb_printf("Fanout expander: ");
 363                                 if ((ptgt->m_deviceinfo &
 364                                     MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
 365                                     MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER)
 366                                         mdb_printf("Edge expander: ");
 367                                 if ((ptgt->m_deviceinfo &
 368                                     MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
 369                                     MPI2_SAS_DEVICE_INFO_END_DEVICE)
 370                                         mdb_printf("End device: ");
 371                                 if ((ptgt->m_deviceinfo &
 372                                     MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
 373                                     MPI2_SAS_DEVICE_INFO_NO_DEVICE)
 374                                         mdb_printf("No device ");
 375 
 376                                 for (loop = 0, comma = 0;
 377                                     loop < (sizeof (devinfo_array) /
 378                                     sizeof (devinfo_array[0])); loop++) {
 379                                         if (ptgt->m_deviceinfo &
 380                                             devinfo_array[loop].value) {
 381                                                 mdb_printf("%s%s",
 382                                                     (comma ? ", " : ""),
 383                                                     devinfo_array[loop].text);
 384                                                 comma++;
 385                                         }
 386                                 }
 387                                 mdb_printf("\n");
 388 #if 0
 389                                 if (ptgt->m_tgt_dip) {
 390                                         char    target_path[PATH_MAX];
 391                                         *target_path = 0;
 392                                         if (construct_path((uintptr_t)
 393                                             ptgt->m_tgt_dip,
 394                                             target_path)
 395                                             == DCMD_OK)
 396                                                 mdb_printf("%s\n", target_path);
 397                                 }
 398 #endif
 399                                 mdi_info(mp, ptgt->m_slot_num);
 400                                 mdb_dec_indent(5);
 401                         }
 402                 }
 403         }
 404 
 405         mdb_printf("\n");
 406         mdb_printf("The smp child information\n");
 407         for (psmp = (mptsas_smp_t *)krefhash_first(
 408             (uintptr_t)mp->m_smp_targets);
 409             psmp != NULL;
 410             psmp = krefhash_next((uintptr_t)mp->m_smp_targets, psmp)) {
 411                 mdb_printf("\n");
 412                 mdb_printf("devhdl %x, sasaddress %"PRIx64", phymask %x \n",
 413                     psmp->m_devhdl, psmp->m_addr.mta_wwn,
 414                     psmp->m_addr.mta_phymask);
 415         }
 416 }
 417 
 418 int
 419 display_slotinfo(struct mptsas *mp, struct mptsas_slots *s)
 420 {

 421         int                     i, nslots;
 422         struct mptsas_cmd       c, *q, *slots;
 423         mptsas_target_t         *ptgt;
 424         int                     header_output = 0;
 425         int                     rv = DCMD_OK;
 426         int                     slots_in_use = 0;
 427         int                     tcmds = 0;
 428         int                     mismatch = 0;
 429         int                     wq, dq;
 430         int                     ncmds = 0;
 431         ulong_t                 saved_indent;
 432 
 433         nslots = s->m_n_normal;

 434         slots = mdb_alloc(sizeof (mptsas_cmd_t) * nslots, UM_SLEEP);
 435 
 436         for (i = 0; i < nslots; i++)
 437                 if (s->m_slot[i]) {
 438                         slots_in_use++;
 439                         if (mdb_vread(&slots[i], sizeof (mptsas_cmd_t),
 440                             (uintptr_t)s->m_slot[i]) == -1) {
 441                                 mdb_warn("couldn't read slot");
 442                                 s->m_slot[i] = NULL;
 443                         }
 444                         if ((slots[i].cmd_flags & CFLAG_CMDIOC) == 0)
 445                                 tcmds++;
 446                         if (i != slots[i].cmd_slot)
 447                                 mismatch++;
 448                 }
 449 
 450         for (q = mp->m_waitq, wq = 0; q; q = c.cmd_linkp, wq++)
 451                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
 452                         mdb_warn("couldn't follow m_waitq");
 453                         rv = DCMD_ERR;
 454                         goto exit;
 455                 }
 456 
 457         for (q = mp->m_doneq, dq = 0; q; q = c.cmd_linkp, dq++)
 458                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
 459                         mdb_warn("couldn't follow m_doneq");
 460                         rv = DCMD_ERR;
 461                         goto exit;
 462                 }
 463 
 464         for (ptgt = (mptsas_target_t *)krefhash_first(
 465             (uintptr_t)mp->m_targets);
 466             ptgt != NULL;
 467             ptgt = krefhash_next((uintptr_t)mp->m_targets, ptgt)) {
 468                 if (ptgt->m_addr.mta_wwn ||
 469                     ptgt->m_deviceinfo) {
 470                         ncmds += ptgt->m_t_ncmds;
 471                 }
 472         }
 473 
 474         mdb_printf("\n");
 475         mdb_printf("   mpt.  slot               mptsas_slots     slot");
 476         mdb_printf("\n");
 477         mdb_printf("m_ncmds total"
 478             " targ throttle m_t_ncmds targ_tot wq dq");
 479         mdb_printf("\n");
 480         mdb_printf("----------------------------------------------------");
 481         mdb_printf("\n");
 482 
 483         mdb_printf("%7d ", mp->m_ncmds);
 484         mdb_printf("%s", (mp->m_ncmds == slots_in_use ? "  " : "!="));
 485         mdb_printf("%3d               total %3d ", slots_in_use, ncmds);
 486         mdb_printf("%s", (tcmds == ncmds ? "     " : "   !="));
 487         mdb_printf("%3d %2d %2d\n", tcmds, wq, dq);
 488 
 489         saved_indent = mdb_dec_indent(0);
 490         mdb_dec_indent(saved_indent);
 491 
 492         for (i = 0; i < s->m_n_normal; i++)
 493                 if (s->m_slot[i]) {
 494                         if (!header_output) {
 495                                 mdb_printf("\n");
 496                                 mdb_printf("mptsas_cmd          slot cmd_slot "
 497                                     "cmd_flags cmd_pkt_flags scsi_pkt      "
 498                                     "  targ,lun [ pkt_cdbp ...\n");
 499                                 mdb_printf("-------------------------------"
 500                                     "--------------------------------------"
 501                                     "--------------------------------------"
 502                                     "------\n");
 503                                 header_output = 1;
 504                         }
 505                         mdb_printf("%16p %4d %s %4d  %8x      %8x %16p ",
 506                             s->m_slot[i], i,
 507                             (i == slots[i].cmd_slot?"   ":"BAD"),
 508                             slots[i].cmd_slot,
 509                             slots[i].cmd_flags,
 510                             slots[i].cmd_pkt_flags,
 511                             slots[i].cmd_pkt);
 512                         (void) print_cdb(&slots[i]);
 513                 }
 514 
 515         /* print the wait queue */
 516 
 517         for (q = mp->m_waitq; q; q = c.cmd_linkp) {
 518                 if (q == mp->m_waitq)
 519                         mdb_printf("\n");
 520                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
 521                     == -1) {
 522                         mdb_warn("couldn't follow m_waitq");
 523                         rv = DCMD_ERR;
 524                         goto exit;
 525                 }
 526                 mdb_printf("%16p wait n/a %4d  %8x      %8x %16p ",
 527                     q, c.cmd_slot, c.cmd_flags, c.cmd_pkt_flags,
 528                     c.cmd_pkt);
 529                 print_cdb(&c);
 530         }
 531 
 532         /* print the done queue */
 533 
 534         for (q = mp->m_doneq; q; q = c.cmd_linkp) {
 535                 if (q == mp->m_doneq)
 536                         mdb_printf("\n");
 537                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
 538                     == -1) {
 539                         mdb_warn("couldn't follow m_doneq");
 540                         rv = DCMD_ERR;
 541                         goto exit;
 542                 }
 543                 mdb_printf("%16p done  n/a %4d  %8x      %8x %16p ",
 544                     q, c.cmd_slot, c.cmd_flags, c.cmd_pkt_flags,
 545                     c.cmd_pkt);
 546                 print_cdb(&c);
 547         }
 548 
 549         mdb_inc_indent(saved_indent);
 550 
 551         if (mp->m_ncmds != slots_in_use)
 552                 mdb_printf("WARNING: mpt.m_ncmds does not match the number of "
 553                     "slots in use\n");
 554 
 555         if (tcmds != ncmds)
 556                 mdb_printf("WARNING: the total of m_target[].m_t_ncmds does "
 557                     "not match the slots in use\n");
 558 
 559         if (mismatch)
 560                 mdb_printf("WARNING: corruption in slot table, "
 561                     "m_slot[].cmd_slot incorrect\n");
 562 
 563         /* now check for corruptions */
 564 
 565         for (q = mp->m_waitq; q; q = c.cmd_linkp) {
 566                 for (i = 0; i < nslots; i++)
 567                         if (s->m_slot[i] == q)
 568                                 mdb_printf("WARNING: m_waitq entry"
 569                                     "(mptsas_cmd_t) %p is in m_slot[%i]\n",
 570                                     q, i);
 571 
 572                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
 573                         mdb_warn("couldn't follow m_waitq");
 574                         rv = DCMD_ERR;
 575                         goto exit;
 576                 }
 577         }
 578 
 579         for (q = mp->m_doneq; q; q = c.cmd_linkp) {
 580                 for (i = 0; i < nslots; i++)
 581                         if (s->m_slot[i] == q)
 582                                 mdb_printf("WARNING: m_doneq entry "
 583                                 "(mptsas_cmd_t) %p is in m_slot[%i]\n", q, i);
 584 
 585                 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
 586                         mdb_warn("couldn't follow m_doneq");
 587                         rv = DCMD_ERR;
 588                         goto exit;
 589                 }
 590                 if ((c.cmd_flags & CFLAG_FINISHED) == 0)
 591                         mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
 592                             "should have CFLAG_FINISHED set\n", q);
 593                 if (c.cmd_flags & CFLAG_IN_TRANSPORT)
 594                         mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
 595                             "should not have CFLAG_IN_TRANSPORT set\n", q);
 596                 if (c.cmd_flags & CFLAG_CMDARQ)
 597                         mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
 598                             "should not have CFLAG_CMDARQ set\n", q);
 599                 if (c.cmd_flags & CFLAG_COMPLETED)
 600                         mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
 601                             "should not have CFLAG_COMPLETED set\n", q);
 602         }
 603 
 604 exit:
 605         mdb_free(slots, sizeof (mptsas_cmd_t) * nslots);
 606         return (rv);




 607 }
 608 
 609 void
 610 display_deviceinfo(struct mptsas *mp)
 611 {
 612         char    device_path[PATH_MAX];
 613 
 614         *device_path = 0;
 615         if (construct_path((uintptr_t)mp->m_dip, device_path) != DCMD_OK) {
 616                 strcpy(device_path, "couldn't determine device path");
 617         }
 618 
 619         mdb_printf("\n");


 620         mdb_printf("base_wwid          phys "
 621             " prodid  devid          revid   ssid\n");
 622         mdb_printf("-----------------------------"
 623             "----------------------------------\n");
 624         mdb_printf("%"PRIx64"     %2d  "
 625             "0x%04x 0x%04x ", mp->un.m_base_wwid, mp->m_num_phys,
 626             mp->m_productid, mp->m_devid);
 627         switch (mp->m_devid) {
 628                 case MPI2_MFGPAGE_DEVID_SAS2004:
 629                         mdb_printf("(SAS2004) ");
 630                         break;
 631                 case MPI2_MFGPAGE_DEVID_SAS2008:
 632                         mdb_printf("(SAS2008) ");
 633                         break;
 634                 case MPI2_MFGPAGE_DEVID_SAS2108_1:
 635                 case MPI2_MFGPAGE_DEVID_SAS2108_2:
 636                 case MPI2_MFGPAGE_DEVID_SAS2108_3:
 637                         mdb_printf("(SAS2108) ");
 638                         break;
 639                 case MPI2_MFGPAGE_DEVID_SAS2116_1:
 640                 case MPI2_MFGPAGE_DEVID_SAS2116_2:
 641                         mdb_printf("(SAS2116) ");
 642                         break;
 643                 case MPI2_MFGPAGE_DEVID_SAS2208_1:
 644                 case MPI2_MFGPAGE_DEVID_SAS2208_2:
 645                 case MPI2_MFGPAGE_DEVID_SAS2208_3:
 646                 case MPI2_MFGPAGE_DEVID_SAS2208_4:
 647                 case MPI2_MFGPAGE_DEVID_SAS2208_5:
 648                 case MPI2_MFGPAGE_DEVID_SAS2208_6:
 649 #if 0
 650                 /* Same as 2308_1/2 ?? */
 651                 case MPI2_MFGPAGE_DEVID_SAS2208_7:
 652                 case MPI2_MFGPAGE_DEVID_SAS2208_8:
 653 #endif
 654                         mdb_printf("(SAS2208) ");
 655                         break;
 656                 default:
 657                         mdb_printf("(SAS????) ");
 658                         break;
 659         }
 660         mdb_printf("0x%02x 0x%04x\n", mp->m_revid, mp->m_ssid);
 661         mdb_printf("%s\n", device_path);
 662 
 663 #if 0
 664         for (i = 0; i < MAX_MPI2_PORTS; i++) {
 665                 if (i%4 == 0)
 666                         mdb_printf("\n");
 667 
 668                 mdb_printf("%d:", i);
 669 
 670                 switch (mp->m_port_type[i]) {
 671                         case MPI2_PORTFACTS_PORTTYPE_INACTIVE:
 672                                 mdb_printf("inactive     ",
 673                                     mp->m_protocol_flags[i]);
 674                                 break;
 675                         case MPI2_PORTFACTS_PORTTYPE_SCSI:
 676                                 mdb_printf("SCSI (0x%1x)   ",
 677                                     mp->m_protocol_flags[i]);
 678                                 break;
 679                         case MPI2_PORTFACTS_PORTTYPE_FC:
 680                                 mdb_printf("FC (0x%1x)     ",
 681                                     mp->m_protocol_flags[i]);
 682                                 break;
 683                         case MPI2_PORTFACTS_PORTTYPE_ISCSI:
 684                                 mdb_printf("iSCSI (0x%1x)  ",
 685                                     mp->m_protocol_flags[i]);
 686                                 break;
 687                         case MPI2_PORTFACTS_PORTTYPE_SAS:
 688                                 mdb_printf("SAS (0x%1x)    ",
 689                                     mp->m_protocol_flags[i]);
 690                                 break;
 691                         default:
 692                                 mdb_printf("unknown      ");
 693                 }
 694         }
 695         mdb_printf("\n");
 696 #endif
 697 }
 698 
 699 void
 700 dump_debug_log(struct mptsas *mp)
 701 {
 702         uint_t  idx;
 703         char    *logbuf;
 704         int     i;
 705 
 706         if (mdb_readsym(&idx, sizeof (uint_t),
 707                 "mptsas_dbglog_idx") == -1) {
 708                 mdb_warn("No debug log buffer present");
 709                 return;
 710         }
 711         logbuf = mdb_alloc(16*256, UM_SLEEP);
 712         if (idx == 0) {
 713                 mdb_warn("Logging turned off");
 714                 return;
 715         }
 716         
 717         if (mdb_readsym(logbuf, 16*256,
 718                 "mptsas_dbglog_bufs") == -1) {
 719                 mdb_warn("No debug log buffer present");
 720                 return;
 721         }
 722         mdb_printf("\n");
 723         idx &= 0xf;
 724         for (i = 0; i < 16; i++) {
 725                 mdb_printf("%s\n", &logbuf[idx*256]);
 726                 idx = (idx+1) & 0xf;
 727         }
 728         mdb_free(logbuf, 16*256);
 729 }
 730 
 731 static int
 732 mptsas_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 733 {
 734         struct mptsas           m;
 735         struct mptsas_slots     *s;
 736 
 737         int                     nslots;
 738         int                     slot_size = 0;
 739         uint_t                  verbose = FALSE;
 740         uint_t                  target_info = FALSE;
 741         uint_t                  slot_info = FALSE;
 742         uint_t                  device_info = FALSE;
 743         uint_t                  port_info = FALSE;
 744         uint_t                  debug_log = FALSE;
 745         int                     rv = DCMD_OK;

 746 
 747         if (!(flags & DCMD_ADDRSPEC)) {
 748                 void            *mptsas_state = NULL;
 749 
 750                 if (mdb_readvar(&mptsas_state, "mptsas_state") == -1) {
 751                         mdb_warn("can't read mptsas_state");
 752                         return (DCMD_ERR);
 753                 }
 754                 if (mdb_pwalk_dcmd("genunix`softstate",
 755                         "mpt_sas`mptsas", argc,
 756                         argv, (uintptr_t)mptsas_state) == -1) {
 757                         mdb_warn("mdb_pwalk_dcmd failed");
 758                         return (DCMD_ERR);
 759                 }
 760                 return (DCMD_OK);
 761         }
 762 
 763         if (mdb_getopts(argc, argv,
 764             's', MDB_OPT_SETBITS, TRUE, &slot_info,
 765             'd', MDB_OPT_SETBITS, TRUE, &device_info,
 766             't', MDB_OPT_SETBITS, TRUE, &target_info,
 767             'p', MDB_OPT_SETBITS, TRUE, &port_info,
 768             'v', MDB_OPT_SETBITS, TRUE, &verbose,
 769             'D', MDB_OPT_SETBITS, TRUE, &debug_log,
 770             NULL) != argc)
 771                 return (DCMD_USAGE);
 772 
 773 
 774         if (mdb_vread(&m, sizeof (m), addr) == -1) {
 775                 mdb_warn("couldn't read mpt struct at 0x%p", addr);
 776                 return (DCMD_ERR);
 777         }
 778 
 779         s = mdb_alloc(sizeof (mptsas_slots_t), UM_SLEEP);
 780 
 781         if (mdb_vread(s, sizeof (mptsas_slots_t),
 782             (uintptr_t)m.m_active) == -1) {
 783                 mdb_warn("couldn't read small mptsas_slots_t at 0x%p",
 784                     m.m_active);
 785                 mdb_free(s, sizeof (mptsas_slots_t));
 786                 return (DCMD_ERR);
 787         }
 788 
 789         nslots = s->m_n_normal;


 822                 case PM_LEVEL_D0:
 823                         mdb_printf(" ON=D0 ");
 824                         break;
 825                 case PM_LEVEL_D1:
 826                         mdb_printf("    D1 ");
 827                         break;
 828                 case PM_LEVEL_D2:
 829                         mdb_printf("    D2 ");
 830                         break;
 831                 case PM_LEVEL_D3:
 832                         mdb_printf("OFF=D3 ");
 833                         break;
 834                 default:
 835                         mdb_printf("INVALD ");
 836         }
 837         mdb_printf("\n");
 838 
 839         mdb_inc_indent(17);
 840 
 841         if (target_info)
 842                 display_targets(&m, verbose);
 843 
 844         if (port_info)
 845                 display_ports(&m);
 846 
 847         if (device_info)
 848                 display_deviceinfo(&m);
 849 
 850         if (slot_info)
 851                 display_slotinfo(&m, s);
 852 
 853         if (debug_log)
 854                 dump_debug_log(&m);
 855 
 856         mdb_dec_indent(17);
 857 
 858         mdb_free(s, slot_size);
 859 
 860         return (rv);
 861 }
 862 
 863 void
 864 mptsas_help()
 865 {
 866         mdb_printf("Prints summary information about each mpt_sas instance, "
 867             "including warning\nmessages when slot usage doesn't match "
 868             "summary information.\n"
 869             "Without the address of a \"struct mptsas\", prints every "
 870             "instance.\n\n"
 871             "Switches:\n"
 872             "  -t[v]  includes information about targets, v = be more verbose\n"
 873             "  -p     includes information about port\n"
 874             "  -s     includes information about mpt slots\n"
 875             "  -d     includes information about the hardware\n"
 876             "  -D     print the mptsas specific debug log\n");
 877 }
 878 
 879 static const mdb_dcmd_t dcmds[] = {
 880         { "mptsas", "?[-tpsdD]", "print mpt_sas information", mptsas_dcmd,
 881             mptsas_help}, { NULL }
 882 };
 883 
 884 static const mdb_modinfo_t modinfo = {
 885         MDB_API_VERSION, dcmds, NULL
 886 };
 887 
 888 const mdb_modinfo_t *
 889 _mdb_init(void)
 890 {
 891         return (&modinfo);
 892 }