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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Copyright 2014 Joyent, Inc. All rights reserved.
28 * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
32 #include <sys/mdb_modapi.h>
33 #include <sys/sysinfo.h>
34 #include <sys/sunmdi.h>
36 #include <sys/scsi/scsi.h>
39 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
40 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
41 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
42 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
43 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
44 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
45 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
46 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
49 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
50 #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
56 { MPI2_SAS_DEVICE_INFO_SEP
, "SEP" },
57 { MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE
, "ATAPI device" },
58 { MPI2_SAS_DEVICE_INFO_LSI_DEVICE
, "LSI device" },
59 { MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH
, "direct attach" },
60 { MPI2_SAS_DEVICE_INFO_SSP_TARGET
, "SSP tgt" },
61 { MPI2_SAS_DEVICE_INFO_STP_TARGET
, "STP tgt" },
62 { MPI2_SAS_DEVICE_INFO_SMP_TARGET
, "SMP tgt" },
63 { MPI2_SAS_DEVICE_INFO_SATA_DEVICE
, "SATA dev" },
64 { MPI2_SAS_DEVICE_INFO_SSP_INITIATOR
, "SSP init" },
65 { MPI2_SAS_DEVICE_INFO_STP_INITIATOR
, "STP init" },
66 { MPI2_SAS_DEVICE_INFO_SMP_INITIATOR
, "SMP init" },
67 { MPI2_SAS_DEVICE_INFO_SATA_HOST
, "SATA host" }
71 construct_path(uintptr_t addr
, char *result
)
74 char devi_node
[PATH_MAX
];
75 char devi_addr
[PATH_MAX
];
77 if (mdb_vread(&d
, sizeof (d
), addr
) == -1) {
78 mdb_warn("couldn't read dev_info");
83 construct_path((uintptr_t)d
.devi_parent
, result
);
84 mdb_readstr(devi_node
, sizeof (devi_node
),
85 (uintptr_t)d
.devi_node_name
);
86 mdb_readstr(devi_addr
, sizeof (devi_addr
),
87 (uintptr_t)d
.devi_addr
);
88 mdb_snprintf(result
+strlen(result
),
89 PATH_MAX
-strlen(result
),
90 "/%s%s%s", devi_node
, (*devi_addr
? "@" : ""),
98 mdi_info_cb(uintptr_t addr
, const void *data
, void *cbdata
)
100 struct mdi_pathinfo pi
;
102 char dev_path
[PATH_MAX
];
103 char string
[PATH_MAX
];
104 int mdi_target
= 0, mdi_lun
= 0;
105 int target
= *(int *)cbdata
;
107 if (mdb_vread(&pi
, sizeof (pi
), addr
) == -1) {
108 mdb_warn("couldn't read mdi_pathinfo");
111 mdb_readstr(string
, sizeof (string
), (uintptr_t)pi
.pi_addr
);
112 mdi_target
= (int)mdb_strtoull(string
);
113 mdi_lun
= (int)mdb_strtoull(strchr(string
, ',') + 1);
114 if (target
!= mdi_target
)
117 if (mdb_vread(&c
, sizeof (c
), (uintptr_t)pi
.pi_client
) == -1) {
118 mdb_warn("couldn't read mdi_client");
123 if (construct_path((uintptr_t)c
.ct_dip
, dev_path
) != DCMD_OK
)
124 strcpy(dev_path
, "unknown");
126 mdb_printf("LUN %d: %s\n", mdi_lun
, dev_path
);
127 mdb_printf(" dip: %p %s path", c
.ct_dip
,
128 (pi
.pi_preferred
? "preferred" : ""));
129 switch (pi
.pi_state
& MDI_PATHINFO_STATE_MASK
) {
130 case MDI_PATHINFO_STATE_INIT
:
131 mdb_printf(" initializing");
133 case MDI_PATHINFO_STATE_ONLINE
:
134 mdb_printf(" online");
136 case MDI_PATHINFO_STATE_STANDBY
:
137 mdb_printf(" standby");
139 case MDI_PATHINFO_STATE_FAULT
:
140 mdb_printf(" fault");
142 case MDI_PATHINFO_STATE_OFFLINE
:
143 mdb_printf(" offline");
146 mdb_printf(" invalid state");
154 mdi_info(struct mptsas
*mp
, int target
)
159 if (mdb_vread(&d
, sizeof (d
), (uintptr_t)mp
->m_dip
) == -1) {
160 mdb_warn("couldn't read m_dip");
165 if (mdb_vread(&p
, sizeof (p
), (uintptr_t)d
.devi_mdi_xhci
)
167 mdb_warn("couldn't read m_dip.devi_mdi_xhci");
171 mdb_pwalk("mdipi_phci_list", (mdb_walk_cb_t
)mdi_info_cb
,
172 &target
, (uintptr_t)p
.ph_path_head
);
178 print_cdb(mptsas_cmd_t
*m
)
181 uchar_t cdb
[512]; /* an arbitrarily large number */
184 if (mdb_vread(&pkt
, sizeof (pkt
), (uintptr_t)m
->cmd_pkt
) == -1) {
185 mdb_warn("couldn't read cmd_pkt");
190 * We use cmd_cdblen here because 5.10 doesn't
191 * have the cdb length in the pkt
193 if (mdb_vread(&cdb
, m
->cmd_cdblen
, (uintptr_t)pkt
.pkt_cdbp
) == -1) {
194 mdb_warn("couldn't read pkt_cdbp");
198 mdb_printf("%3d,%-3d [ ",
199 pkt
.pkt_address
.a_target
, pkt
.pkt_address
.a_lun
);
201 for (j
= 0; j
< m
->cmd_cdblen
; j
++)
202 mdb_printf("%02x ", cdb
[j
]);
209 display_ports(struct mptsas
*mp
)
213 mdb_printf("phy number and port mapping table\n");
214 for (i
= 0; i
< MPTSAS_MAX_PHYS
; i
++) {
215 if (mp
->m_phy_info
[i
].attached_devhdl
) {
216 mdb_printf("phy %x --> port %x, phymask %x,"
217 "attached_devhdl %x\n", i
, mp
->m_phy_info
[i
].port_num
,
218 mp
->m_phy_info
[i
].phy_mask
,
219 mp
->m_phy_info
[i
].attached_devhdl
);
226 klist_head(list_t
*lp
, uintptr_t klp
)
228 if ((uintptr_t)lp
->list_head
.list_next
==
229 klp
+ offsetof(struct list
, list_head
))
230 return ((uintptr_t)NULL
);
232 return ((uintptr_t)(((char *)lp
->list_head
.list_next
) -
237 klist_next(list_t
*lp
, uintptr_t klp
, void *op
)
239 /* LINTED E_BAD_PTR_CAST_ALIG */
240 struct list_node
*np
= (struct list_node
*)(((char *)op
) +
243 if ((uintptr_t)np
->list_next
== klp
+ offsetof(struct list
, list_head
))
244 return ((uintptr_t)NULL
);
246 return (((uintptr_t)(np
->list_next
)) - lp
->list_offset
);
250 krefhash_first(uintptr_t khp
, uintptr_t *addr
)
257 mdb_vread(&mh
, sizeof (mh
), khp
);
258 klp
= klist_head(&mh
.rh_objs
, khp
+ offsetof(refhash_t
, rh_objs
));
262 kop
= klp
- mh
.rh_link_off
;
265 rp
= mdb_alloc(mh
.rh_obj_size
, UM_SLEEP
);
266 mdb_vread(rp
, mh
.rh_obj_size
, kop
);
272 krefhash_next(uintptr_t khp
, void *op
, uintptr_t *addr
)
282 mdb_vread(&mh
, sizeof (mh
), khp
);
283 /* LINTED E_BAD_PTR_CAST_ALIG */
284 lp
= (refhash_link_t
*)(((char *)(op
)) + mh
.rh_link_off
);
286 while ((klp
= klist_next(&mh
.rh_objs
,
287 khp
+ offsetof(refhash_t
, rh_objs
), &ml
)) != (uintptr_t)NULL
) {
288 mdb_vread(&ml
, sizeof (ml
), klp
);
289 if (!(ml
.rhl_flags
& RHL_F_DEAD
))
293 if (klp
== (uintptr_t)NULL
) {
294 mdb_free(prev
, mh
.rh_obj_size
);
298 kop
= klp
- mh
.rh_link_off
;
301 rp
= mdb_alloc(mh
.rh_obj_size
, UM_SLEEP
);
302 mdb_vread(rp
, mh
.rh_obj_size
, kop
);
304 mdb_free(prev
, mh
.rh_obj_size
);
309 display_targets(struct mptsas
*mp
, uint_t verbose
)
311 mptsas_target_t
*ptgt
;
317 mdb_printf(" mptsas_target_t slot devhdl wwn ncmds throttle "
319 mdb_printf("---------------------------------------"
320 "-------------------------------\n");
321 for (ptgt
= krefhash_first((uintptr_t)mp
->m_targets
, &p_addr
);
323 ptgt
= krefhash_next((uintptr_t)mp
->m_targets
, ptgt
, &p_addr
)) {
324 if (ptgt
->m_addr
.mta_wwn
||
325 ptgt
->m_deviceinfo
) {
326 mdb_printf("%16p ", p_addr
);
327 mdb_printf("%4d ", ptgt
->m_slot_num
);
328 mdb_printf("%4d ", ptgt
->m_devhdl
);
329 if (ptgt
->m_addr
.mta_wwn
)
330 mdb_printf("%"PRIx64
" ",
331 ptgt
->m_addr
.mta_wwn
);
332 mdb_printf("%3d", ptgt
->m_t_ncmds
);
333 switch (ptgt
->m_t_throttle
) {
335 mdb_printf(" QFULL ");
338 mdb_printf(" DRAIN ");
341 mdb_printf(" HOLD ");
350 switch (ptgt
->m_dr_flag
) {
351 case MPTSAS_DR_INACTIVE
:
352 mdb_printf(" INACTIVE ");
354 case MPTSAS_DR_INTRANSITION
:
355 mdb_printf("TRANSITION ");
358 mdb_printf(" UNKNOWN ");
366 if ((ptgt
->m_deviceinfo
&
367 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE
) ==
368 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER
)
369 mdb_printf("Fanout expander: ");
370 if ((ptgt
->m_deviceinfo
&
371 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE
) ==
372 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER
)
373 mdb_printf("Edge expander: ");
374 if ((ptgt
->m_deviceinfo
&
375 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE
) ==
376 MPI2_SAS_DEVICE_INFO_END_DEVICE
)
377 mdb_printf("End device: ");
378 if ((ptgt
->m_deviceinfo
&
379 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE
) ==
380 MPI2_SAS_DEVICE_INFO_NO_DEVICE
)
381 mdb_printf("No device ");
383 for (loop
= 0, comma
= 0;
384 loop
< (sizeof (devinfo_array
) /
385 sizeof (devinfo_array
[0])); loop
++) {
386 if (ptgt
->m_deviceinfo
&
387 devinfo_array
[loop
].value
) {
390 devinfo_array
[loop
].text
);
395 mdi_info(mp
, ptgt
->m_slot_num
);
402 mdb_printf(" mptsas_smp_t devhdl wwn phymask\n");
403 mdb_printf("---------------------------------------"
404 "------------------\n");
405 for (psmp
= (mptsas_smp_t
*)krefhash_first(
406 (uintptr_t)mp
->m_smp_targets
, &p_addr
);
408 psmp
= krefhash_next((uintptr_t)mp
->m_smp_targets
, psmp
,
410 mdb_printf("%16p ", p_addr
);
411 mdb_printf("%4d %"PRIx64
" %04x\n",
412 psmp
->m_devhdl
, psmp
->m_addr
.mta_wwn
,
413 psmp
->m_addr
.mta_phymask
);
419 if ((psmp
->m_deviceinfo
& MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE
)
420 == MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER
)
421 mdb_printf("Fanout expander: ");
422 if ((psmp
->m_deviceinfo
& MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE
)
423 == MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER
)
424 mdb_printf("Edge expander: ");
425 if ((psmp
->m_deviceinfo
& MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE
)
426 == MPI2_SAS_DEVICE_INFO_END_DEVICE
)
427 mdb_printf("End device: ");
428 if ((psmp
->m_deviceinfo
& MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE
)
429 == MPI2_SAS_DEVICE_INFO_NO_DEVICE
)
430 mdb_printf("No device ");
432 for (loop
= 0, comma
= 0;
433 loop
< (sizeof (devinfo_array
)
434 / sizeof (devinfo_array
[0]));
436 if (psmp
->m_deviceinfo
&
437 devinfo_array
[loop
].value
) {
440 devinfo_array
[loop
].text
);
450 display_slotinfo(struct mptsas
*mp
, struct mptsas_slots
*s
)
453 struct mptsas_cmd c
, *q
, *slots
;
454 mptsas_target_t
*ptgt
;
455 int header_output
= 0;
457 int slots_in_use
= 0;
462 ulong_t saved_indent
;
466 if ((state
= mdb_get_state()) == MDB_STATE_RUNNING
) {
467 mdb_warn("mptsas: slot info can only be displayed on a system "
468 "dump or under kmdb\n");
472 if (mdb_readvar(&panicstr
, "panicstr") == -1) {
473 mdb_warn("can't read variable 'panicstr'");
477 if (state
!= MDB_STATE_STOPPED
&& panicstr
== (uintptr_t)NULL
) {
478 mdb_warn("mptsas: slot info not available for live dump\n");
482 nslots
= s
->m_n_normal
;
483 slots
= mdb_alloc(sizeof (mptsas_cmd_t
) * nslots
, UM_SLEEP
);
485 for (i
= 0; i
< nslots
; i
++)
488 if (mdb_vread(&slots
[i
], sizeof (mptsas_cmd_t
),
489 (uintptr_t)s
->m_slot
[i
]) == -1) {
490 mdb_warn("couldn't read slot");
493 if ((slots
[i
].cmd_flags
& CFLAG_CMDIOC
) == 0)
495 if (i
!= slots
[i
].cmd_slot
)
499 for (q
= mp
->m_waitq
, wq
= 0; q
; q
= c
.cmd_linkp
, wq
++)
500 if (mdb_vread(&c
, sizeof (mptsas_cmd_t
), (uintptr_t)q
) == -1) {
501 mdb_warn("couldn't follow m_waitq");
506 for (q
= mp
->m_doneq
, dq
= 0; q
; q
= c
.cmd_linkp
, dq
++)
507 if (mdb_vread(&c
, sizeof (mptsas_cmd_t
), (uintptr_t)q
) == -1) {
508 mdb_warn("couldn't follow m_doneq");
513 for (ptgt
= krefhash_first((uintptr_t)mp
->m_targets
, NULL
);
515 ptgt
= krefhash_next((uintptr_t)mp
->m_targets
, ptgt
, NULL
)) {
516 if (ptgt
->m_addr
.mta_wwn
||
517 ptgt
->m_deviceinfo
) {
518 ncmds
+= ptgt
->m_t_ncmds
;
523 mdb_printf(" mpt. slot mptsas_slots slot");
525 mdb_printf("m_ncmds total"
526 " targ throttle m_t_ncmds targ_tot wq dq");
528 mdb_printf("----------------------------------------------------");
531 mdb_printf("%7d ", mp
->m_ncmds
);
532 mdb_printf("%s", (mp
->m_ncmds
== slots_in_use
? " " : "!="));
533 mdb_printf("%3d total %3d ", slots_in_use
, ncmds
);
534 mdb_printf("%s", (tcmds
== ncmds
? " " : " !="));
535 mdb_printf("%3d %2d %2d\n", tcmds
, wq
, dq
);
537 saved_indent
= mdb_dec_indent(0);
538 mdb_dec_indent(saved_indent
);
540 for (i
= 0; i
< s
->m_n_normal
; i
++)
542 if (!header_output
) {
544 mdb_printf("mptsas_cmd slot cmd_slot "
545 "cmd_flags cmd_pkt_flags scsi_pkt "
546 " targ,lun [ pkt_cdbp ...\n");
547 mdb_printf("-------------------------------"
548 "--------------------------------------"
549 "--------------------------------------"
553 mdb_printf("%16p %4d %s %4d %8x %8x %16p ",
555 (i
== slots
[i
].cmd_slot
?" ":"BAD"),
558 slots
[i
].cmd_pkt_flags
,
560 (void) print_cdb(&slots
[i
]);
563 /* print the wait queue */
565 for (q
= mp
->m_waitq
; q
; q
= c
.cmd_linkp
) {
566 if (q
== mp
->m_waitq
)
568 if (mdb_vread(&c
, sizeof (mptsas_cmd_t
), (uintptr_t)q
)
570 mdb_warn("couldn't follow m_waitq");
574 mdb_printf("%16p wait n/a %4d %8x %8x %16p ",
575 q
, c
.cmd_slot
, c
.cmd_flags
, c
.cmd_pkt_flags
,
580 /* print the done queue */
582 for (q
= mp
->m_doneq
; q
; q
= c
.cmd_linkp
) {
583 if (q
== mp
->m_doneq
)
585 if (mdb_vread(&c
, sizeof (mptsas_cmd_t
), (uintptr_t)q
)
587 mdb_warn("couldn't follow m_doneq");
591 mdb_printf("%16p done n/a %4d %8x %8x %16p ",
592 q
, c
.cmd_slot
, c
.cmd_flags
, c
.cmd_pkt_flags
,
597 mdb_inc_indent(saved_indent
);
599 if (mp
->m_ncmds
!= slots_in_use
)
600 mdb_printf("WARNING: mpt.m_ncmds does not match the number of "
604 mdb_printf("WARNING: the total of m_target[].m_t_ncmds does "
605 "not match the slots in use\n");
608 mdb_printf("WARNING: corruption in slot table, "
609 "m_slot[].cmd_slot incorrect\n");
611 /* now check for corruptions */
613 for (q
= mp
->m_waitq
; q
; q
= c
.cmd_linkp
) {
614 for (i
= 0; i
< nslots
; i
++)
615 if (s
->m_slot
[i
] == q
)
616 mdb_printf("WARNING: m_waitq entry"
617 "(mptsas_cmd_t) %p is in m_slot[%i]\n",
620 if (mdb_vread(&c
, sizeof (mptsas_cmd_t
), (uintptr_t)q
) == -1) {
621 mdb_warn("couldn't follow m_waitq");
627 for (q
= mp
->m_doneq
; q
; q
= c
.cmd_linkp
) {
628 for (i
= 0; i
< nslots
; i
++)
629 if (s
->m_slot
[i
] == q
)
630 mdb_printf("WARNING: m_doneq entry "
631 "(mptsas_cmd_t) %p is in m_slot[%i]\n", q
, i
);
633 if (mdb_vread(&c
, sizeof (mptsas_cmd_t
), (uintptr_t)q
) == -1) {
634 mdb_warn("couldn't follow m_doneq");
638 if ((c
.cmd_flags
& CFLAG_FINISHED
) == 0)
639 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
640 "should have CFLAG_FINISHED set\n", q
);
641 if (c
.cmd_flags
& CFLAG_IN_TRANSPORT
)
642 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
643 "should not have CFLAG_IN_TRANSPORT set\n", q
);
644 if (c
.cmd_flags
& CFLAG_CMDARQ
)
645 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
646 "should not have CFLAG_CMDARQ set\n", q
);
647 if (c
.cmd_flags
& CFLAG_COMPLETED
)
648 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
649 "should not have CFLAG_COMPLETED set\n", q
);
653 mdb_free(slots
, sizeof (mptsas_cmd_t
) * nslots
);
658 display_deviceinfo(struct mptsas
*mp
)
660 char device_path
[PATH_MAX
];
663 if (construct_path((uintptr_t)mp
->m_dip
, device_path
) != DCMD_OK
) {
664 strcpy(device_path
, "couldn't determine device path");
668 mdb_printf("base_wwid phys "
669 " prodid devid revid ssid\n");
670 mdb_printf("-----------------------------"
671 "----------------------------------\n");
672 mdb_printf("%"PRIx64
" %2d "
673 "0x%04x 0x%04x ", mp
->un
.m_base_wwid
, mp
->m_num_phys
,
674 mp
->m_productid
, mp
->m_devid
);
675 switch (mp
->m_devid
) {
676 case MPI2_MFGPAGE_DEVID_SAS2004
:
677 mdb_printf("(SAS2004) ");
679 case MPI2_MFGPAGE_DEVID_SAS2008
:
680 mdb_printf("(SAS2008) ");
682 case MPI2_MFGPAGE_DEVID_SAS2108_1
:
683 case MPI2_MFGPAGE_DEVID_SAS2108_2
:
684 case MPI2_MFGPAGE_DEVID_SAS2108_3
:
685 mdb_printf("(SAS2108) ");
687 case MPI2_MFGPAGE_DEVID_SAS2116_1
:
688 case MPI2_MFGPAGE_DEVID_SAS2116_2
:
689 mdb_printf("(SAS2116) ");
691 case MPI2_MFGPAGE_DEVID_SSS6200
:
692 mdb_printf("(SSS6200) ");
694 case MPI2_MFGPAGE_DEVID_SAS2208_1
:
695 case MPI2_MFGPAGE_DEVID_SAS2208_2
:
696 case MPI2_MFGPAGE_DEVID_SAS2208_3
:
697 case MPI2_MFGPAGE_DEVID_SAS2208_4
:
698 case MPI2_MFGPAGE_DEVID_SAS2208_5
:
699 case MPI2_MFGPAGE_DEVID_SAS2208_6
:
700 mdb_printf("(SAS2208) ");
702 case MPI2_MFGPAGE_DEVID_SAS2308_1
:
703 case MPI2_MFGPAGE_DEVID_SAS2308_2
:
704 case MPI2_MFGPAGE_DEVID_SAS2308_3
:
705 mdb_printf("(SAS2308) ");
707 case MPI25_MFGPAGE_DEVID_SAS3004
:
708 mdb_printf("(SAS3004) ");
710 case MPI25_MFGPAGE_DEVID_SAS3008
:
711 mdb_printf("(SAS3008) ");
713 case MPI25_MFGPAGE_DEVID_SAS3108_1
:
714 case MPI25_MFGPAGE_DEVID_SAS3108_2
:
715 case MPI25_MFGPAGE_DEVID_SAS3108_5
:
716 case MPI25_MFGPAGE_DEVID_SAS3108_6
:
717 mdb_printf("(SAS3108) ");
720 mdb_printf("(SAS????) ");
723 mdb_printf("0x%02x 0x%04x\n", mp
->m_revid
, mp
->m_ssid
);
724 mdb_printf("%s\n", device_path
);
732 size_t linecnt
, linelen
;
736 if (mdb_readsym(&idx
, sizeof (uint32_t), "mptsas_dbglog_idx") == -1) {
737 mdb_warn("No debug log buffer present");
740 if (mdb_readsym(&linecnt
, sizeof (size_t), "mptsas_dbglog_linecnt")
742 mdb_warn("No debug linecnt present");
745 if (mdb_readsym(&linelen
, sizeof (size_t), "mptsas_dbglog_linelen")
747 mdb_warn("No debug linelen present");
750 logbuf
= mdb_alloc(linelen
* linecnt
, UM_SLEEP
);
752 if (mdb_readsym(logbuf
, linelen
* linecnt
, "mptsas_dbglog_bufs")
754 mdb_warn("No debug log buffer present");
759 for (i
= 0; i
< linecnt
; i
++) {
760 mdb_printf("%s\n", &logbuf
[idx
* linelen
]);
764 mdb_free(logbuf
, linelen
* linecnt
);
768 mptsas_dcmd(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
771 struct mptsas_slots
*s
;
775 uint_t verbose
= FALSE
;
776 uint_t target_info
= FALSE
;
777 uint_t slot_info
= FALSE
;
778 uint_t device_info
= FALSE
;
779 uint_t port_info
= FALSE
;
780 uint_t debug_log
= FALSE
;
783 if (!(flags
& DCMD_ADDRSPEC
)) {
784 void *mptsas_state
= NULL
;
786 if (mdb_readvar(&mptsas_state
, "mptsas_state") == -1) {
787 mdb_warn("can't read mptsas_state");
790 if (mdb_pwalk_dcmd("genunix`softstate", "mpt_sas`mptsas", argc
,
791 argv
, (uintptr_t)mptsas_state
) == -1) {
792 mdb_warn("mdb_pwalk_dcmd failed");
798 if (mdb_getopts(argc
, argv
,
799 's', MDB_OPT_SETBITS
, TRUE
, &slot_info
,
800 'd', MDB_OPT_SETBITS
, TRUE
, &device_info
,
801 't', MDB_OPT_SETBITS
, TRUE
, &target_info
,
802 'p', MDB_OPT_SETBITS
, TRUE
, &port_info
,
803 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
804 'D', MDB_OPT_SETBITS
, TRUE
, &debug_log
,
809 if (mdb_vread(&m
, sizeof (m
), addr
) == -1) {
810 mdb_warn("couldn't read mpt struct at 0x%p", addr
);
814 s
= mdb_alloc(sizeof (mptsas_slots_t
), UM_SLEEP
);
816 if (mdb_vread(s
, sizeof (mptsas_slots_t
),
817 (uintptr_t)m
.m_active
) == -1) {
818 mdb_warn("couldn't read small mptsas_slots_t at 0x%p",
820 mdb_free(s
, sizeof (mptsas_slots_t
));
824 nslots
= s
->m_n_normal
;
826 mdb_free(s
, sizeof (mptsas_slots_t
));
828 slot_size
= sizeof (mptsas_slots_t
) +
829 (sizeof (mptsas_cmd_t
*) * (nslots
-1));
831 s
= mdb_alloc(slot_size
, UM_SLEEP
);
833 if (mdb_vread(s
, slot_size
, (uintptr_t)m
.m_active
) == -1) {
834 mdb_warn("couldn't read large mptsas_slots_t at 0x%p",
836 mdb_free(s
, slot_size
);
840 /* processing completed */
842 if (((flags
& DCMD_ADDRSPEC
) && !(flags
& DCMD_LOOP
)) ||
843 (flags
& DCMD_LOOPFIRST
) || slot_info
|| device_info
||
845 if ((flags
& DCMD_LOOP
) && !(flags
& DCMD_LOOPFIRST
))
847 mdb_printf(" mptsas_t inst ncmds suspend power");
849 mdb_printf("========================================="
850 "=======================================");
854 mdb_printf("%16p %4d %5d ", addr
, m
.m_instance
, m
.m_ncmds
);
855 mdb_printf("%7d", m
.m_suspended
);
856 switch (m
.m_power_level
) {
858 mdb_printf(" ON=D0 ");
867 mdb_printf("OFF=D3 ");
870 mdb_printf("INVALD ");
877 display_targets(&m
, verbose
);
883 display_deviceinfo(&m
);
886 display_slotinfo(&m
, s
);
893 mdb_free(s
, slot_size
);
901 mdb_printf("Prints summary information about each mpt_sas instance, "
902 "including warning\nmessages when slot usage doesn't match "
903 "summary information.\n"
904 "Without the address of a \"struct mptsas\", prints every "
907 " -t[v] includes information about targets, v = be more verbose\n"
908 " -p includes information about port\n"
909 " -s includes information about mpt slots\n"
910 " -d includes information about the hardware\n"
911 " -D print the mptsas specific debug log\n");
914 static const mdb_dcmd_t dcmds
[] = {
915 { "mptsas", "?[-tpsdD]", "print mpt_sas information", mptsas_dcmd
,
916 mptsas_help
}, { NULL
}
919 static const mdb_modinfo_t modinfo
= {
920 MDB_API_VERSION
, dcmds
, NULL
923 const mdb_modinfo_t
*