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 }
|