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.
@@ -148,16 +148,16 @@
mdb_printf("\n");
return (0);
}
void
-mdi_info(struct mptsas m, int target)
+mdi_info(struct mptsas *mp, int target)
{
struct dev_info d;
struct mdi_phci p;
- if (mdb_vread(&d, sizeof (d), (uintptr_t)m.m_dip) == -1) {
+ if (mdb_vread(&d, sizeof (d), (uintptr_t)mp->m_dip) == -1) {
mdb_warn("couldn't read m_dip");
return;
}
if (MDI_PHCI(&d)) {
@@ -299,56 +299,34 @@
mdb_free(prev, mh.rh_obj_size);
return (rp);
}
void
-display_targets(struct mptsas *mp)
+display_targets(struct mptsas *mp, uint_t verbose)
{
mptsas_target_t *ptgt;
mptsas_smp_t *psmp;
+ int loop, comma;
mdb_printf("\n");
- mdb_printf("The SCSI target information\n");
- for (ptgt = (mptsas_target_t *)krefhash_first((uintptr_t)mp->m_targets);
- ptgt != NULL;
- ptgt = krefhash_next((uintptr_t)mp->m_targets, ptgt)) {
- mdb_printf("\n");
- mdb_printf("devhdl %x, sasaddress %"PRIx64", phymask %x,"
- "devinfo %x\n", ptgt->m_devhdl, ptgt->m_addr.mta_wwn,
- ptgt->m_addr.mta_phymask, ptgt->m_deviceinfo);
- mdb_printf("throttle %x, dr_flag %x, m_t_ncmds %x, "
- "enclosure %x, slot_num %x\n", ptgt->m_t_throttle,
- ptgt->m_dr_flag, ptgt->m_t_ncmds, ptgt->m_enclosure,
- ptgt->m_slot_num);
- }
-
- mdb_printf("\n");
- mdb_printf("The smp child information\n");
- for (psmp = (mptsas_smp_t *)krefhash_first(
- (uintptr_t)mp->m_smp_targets);
- psmp != NULL;
- psmp = krefhash_next((uintptr_t)mp->m_smp_targets, psmp)) {
- mdb_printf("\n");
- mdb_printf("devhdl %x, sasaddress %"PRIx64", phymask %x \n",
- psmp->m_devhdl, psmp->m_addr.mta_wwn,
- psmp->m_addr.mta_phymask);
- }
- mdb_printf("\n");
-#if 0
- mdb_printf("targ wwn ncmds throttle "
- "dr_flag timeout dups\n");
+ mdb_printf("slot devhdl wwn ncmds throttle "
+ "dr_flag dups\n");
mdb_printf("-------------------------------"
"--------------------------------\n");
- for (i = 0; i < MPTSAS_MAX_TARGETS; i++) {
- if (s->m_target[i].m_addr.mta_wwn ||
- s->m_target[i].m_deviceinfo) {
- mdb_printf("%4d ", i);
- if (s->m_target[i].m_addr.mta_wwn)
+ for (ptgt = (mptsas_target_t *)krefhash_first(
+ (uintptr_t)mp->m_targets);
+ ptgt != NULL;
+ ptgt = krefhash_next((uintptr_t)mp->m_targets, ptgt)) {
+ if (ptgt->m_addr.mta_wwn ||
+ ptgt->m_deviceinfo) {
+ mdb_printf("%4d ", ptgt->m_slot_num);
+ mdb_printf("%4d ", ptgt->m_devhdl);
+ if (ptgt->m_addr.mta_wwn)
mdb_printf("%"PRIx64" ",
- s->m_target[i].m_addr.mta_wwn);
- mdb_printf("%3d", s->m_target[i].m_t_ncmds);
- switch (s->m_target[i].m_t_throttle) {
+ ptgt->m_addr.mta_wwn);
+ mdb_printf("%3d", ptgt->m_t_ncmds);
+ switch (ptgt->m_t_throttle) {
case QFULL_THROTTLE:
mdb_printf(" QFULL ");
break;
case DRAIN_THROTTLE:
mdb_printf(" DRAIN ");
@@ -357,107 +335,104 @@
mdb_printf(" HOLD ");
break;
case MAX_THROTTLE:
mdb_printf(" MAX ");
break;
- case CHOKE_THROTTLE:
- mdb_printf(" CHOKE ");
- break;
default:
mdb_printf("%8d ",
- s->m_target[i].m_t_throttle);
+ ptgt->m_t_throttle);
}
- switch (s->m_target[i].m_dr_flag) {
+ switch (ptgt->m_dr_flag) {
case MPTSAS_DR_INACTIVE:
mdb_printf(" INACTIVE ");
break;
- case MPTSAS_DR_PRE_OFFLINE_TIMEOUT:
- mdb_printf(" TIMEOUT ");
- break;
- case MPTSAS_DR_PRE_OFFLINE_TIMEOUT_NO_CANCEL:
- mdb_printf("TIMEOUT_NC ");
- break;
- case MPTSAS_DR_OFFLINE_IN_PROGRESS:
- mdb_printf(" OFFLINING ");
- break;
- case MPTSAS_DR_ONLINE_IN_PROGRESS:
- mdb_printf(" ONLINING ");
+ case MPTSAS_DR_INTRANSITION:
+ mdb_printf("TRANSITION ");
break;
default:
mdb_printf(" UNKNOWN ");
break;
}
- mdb_printf("%3d/%-3d %d/%d\n",
- s->m_target[i].m_dr_timeout, m.m_offline_delay,
- s->m_target[i].m_dr_online_dups,
- s->m_target[i].m_dr_offline_dups);
+ mdb_printf("%d\n", ptgt->m_dups);
if (verbose) {
mdb_inc_indent(5);
- if ((s->m_target[i].m_deviceinfo &
+ if ((ptgt->m_deviceinfo &
MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
mdb_printf("Fanout expander: ");
- if ((s->m_target[i].m_deviceinfo &
+ if ((ptgt->m_deviceinfo &
MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER)
mdb_printf("Edge expander: ");
- if ((s->m_target[i].m_deviceinfo &
+ if ((ptgt->m_deviceinfo &
MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
MPI2_SAS_DEVICE_INFO_END_DEVICE)
mdb_printf("End device: ");
- if ((s->m_target[i].m_deviceinfo &
+ if ((ptgt->m_deviceinfo &
MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
MPI2_SAS_DEVICE_INFO_NO_DEVICE)
mdb_printf("No device ");
for (loop = 0, comma = 0;
loop < (sizeof (devinfo_array) /
sizeof (devinfo_array[0])); loop++) {
- if (s->m_target[i].m_deviceinfo &
+ if (ptgt->m_deviceinfo &
devinfo_array[loop].value) {
mdb_printf("%s%s",
(comma ? ", " : ""),
devinfo_array[loop].text);
comma++;
}
}
mdb_printf("\n");
-
- if (s->m_target[i].m_tgt_dip) {
+#if 0
+ if (ptgt->m_tgt_dip) {
+ char target_path[PATH_MAX];
*target_path = 0;
if (construct_path((uintptr_t)
- s->m_target[i].m_tgt_dip,
+ ptgt->m_tgt_dip,
target_path)
== DCMD_OK)
mdb_printf("%s\n", target_path);
}
- mdi_info(m, i);
+#endif
+ mdi_info(mp, ptgt->m_slot_num);
mdb_dec_indent(5);
}
}
}
-#endif
+
+ mdb_printf("\n");
+ mdb_printf("The smp child information\n");
+ for (psmp = (mptsas_smp_t *)krefhash_first(
+ (uintptr_t)mp->m_smp_targets);
+ psmp != NULL;
+ psmp = krefhash_next((uintptr_t)mp->m_smp_targets, psmp)) {
+ mdb_printf("\n");
+ mdb_printf("devhdl %x, sasaddress %"PRIx64", phymask %x \n",
+ psmp->m_devhdl, psmp->m_addr.mta_wwn,
+ psmp->m_addr.mta_phymask);
+ }
}
int
-display_slotinfo()
+display_slotinfo(struct mptsas *mp, struct mptsas_slots *s)
{
-#if 0
int i, nslots;
struct mptsas_cmd c, *q, *slots;
+ mptsas_target_t *ptgt;
int header_output = 0;
int rv = DCMD_OK;
int slots_in_use = 0;
int tcmds = 0;
int mismatch = 0;
int wq, dq;
int ncmds = 0;
ulong_t saved_indent;
nslots = s->m_n_normal;
-
slots = mdb_alloc(sizeof (mptsas_cmd_t) * nslots, UM_SLEEP);
for (i = 0; i < nslots; i++)
if (s->m_slot[i]) {
slots_in_use++;
@@ -470,38 +445,45 @@
tcmds++;
if (i != slots[i].cmd_slot)
mismatch++;
}
- for (q = m.m_waitq, wq = 0; q; q = c.cmd_linkp, wq++)
+ for (q = mp->m_waitq, wq = 0; q; q = c.cmd_linkp, wq++)
if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
mdb_warn("couldn't follow m_waitq");
rv = DCMD_ERR;
goto exit;
}
- for (q = m.m_doneq, dq = 0; q; q = c.cmd_linkp, dq++)
+ for (q = mp->m_doneq, dq = 0; q; q = c.cmd_linkp, dq++)
if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
mdb_warn("couldn't follow m_doneq");
rv = DCMD_ERR;
goto exit;
}
- for (i = 0; i < MPTSAS_MAX_TARGETS; i++)
- ncmds += s->m_target[i].m_t_ncmds;
+ for (ptgt = (mptsas_target_t *)krefhash_first(
+ (uintptr_t)mp->m_targets);
+ ptgt != NULL;
+ ptgt = krefhash_next((uintptr_t)mp->m_targets, ptgt)) {
+ if (ptgt->m_addr.mta_wwn ||
+ ptgt->m_deviceinfo) {
+ ncmds += ptgt->m_t_ncmds;
+ }
+ }
mdb_printf("\n");
mdb_printf(" mpt. slot mptsas_slots slot");
mdb_printf("\n");
mdb_printf("m_ncmds total"
" targ throttle m_t_ncmds targ_tot wq dq");
mdb_printf("\n");
mdb_printf("----------------------------------------------------");
mdb_printf("\n");
- mdb_printf("%7d ", m.m_ncmds);
- mdb_printf("%s", (m.m_ncmds == slots_in_use ? " " : "!="));
+ mdb_printf("%7d ", mp->m_ncmds);
+ mdb_printf("%s", (mp->m_ncmds == slots_in_use ? " " : "!="));
mdb_printf("%3d total %3d ", slots_in_use, ncmds);
mdb_printf("%s", (tcmds == ncmds ? " " : " !="));
mdb_printf("%3d %2d %2d\n", tcmds, wq, dq);
saved_indent = mdb_dec_indent(0);
@@ -530,12 +512,12 @@
(void) print_cdb(&slots[i]);
}
/* print the wait queue */
- for (q = m.m_waitq; q; q = c.cmd_linkp) {
- if (q == m.m_waitq)
+ for (q = mp->m_waitq; q; q = c.cmd_linkp) {
+ if (q == mp->m_waitq)
mdb_printf("\n");
if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
== -1) {
mdb_warn("couldn't follow m_waitq");
rv = DCMD_ERR;
@@ -547,12 +529,12 @@
print_cdb(&c);
}
/* print the done queue */
- for (q = m.m_doneq; q; q = c.cmd_linkp) {
- if (q == m.m_doneq)
+ for (q = mp->m_doneq; q; q = c.cmd_linkp) {
+ if (q == mp->m_doneq)
mdb_printf("\n");
if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
== -1) {
mdb_warn("couldn't follow m_doneq");
rv = DCMD_ERR;
@@ -564,11 +546,11 @@
print_cdb(&c);
}
mdb_inc_indent(saved_indent);
- if (m.m_ncmds != slots_in_use)
+ if (mp->m_ncmds != slots_in_use)
mdb_printf("WARNING: mpt.m_ncmds does not match the number of "
"slots in use\n");
if (tcmds != ncmds)
mdb_printf("WARNING: the total of m_target[].m_t_ncmds does "
@@ -578,11 +560,11 @@
mdb_printf("WARNING: corruption in slot table, "
"m_slot[].cmd_slot incorrect\n");
/* now check for corruptions */
- for (q = m.m_waitq; q; q = c.cmd_linkp) {
+ for (q = mp->m_waitq; q; q = c.cmd_linkp) {
for (i = 0; i < nslots; i++)
if (s->m_slot[i] == q)
mdb_printf("WARNING: m_waitq entry"
"(mptsas_cmd_t) %p is in m_slot[%i]\n",
q, i);
@@ -592,11 +574,11 @@
rv = DCMD_ERR;
goto exit;
}
}
- for (q = m.m_doneq; q; q = c.cmd_linkp) {
+ for (q = mp->m_doneq; q; q = c.cmd_linkp) {
for (i = 0; i < nslots; i++)
if (s->m_slot[i] == q)
mdb_printf("WARNING: m_doneq entry "
"(mptsas_cmd_t) %p is in m_slot[%i]\n", q, i);
@@ -620,14 +602,10 @@
}
exit:
mdb_free(slots, sizeof (mptsas_cmd_t) * nslots);
return (rv);
-#endif
- mdb_printf("\n");
- mdb_printf("The slot information is not implemented yet\n");
- return (0);
}
void
display_deviceinfo(struct mptsas *mp)
{
@@ -637,84 +615,119 @@
if (construct_path((uintptr_t)mp->m_dip, device_path) != DCMD_OK) {
strcpy(device_path, "couldn't determine device path");
}
mdb_printf("\n");
- mdb_printf("Path in device tree %s\n", device_path);
-#if 0
mdb_printf("base_wwid phys "
- "mptid prodid devid revid ssid\n");
+ " prodid devid revid ssid\n");
mdb_printf("-----------------------------"
"----------------------------------\n");
- mdb_printf("%"PRIx64" %2d %3d "
- "0x%04x 0x%04x ", m.un.m_base_wwid, m.m_num_phys, m.m_mptid,
- m.m_productid, m.m_devid);
- switch (m.m_devid) {
- case MPTSAS_909:
- mdb_printf("(909) ");
- break;
- case MPTSAS_929:
- mdb_printf("(929) ");
- break;
- case MPTSAS_919:
- mdb_printf("(919) ");
- break;
- case MPTSAS_1030:
- mdb_printf("(1030) ");
- break;
- case MPTSAS_1064:
- mdb_printf("(1064) ");
- break;
- case MPTSAS_1068:
- mdb_printf("(1068) ");
- break;
- case MPTSAS_1064E:
- mdb_printf("(1064E) ");
- break;
- case MPTSAS_1068E:
- mdb_printf("(1068E) ");
+ mdb_printf("%"PRIx64" %2d "
+ "0x%04x 0x%04x ", mp->un.m_base_wwid, mp->m_num_phys,
+ mp->m_productid, mp->m_devid);
+ switch (mp->m_devid) {
+ case MPI2_MFGPAGE_DEVID_SAS2004:
+ mdb_printf("(SAS2004) ");
+ break;
+ case MPI2_MFGPAGE_DEVID_SAS2008:
+ mdb_printf("(SAS2008) ");
+ break;
+ case MPI2_MFGPAGE_DEVID_SAS2108_1:
+ case MPI2_MFGPAGE_DEVID_SAS2108_2:
+ case MPI2_MFGPAGE_DEVID_SAS2108_3:
+ mdb_printf("(SAS2108) ");
+ break;
+ case MPI2_MFGPAGE_DEVID_SAS2116_1:
+ case MPI2_MFGPAGE_DEVID_SAS2116_2:
+ mdb_printf("(SAS2116) ");
+ break;
+ case MPI2_MFGPAGE_DEVID_SAS2208_1:
+ case MPI2_MFGPAGE_DEVID_SAS2208_2:
+ case MPI2_MFGPAGE_DEVID_SAS2208_3:
+ case MPI2_MFGPAGE_DEVID_SAS2208_4:
+ case MPI2_MFGPAGE_DEVID_SAS2208_5:
+ case MPI2_MFGPAGE_DEVID_SAS2208_6:
+#if 0
+ /* Same as 2308_1/2 ?? */
+ case MPI2_MFGPAGE_DEVID_SAS2208_7:
+ case MPI2_MFGPAGE_DEVID_SAS2208_8:
+#endif
+ mdb_printf("(SAS2208) ");
break;
default:
- mdb_printf("(?????) ");
+ mdb_printf("(SAS????) ");
break;
}
- mdb_printf("0x%02x 0x%04x\n", m.m_revid, m.m_ssid);
+ mdb_printf("0x%02x 0x%04x\n", mp->m_revid, mp->m_ssid);
mdb_printf("%s\n", device_path);
+#if 0
for (i = 0; i < MAX_MPI2_PORTS; i++) {
if (i%4 == 0)
mdb_printf("\n");
mdb_printf("%d:", i);
- switch (m.m_port_type[i]) {
+ switch (mp->m_port_type[i]) {
case MPI2_PORTFACTS_PORTTYPE_INACTIVE:
mdb_printf("inactive ",
- m.m_protocol_flags[i]);
+ mp->m_protocol_flags[i]);
break;
case MPI2_PORTFACTS_PORTTYPE_SCSI:
mdb_printf("SCSI (0x%1x) ",
- m.m_protocol_flags[i]);
+ mp->m_protocol_flags[i]);
break;
case MPI2_PORTFACTS_PORTTYPE_FC:
mdb_printf("FC (0x%1x) ",
- m.m_protocol_flags[i]);
+ mp->m_protocol_flags[i]);
break;
case MPI2_PORTFACTS_PORTTYPE_ISCSI:
mdb_printf("iSCSI (0x%1x) ",
- m.m_protocol_flags[i]);
+ mp->m_protocol_flags[i]);
break;
case MPI2_PORTFACTS_PORTTYPE_SAS:
mdb_printf("SAS (0x%1x) ",
- m.m_protocol_flags[i]);
+ mp->m_protocol_flags[i]);
break;
default:
mdb_printf("unknown ");
}
}
+ mdb_printf("\n");
#endif
+}
+
+void
+dump_debug_log(struct mptsas *mp)
+{
+ uint_t idx;
+ char *logbuf;
+ int i;
+
+ if (mdb_readsym(&idx, sizeof (uint_t),
+ "mptsas_dbglog_idx") == -1) {
+ mdb_warn("No debug log buffer present");
+ return;
+ }
+ logbuf = mdb_alloc(16*256, UM_SLEEP);
+ if (idx == 0) {
+ mdb_warn("Logging turned off");
+ return;
+ }
+
+ if (mdb_readsym(logbuf, 16*256,
+ "mptsas_dbglog_bufs") == -1) {
+ mdb_warn("No debug log buffer present");
+ return;
+ }
mdb_printf("\n");
+ idx &= 0xf;
+ for (i = 0; i < 16; i++) {
+ mdb_printf("%s\n", &logbuf[idx*256]);
+ idx = (idx+1) & 0xf;
+ }
+ mdb_free(logbuf, 16*256);
}
static int
mptsas_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
@@ -726,20 +739,22 @@
uint_t verbose = FALSE;
uint_t target_info = FALSE;
uint_t slot_info = FALSE;
uint_t device_info = FALSE;
uint_t port_info = FALSE;
+ uint_t debug_log = FALSE;
int rv = DCMD_OK;
- void *mptsas_state;
if (!(flags & DCMD_ADDRSPEC)) {
- mptsas_state = NULL;
+ void *mptsas_state = NULL;
+
if (mdb_readvar(&mptsas_state, "mptsas_state") == -1) {
mdb_warn("can't read mptsas_state");
return (DCMD_ERR);
}
- if (mdb_pwalk_dcmd("genunix`softstate", "mpt_sas`mptsas", argc,
+ if (mdb_pwalk_dcmd("genunix`softstate",
+ "mpt_sas`mptsas", argc,
argv, (uintptr_t)mptsas_state) == -1) {
mdb_warn("mdb_pwalk_dcmd failed");
return (DCMD_ERR);
}
return (DCMD_OK);
@@ -749,10 +764,11 @@
's', MDB_OPT_SETBITS, TRUE, &slot_info,
'd', MDB_OPT_SETBITS, TRUE, &device_info,
't', MDB_OPT_SETBITS, TRUE, &target_info,
'p', MDB_OPT_SETBITS, TRUE, &port_info,
'v', MDB_OPT_SETBITS, TRUE, &verbose,
+ 'D', MDB_OPT_SETBITS, TRUE, &debug_log,
NULL) != argc)
return (DCMD_USAGE);
if (mdb_vread(&m, sizeof (m), addr) == -1) {
@@ -821,20 +837,23 @@
mdb_printf("\n");
mdb_inc_indent(17);
if (target_info)
- display_targets(&m);
+ display_targets(&m, verbose);
if (port_info)
display_ports(&m);
if (device_info)
display_deviceinfo(&m);
if (slot_info)
- display_slotinfo();
+ display_slotinfo(&m, s);
+
+ if (debug_log)
+ dump_debug_log(&m);
mdb_dec_indent(17);
mdb_free(s, slot_size);
@@ -848,17 +867,19 @@
"including warning\nmessages when slot usage doesn't match "
"summary information.\n"
"Without the address of a \"struct mptsas\", prints every "
"instance.\n\n"
"Switches:\n"
- " -t includes information about targets\n"
+ " -t[v] includes information about targets, v = be more verbose\n"
" -p includes information about port\n"
- " -d includes information about the hardware\n");
+ " -s includes information about mpt slots\n"
+ " -d includes information about the hardware\n"
+ " -D print the mptsas specific debug log\n");
}
static const mdb_dcmd_t dcmds[] = {
- { "mptsas", "?[-tpd]", "print mpt_sas information", mptsas_dcmd,
+ { "mptsas", "?[-tpsdD]", "print mpt_sas information", mptsas_dcmd,
mptsas_help}, { NULL }
};
static const mdb_modinfo_t modinfo = {
MDB_API_VERSION, dcmds, NULL