19907SJaven.Wu@Sun.COM /*
29907SJaven.Wu@Sun.COM * CDDL HEADER START
39907SJaven.Wu@Sun.COM *
49907SJaven.Wu@Sun.COM * The contents of this file are subject to the terms of the
59907SJaven.Wu@Sun.COM * Common Development and Distribution License (the "License").
69907SJaven.Wu@Sun.COM * You may not use this file except in compliance with the License.
79907SJaven.Wu@Sun.COM *
89907SJaven.Wu@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99907SJaven.Wu@Sun.COM * or http://www.opensolaris.org/os/licensing.
109907SJaven.Wu@Sun.COM * See the License for the specific language governing permissions
119907SJaven.Wu@Sun.COM * and limitations under the License.
129907SJaven.Wu@Sun.COM *
139907SJaven.Wu@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
149907SJaven.Wu@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159907SJaven.Wu@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
169907SJaven.Wu@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
179907SJaven.Wu@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
189907SJaven.Wu@Sun.COM *
199907SJaven.Wu@Sun.COM * CDDL HEADER END
209907SJaven.Wu@Sun.COM */
219907SJaven.Wu@Sun.COM /*
229907SJaven.Wu@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
239907SJaven.Wu@Sun.COM * Use is subject to license terms.
249907SJaven.Wu@Sun.COM */
259907SJaven.Wu@Sun.COM
269907SJaven.Wu@Sun.COM #include <limits.h>
279907SJaven.Wu@Sun.COM #include <sys/mdb_modapi.h>
289907SJaven.Wu@Sun.COM #include <sys/sysinfo.h>
299907SJaven.Wu@Sun.COM #include <sys/sunmdi.h>
309907SJaven.Wu@Sun.COM #include <sys/scsi/scsi.h>
319907SJaven.Wu@Sun.COM
329907SJaven.Wu@Sun.COM #pragma pack(1)
339907SJaven.Wu@Sun.COM #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
349907SJaven.Wu@Sun.COM #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
359907SJaven.Wu@Sun.COM #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
369907SJaven.Wu@Sun.COM #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
379907SJaven.Wu@Sun.COM #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
389907SJaven.Wu@Sun.COM #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
39*11194SAda.Feng@Sun.COM #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
40*11194SAda.Feng@Sun.COM #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
419907SJaven.Wu@Sun.COM #pragma pack()
429907SJaven.Wu@Sun.COM
439907SJaven.Wu@Sun.COM #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
449907SJaven.Wu@Sun.COM
459907SJaven.Wu@Sun.COM struct {
469907SJaven.Wu@Sun.COM
479907SJaven.Wu@Sun.COM int value;
489907SJaven.Wu@Sun.COM char *text;
499907SJaven.Wu@Sun.COM } devinfo_array[] = {
509907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_SEP, "SEP" },
519907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE, "ATAPI device" },
529907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_LSI_DEVICE, "LSI device" },
539907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH, "direct attach" },
549907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_SSP_TARGET, "SSP tgt" },
559907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_STP_TARGET, "STP tgt" },
569907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_SMP_TARGET, "SMP tgt" },
579907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_SATA_DEVICE, "SATA dev" },
589907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_SSP_INITIATOR, "SSP init" },
599907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_STP_INITIATOR, "STP init" },
609907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_SMP_INITIATOR, "SMP init" },
619907SJaven.Wu@Sun.COM { MPI2_SAS_DEVICE_INFO_SATA_HOST, "SATA host" }
629907SJaven.Wu@Sun.COM };
639907SJaven.Wu@Sun.COM
649907SJaven.Wu@Sun.COM static int
atoi(const char * p)659907SJaven.Wu@Sun.COM atoi(const char *p)
669907SJaven.Wu@Sun.COM {
679907SJaven.Wu@Sun.COM int n;
689907SJaven.Wu@Sun.COM int c = *p++;
699907SJaven.Wu@Sun.COM
709907SJaven.Wu@Sun.COM for (n = 0; c >= '0' && c <= '9'; c = *p++) {
719907SJaven.Wu@Sun.COM n *= 10; /* two steps to avoid unnecessary overflow */
729907SJaven.Wu@Sun.COM n += '0' - c; /* accum neg to avoid surprises at MAX */
739907SJaven.Wu@Sun.COM }
749907SJaven.Wu@Sun.COM return (-n);
759907SJaven.Wu@Sun.COM }
769907SJaven.Wu@Sun.COM
779907SJaven.Wu@Sun.COM int
construct_path(uintptr_t addr,char * result)789907SJaven.Wu@Sun.COM construct_path(uintptr_t addr, char *result)
799907SJaven.Wu@Sun.COM {
809907SJaven.Wu@Sun.COM struct dev_info d;
819907SJaven.Wu@Sun.COM char devi_node[PATH_MAX];
829907SJaven.Wu@Sun.COM char devi_addr[PATH_MAX];
839907SJaven.Wu@Sun.COM
849907SJaven.Wu@Sun.COM if (mdb_vread(&d, sizeof (d), addr) == -1) {
859907SJaven.Wu@Sun.COM mdb_warn("couldn't read dev_info");
869907SJaven.Wu@Sun.COM return (DCMD_ERR);
879907SJaven.Wu@Sun.COM }
889907SJaven.Wu@Sun.COM
899907SJaven.Wu@Sun.COM if (d.devi_parent) {
909907SJaven.Wu@Sun.COM construct_path((uintptr_t)d.devi_parent, result);
919907SJaven.Wu@Sun.COM mdb_readstr(devi_node, sizeof (devi_node),
929907SJaven.Wu@Sun.COM (uintptr_t)d.devi_node_name);
939907SJaven.Wu@Sun.COM mdb_readstr(devi_addr, sizeof (devi_addr),
949907SJaven.Wu@Sun.COM (uintptr_t)d.devi_addr);
959907SJaven.Wu@Sun.COM mdb_snprintf(result+strlen(result),
969907SJaven.Wu@Sun.COM PATH_MAX-strlen(result),
979907SJaven.Wu@Sun.COM "/%s%s%s", devi_node, (*devi_addr ? "@" : ""),
989907SJaven.Wu@Sun.COM devi_addr);
999907SJaven.Wu@Sun.COM }
1009907SJaven.Wu@Sun.COM return (DCMD_OK);
1019907SJaven.Wu@Sun.COM }
1029907SJaven.Wu@Sun.COM
1039907SJaven.Wu@Sun.COM /* ARGSUSED */
1049907SJaven.Wu@Sun.COM int
mdi_info_cb(uintptr_t addr,const void * data,void * cbdata)1059907SJaven.Wu@Sun.COM mdi_info_cb(uintptr_t addr, const void *data, void *cbdata)
1069907SJaven.Wu@Sun.COM {
1079907SJaven.Wu@Sun.COM struct mdi_pathinfo pi;
1089907SJaven.Wu@Sun.COM struct mdi_client c;
1099907SJaven.Wu@Sun.COM char dev_path[PATH_MAX];
1109907SJaven.Wu@Sun.COM char string[PATH_MAX];
1119907SJaven.Wu@Sun.COM int mdi_target = 0, mdi_lun = 0;
1129907SJaven.Wu@Sun.COM int target = *(int *)cbdata;
1139907SJaven.Wu@Sun.COM
1149907SJaven.Wu@Sun.COM if (mdb_vread(&pi, sizeof (pi), addr) == -1) {
1159907SJaven.Wu@Sun.COM mdb_warn("couldn't read mdi_pathinfo");
1169907SJaven.Wu@Sun.COM return (DCMD_ERR);
1179907SJaven.Wu@Sun.COM }
1189907SJaven.Wu@Sun.COM mdb_readstr(string, sizeof (string), (uintptr_t)pi.pi_addr);
1199907SJaven.Wu@Sun.COM mdi_target = atoi(string);
1209907SJaven.Wu@Sun.COM mdi_lun = atoi(strchr(string, ',')+1);
1219907SJaven.Wu@Sun.COM if (target != mdi_target)
1229907SJaven.Wu@Sun.COM return (0);
1239907SJaven.Wu@Sun.COM
1249907SJaven.Wu@Sun.COM if (mdb_vread(&c, sizeof (c), (uintptr_t)pi.pi_client) == -1) {
1259907SJaven.Wu@Sun.COM mdb_warn("couldn't read mdi_client");
1269907SJaven.Wu@Sun.COM return (-1);
1279907SJaven.Wu@Sun.COM }
1289907SJaven.Wu@Sun.COM
1299907SJaven.Wu@Sun.COM *dev_path = NULL;
1309907SJaven.Wu@Sun.COM if (construct_path((uintptr_t)c.ct_dip, dev_path) != DCMD_OK)
1319907SJaven.Wu@Sun.COM strcpy(dev_path, "unknown");
1329907SJaven.Wu@Sun.COM
1339907SJaven.Wu@Sun.COM mdb_printf("LUN %d: %s\n", mdi_lun, dev_path);
1349907SJaven.Wu@Sun.COM mdb_printf(" dip: %p %s path", c.ct_dip,
1359907SJaven.Wu@Sun.COM (pi.pi_preferred ? "preferred" : ""));
1369907SJaven.Wu@Sun.COM switch (pi.pi_state & MDI_PATHINFO_STATE_MASK) {
1379907SJaven.Wu@Sun.COM case MDI_PATHINFO_STATE_INIT:
1389907SJaven.Wu@Sun.COM mdb_printf(" initializing");
1399907SJaven.Wu@Sun.COM break;
1409907SJaven.Wu@Sun.COM case MDI_PATHINFO_STATE_ONLINE:
1419907SJaven.Wu@Sun.COM mdb_printf(" online");
1429907SJaven.Wu@Sun.COM break;
1439907SJaven.Wu@Sun.COM case MDI_PATHINFO_STATE_STANDBY:
1449907SJaven.Wu@Sun.COM mdb_printf(" standby");
1459907SJaven.Wu@Sun.COM break;
1469907SJaven.Wu@Sun.COM case MDI_PATHINFO_STATE_FAULT:
1479907SJaven.Wu@Sun.COM mdb_printf(" fault");
1489907SJaven.Wu@Sun.COM break;
1499907SJaven.Wu@Sun.COM case MDI_PATHINFO_STATE_OFFLINE:
1509907SJaven.Wu@Sun.COM mdb_printf(" offline");
1519907SJaven.Wu@Sun.COM break;
1529907SJaven.Wu@Sun.COM default:
1539907SJaven.Wu@Sun.COM mdb_printf(" invalid state");
1549907SJaven.Wu@Sun.COM break;
1559907SJaven.Wu@Sun.COM }
1569907SJaven.Wu@Sun.COM mdb_printf("\n");
1579907SJaven.Wu@Sun.COM return (0);
1589907SJaven.Wu@Sun.COM }
1599907SJaven.Wu@Sun.COM
1609907SJaven.Wu@Sun.COM void
mdi_info(struct mptsas m,int target)1619907SJaven.Wu@Sun.COM mdi_info(struct mptsas m, int target)
1629907SJaven.Wu@Sun.COM {
1639907SJaven.Wu@Sun.COM struct dev_info d;
1649907SJaven.Wu@Sun.COM struct mdi_phci p;
1659907SJaven.Wu@Sun.COM
1669907SJaven.Wu@Sun.COM if (mdb_vread(&d, sizeof (d), (uintptr_t)m.m_dip) == -1) {
1679907SJaven.Wu@Sun.COM mdb_warn("couldn't read m_dip");
1689907SJaven.Wu@Sun.COM return;
1699907SJaven.Wu@Sun.COM }
1709907SJaven.Wu@Sun.COM
1719907SJaven.Wu@Sun.COM if (MDI_PHCI(&d)) {
1729907SJaven.Wu@Sun.COM if (mdb_vread(&p, sizeof (p), (uintptr_t)d.devi_mdi_xhci)
1739907SJaven.Wu@Sun.COM == -1) {
1749907SJaven.Wu@Sun.COM mdb_warn("couldn't read m_dip.devi_mdi_xhci");
1759907SJaven.Wu@Sun.COM return;
1769907SJaven.Wu@Sun.COM }
1779907SJaven.Wu@Sun.COM if (p.ph_path_head)
1789907SJaven.Wu@Sun.COM mdb_pwalk("mdipi_phci_list", (mdb_walk_cb_t)mdi_info_cb,
1799907SJaven.Wu@Sun.COM &target, (uintptr_t)p.ph_path_head);
1809907SJaven.Wu@Sun.COM return;
1819907SJaven.Wu@Sun.COM }
1829907SJaven.Wu@Sun.COM }
1839907SJaven.Wu@Sun.COM
1849907SJaven.Wu@Sun.COM void
print_cdb(mptsas_cmd_t * m)1859907SJaven.Wu@Sun.COM print_cdb(mptsas_cmd_t *m)
1869907SJaven.Wu@Sun.COM {
1879907SJaven.Wu@Sun.COM struct scsi_pkt pkt;
1889907SJaven.Wu@Sun.COM uchar_t cdb[512]; /* an arbitrarily large number */
1899907SJaven.Wu@Sun.COM int j;
1909907SJaven.Wu@Sun.COM
1919907SJaven.Wu@Sun.COM if (mdb_vread(&pkt, sizeof (pkt), (uintptr_t)m->cmd_pkt) == -1) {
1929907SJaven.Wu@Sun.COM mdb_warn("couldn't read cmd_pkt");
1939907SJaven.Wu@Sun.COM return;
1949907SJaven.Wu@Sun.COM }
1959907SJaven.Wu@Sun.COM
1969907SJaven.Wu@Sun.COM /*
1979907SJaven.Wu@Sun.COM * We use cmd_cdblen here because 5.10 doesn't
1989907SJaven.Wu@Sun.COM * have the cdb length in the pkt
1999907SJaven.Wu@Sun.COM */
2009907SJaven.Wu@Sun.COM if (mdb_vread(&cdb, m->cmd_cdblen, (uintptr_t)pkt.pkt_cdbp) == -1) {
2019907SJaven.Wu@Sun.COM mdb_warn("couldn't read pkt_cdbp");
2029907SJaven.Wu@Sun.COM return;
2039907SJaven.Wu@Sun.COM }
2049907SJaven.Wu@Sun.COM
2059907SJaven.Wu@Sun.COM mdb_printf("%3d,%-3d [ ",
2069907SJaven.Wu@Sun.COM pkt.pkt_address.a_target, pkt.pkt_address.a_lun);
2079907SJaven.Wu@Sun.COM
2089907SJaven.Wu@Sun.COM for (j = 0; j < m->cmd_cdblen; j++)
2099907SJaven.Wu@Sun.COM mdb_printf("%02x ", cdb[j]);
2109907SJaven.Wu@Sun.COM
2119907SJaven.Wu@Sun.COM mdb_printf("]\n");
2129907SJaven.Wu@Sun.COM }
2139907SJaven.Wu@Sun.COM
2149907SJaven.Wu@Sun.COM
2159907SJaven.Wu@Sun.COM void
display_ports(struct mptsas m)2169907SJaven.Wu@Sun.COM display_ports(struct mptsas m)
2179907SJaven.Wu@Sun.COM {
2189907SJaven.Wu@Sun.COM int i;
2199907SJaven.Wu@Sun.COM mdb_printf("\n");
2209907SJaven.Wu@Sun.COM mdb_printf("phy number and port mapping table\n");
2219907SJaven.Wu@Sun.COM for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
2229907SJaven.Wu@Sun.COM if (m.m_phy_info[i].attached_devhdl) {
2239907SJaven.Wu@Sun.COM mdb_printf("phy %x --> port %x, phymask %x,"
2249907SJaven.Wu@Sun.COM "attached_devhdl %x\n", i, m.m_phy_info[i].port_num,
2259907SJaven.Wu@Sun.COM m.m_phy_info[i].phy_mask,
2269907SJaven.Wu@Sun.COM m.m_phy_info[i].attached_devhdl);
2279907SJaven.Wu@Sun.COM }
2289907SJaven.Wu@Sun.COM }
2299907SJaven.Wu@Sun.COM mdb_printf("\n");
2309907SJaven.Wu@Sun.COM }
2319907SJaven.Wu@Sun.COM static void *
hash_traverse(mptsas_hash_table_t * hashtab,int pos,int alloc_size)2329907SJaven.Wu@Sun.COM hash_traverse(mptsas_hash_table_t *hashtab, int pos, int alloc_size)
2339907SJaven.Wu@Sun.COM {
2349907SJaven.Wu@Sun.COM mptsas_hash_node_t *this = NULL;
2359907SJaven.Wu@Sun.COM mptsas_hash_node_t h;
2369907SJaven.Wu@Sun.COM void *ret = NULL;
2379907SJaven.Wu@Sun.COM
2389907SJaven.Wu@Sun.COM if (pos == MPTSAS_HASH_FIRST) {
2399907SJaven.Wu@Sun.COM hashtab->line = 0;
2409907SJaven.Wu@Sun.COM hashtab->cur = NULL;
2419907SJaven.Wu@Sun.COM this = hashtab->head[0];
2429907SJaven.Wu@Sun.COM } else {
2439907SJaven.Wu@Sun.COM if (hashtab->cur == NULL) {
2449907SJaven.Wu@Sun.COM return (NULL);
2459907SJaven.Wu@Sun.COM } else {
2469907SJaven.Wu@Sun.COM mdb_vread(&h, sizeof (h), (uintptr_t)hashtab->cur);
2479907SJaven.Wu@Sun.COM this = h.next;
2489907SJaven.Wu@Sun.COM }
2499907SJaven.Wu@Sun.COM }
2509907SJaven.Wu@Sun.COM
2519907SJaven.Wu@Sun.COM while (this == NULL) {
2529907SJaven.Wu@Sun.COM hashtab->line++;
2539907SJaven.Wu@Sun.COM if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) {
2549907SJaven.Wu@Sun.COM /* the traverse reaches the end */
2559907SJaven.Wu@Sun.COM hashtab->cur = NULL;
2569907SJaven.Wu@Sun.COM return (NULL);
2579907SJaven.Wu@Sun.COM } else {
2589907SJaven.Wu@Sun.COM this = hashtab->head[hashtab->line];
2599907SJaven.Wu@Sun.COM }
2609907SJaven.Wu@Sun.COM }
2619907SJaven.Wu@Sun.COM hashtab->cur = this;
2629907SJaven.Wu@Sun.COM
2639907SJaven.Wu@Sun.COM if (mdb_vread(&h, sizeof (h), (uintptr_t)this) == -1) {
2649907SJaven.Wu@Sun.COM mdb_warn("couldn't read hashtab");
2659907SJaven.Wu@Sun.COM return (NULL);
2669907SJaven.Wu@Sun.COM }
2679907SJaven.Wu@Sun.COM ret = mdb_alloc(alloc_size, UM_SLEEP);
2689907SJaven.Wu@Sun.COM if (mdb_vread(ret, alloc_size, (uintptr_t)h.data) == -1) {
2699907SJaven.Wu@Sun.COM mdb_warn("couldn't read hashdata");
2709907SJaven.Wu@Sun.COM return (NULL);
2719907SJaven.Wu@Sun.COM }
2729907SJaven.Wu@Sun.COM return (ret);
2739907SJaven.Wu@Sun.COM }
2749907SJaven.Wu@Sun.COM void
display_targets(struct mptsas_slots * s)2759907SJaven.Wu@Sun.COM display_targets(struct mptsas_slots *s)
2769907SJaven.Wu@Sun.COM {
2779907SJaven.Wu@Sun.COM mptsas_target_t *ptgt;
2789907SJaven.Wu@Sun.COM mptsas_smp_t *psmp;
2799907SJaven.Wu@Sun.COM
2809907SJaven.Wu@Sun.COM mdb_printf("\n");
2819907SJaven.Wu@Sun.COM mdb_printf("The SCSI target information\n");
2829907SJaven.Wu@Sun.COM ptgt = (mptsas_target_t *)hash_traverse(&s->m_tgttbl,
2839907SJaven.Wu@Sun.COM MPTSAS_HASH_FIRST, sizeof (mptsas_target_t));
2849907SJaven.Wu@Sun.COM while (ptgt != NULL) {
2859907SJaven.Wu@Sun.COM mdb_printf("\n");
2869907SJaven.Wu@Sun.COM mdb_printf("devhdl %x, sasaddress %"PRIx64", phymask %x,"
2879907SJaven.Wu@Sun.COM "devinfo %x\n", ptgt->m_devhdl, ptgt->m_sas_wwn,
2889907SJaven.Wu@Sun.COM ptgt->m_phymask, ptgt->m_deviceinfo);
2899907SJaven.Wu@Sun.COM mdb_printf("throttle %x, dr_flag %x, m_t_ncmds %x\n",
2909907SJaven.Wu@Sun.COM ptgt->m_t_throttle, ptgt->m_dr_flag, ptgt->m_t_ncmds);
2919907SJaven.Wu@Sun.COM
2929907SJaven.Wu@Sun.COM mdb_free(ptgt, sizeof (mptsas_target_t));
2939907SJaven.Wu@Sun.COM ptgt = (mptsas_target_t *)hash_traverse(
2949907SJaven.Wu@Sun.COM &s->m_tgttbl, MPTSAS_HASH_NEXT, sizeof (mptsas_target_t));
2959907SJaven.Wu@Sun.COM }
2969907SJaven.Wu@Sun.COM mdb_printf("\n");
2979907SJaven.Wu@Sun.COM mdb_printf("The smp child information\n");
2989907SJaven.Wu@Sun.COM psmp = (mptsas_smp_t *)hash_traverse(&s->m_smptbl,
2999907SJaven.Wu@Sun.COM MPTSAS_HASH_FIRST, sizeof (mptsas_smp_t));
3009907SJaven.Wu@Sun.COM while (psmp != NULL) {
3019907SJaven.Wu@Sun.COM mdb_printf("\n");
3029907SJaven.Wu@Sun.COM mdb_printf("devhdl %x, sasaddress %"PRIx64", phymask %x \n",
3039907SJaven.Wu@Sun.COM psmp->m_devhdl, psmp->m_sasaddr, psmp->m_phymask);
3049907SJaven.Wu@Sun.COM
3059907SJaven.Wu@Sun.COM mdb_free(psmp, sizeof (mptsas_smp_t));
3069907SJaven.Wu@Sun.COM psmp = (mptsas_smp_t *)hash_traverse(
3079907SJaven.Wu@Sun.COM &s->m_smptbl, MPTSAS_HASH_NEXT, sizeof (mptsas_smp_t));
3089907SJaven.Wu@Sun.COM }
3099907SJaven.Wu@Sun.COM mdb_printf("\n");
3109907SJaven.Wu@Sun.COM #if 0
3119907SJaven.Wu@Sun.COM mdb_printf("targ wwn ncmds throttle "
3129907SJaven.Wu@Sun.COM "dr_flag timeout dups\n");
3139907SJaven.Wu@Sun.COM mdb_printf("-------------------------------"
3149907SJaven.Wu@Sun.COM "--------------------------------\n");
3159907SJaven.Wu@Sun.COM for (i = 0; i < MPTSAS_MAX_TARGETS; i++) {
3169907SJaven.Wu@Sun.COM if (s->m_target[i].m_sas_wwn || s->m_target[i].m_deviceinfo) {
3179907SJaven.Wu@Sun.COM mdb_printf("%4d ", i);
3189907SJaven.Wu@Sun.COM if (s->m_target[i].m_sas_wwn)
3199907SJaven.Wu@Sun.COM mdb_printf("%"PRIx64" ",
3209907SJaven.Wu@Sun.COM s->m_target[i].m_sas_wwn);
3219907SJaven.Wu@Sun.COM mdb_printf("%3d", s->m_target[i].m_t_ncmds);
3229907SJaven.Wu@Sun.COM switch (s->m_target[i].m_t_throttle) {
3239907SJaven.Wu@Sun.COM case QFULL_THROTTLE:
3249907SJaven.Wu@Sun.COM mdb_printf(" QFULL ");
3259907SJaven.Wu@Sun.COM break;
3269907SJaven.Wu@Sun.COM case DRAIN_THROTTLE:
3279907SJaven.Wu@Sun.COM mdb_printf(" DRAIN ");
3289907SJaven.Wu@Sun.COM break;
3299907SJaven.Wu@Sun.COM case HOLD_THROTTLE:
3309907SJaven.Wu@Sun.COM mdb_printf(" HOLD ");
3319907SJaven.Wu@Sun.COM break;
3329907SJaven.Wu@Sun.COM case MAX_THROTTLE:
3339907SJaven.Wu@Sun.COM mdb_printf(" MAX ");
3349907SJaven.Wu@Sun.COM break;
3359907SJaven.Wu@Sun.COM case CHOKE_THROTTLE:
3369907SJaven.Wu@Sun.COM mdb_printf(" CHOKE ");
3379907SJaven.Wu@Sun.COM break;
3389907SJaven.Wu@Sun.COM default:
3399907SJaven.Wu@Sun.COM mdb_printf("%8d ",
3409907SJaven.Wu@Sun.COM s->m_target[i].m_t_throttle);
3419907SJaven.Wu@Sun.COM }
3429907SJaven.Wu@Sun.COM switch (s->m_target[i].m_dr_flag) {
3439907SJaven.Wu@Sun.COM case MPTSAS_DR_INACTIVE:
3449907SJaven.Wu@Sun.COM mdb_printf(" INACTIVE ");
3459907SJaven.Wu@Sun.COM break;
3469907SJaven.Wu@Sun.COM case MPTSAS_DR_PRE_OFFLINE_TIMEOUT:
3479907SJaven.Wu@Sun.COM mdb_printf(" TIMEOUT ");
3489907SJaven.Wu@Sun.COM break;
3499907SJaven.Wu@Sun.COM case MPTSAS_DR_PRE_OFFLINE_TIMEOUT_NO_CANCEL:
3509907SJaven.Wu@Sun.COM mdb_printf("TIMEOUT_NC ");
3519907SJaven.Wu@Sun.COM break;
3529907SJaven.Wu@Sun.COM case MPTSAS_DR_OFFLINE_IN_PROGRESS:
3539907SJaven.Wu@Sun.COM mdb_printf(" OFFLINING ");
3549907SJaven.Wu@Sun.COM break;
3559907SJaven.Wu@Sun.COM case MPTSAS_DR_ONLINE_IN_PROGRESS:
3569907SJaven.Wu@Sun.COM mdb_printf(" ONLINING ");
3579907SJaven.Wu@Sun.COM break;
3589907SJaven.Wu@Sun.COM default:
3599907SJaven.Wu@Sun.COM mdb_printf(" UNKNOWN ");
3609907SJaven.Wu@Sun.COM break;
3619907SJaven.Wu@Sun.COM }
3629907SJaven.Wu@Sun.COM mdb_printf("%3d/%-3d %d/%d\n",
3639907SJaven.Wu@Sun.COM s->m_target[i].m_dr_timeout, m.m_offline_delay,
3649907SJaven.Wu@Sun.COM s->m_target[i].m_dr_online_dups,
3659907SJaven.Wu@Sun.COM s->m_target[i].m_dr_offline_dups);
3669907SJaven.Wu@Sun.COM
3679907SJaven.Wu@Sun.COM if (verbose) {
3689907SJaven.Wu@Sun.COM mdb_inc_indent(5);
3699907SJaven.Wu@Sun.COM if ((s->m_target[i].m_deviceinfo &
3709907SJaven.Wu@Sun.COM MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
3719907SJaven.Wu@Sun.COM MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
3729907SJaven.Wu@Sun.COM mdb_printf("Fanout expander: ");
3739907SJaven.Wu@Sun.COM if ((s->m_target[i].m_deviceinfo &
3749907SJaven.Wu@Sun.COM MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
3759907SJaven.Wu@Sun.COM MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER)
3769907SJaven.Wu@Sun.COM mdb_printf("Edge expander: ");
3779907SJaven.Wu@Sun.COM if ((s->m_target[i].m_deviceinfo &
3789907SJaven.Wu@Sun.COM MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
3799907SJaven.Wu@Sun.COM MPI2_SAS_DEVICE_INFO_END_DEVICE)
3809907SJaven.Wu@Sun.COM mdb_printf("End device: ");
3819907SJaven.Wu@Sun.COM if ((s->m_target[i].m_deviceinfo &
3829907SJaven.Wu@Sun.COM MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
3839907SJaven.Wu@Sun.COM MPI2_SAS_DEVICE_INFO_NO_DEVICE)
3849907SJaven.Wu@Sun.COM mdb_printf("No device ");
3859907SJaven.Wu@Sun.COM
3869907SJaven.Wu@Sun.COM for (loop = 0, comma = 0;
3879907SJaven.Wu@Sun.COM loop < (sizeof (devinfo_array) /
3889907SJaven.Wu@Sun.COM sizeof (devinfo_array[0])); loop++) {
3899907SJaven.Wu@Sun.COM if (s->m_target[i].m_deviceinfo &
3909907SJaven.Wu@Sun.COM devinfo_array[loop].value) {
3919907SJaven.Wu@Sun.COM mdb_printf("%s%s",
3929907SJaven.Wu@Sun.COM (comma ? ", " : ""),
3939907SJaven.Wu@Sun.COM devinfo_array[loop].text);
3949907SJaven.Wu@Sun.COM comma++;
3959907SJaven.Wu@Sun.COM }
3969907SJaven.Wu@Sun.COM }
3979907SJaven.Wu@Sun.COM mdb_printf("\n");
3989907SJaven.Wu@Sun.COM
3999907SJaven.Wu@Sun.COM if (s->m_target[i].m_tgt_dip) {
4009907SJaven.Wu@Sun.COM *target_path = 0;
4019907SJaven.Wu@Sun.COM if (construct_path((uintptr_t)
4029907SJaven.Wu@Sun.COM s->m_target[i].m_tgt_dip,
4039907SJaven.Wu@Sun.COM target_path)
4049907SJaven.Wu@Sun.COM == DCMD_OK)
4059907SJaven.Wu@Sun.COM mdb_printf("%s\n", target_path);
4069907SJaven.Wu@Sun.COM }
4079907SJaven.Wu@Sun.COM mdi_info(m, i);
4089907SJaven.Wu@Sun.COM mdb_dec_indent(5);
4099907SJaven.Wu@Sun.COM }
4109907SJaven.Wu@Sun.COM }
4119907SJaven.Wu@Sun.COM }
4129907SJaven.Wu@Sun.COM #endif
4139907SJaven.Wu@Sun.COM }
4149907SJaven.Wu@Sun.COM
4159907SJaven.Wu@Sun.COM int
display_slotinfo()4169907SJaven.Wu@Sun.COM display_slotinfo()
4179907SJaven.Wu@Sun.COM {
4189907SJaven.Wu@Sun.COM #if 0
4199907SJaven.Wu@Sun.COM int i, nslots;
4209907SJaven.Wu@Sun.COM struct mptsas_cmd c, *q, *slots;
4219907SJaven.Wu@Sun.COM int header_output = 0;
4229907SJaven.Wu@Sun.COM int rv = DCMD_OK;
4239907SJaven.Wu@Sun.COM int slots_in_use = 0;
4249907SJaven.Wu@Sun.COM int tcmds = 0;
4259907SJaven.Wu@Sun.COM int mismatch = 0;
4269907SJaven.Wu@Sun.COM int wq, dq;
4279907SJaven.Wu@Sun.COM int ncmds = 0;
4289907SJaven.Wu@Sun.COM ulong_t saved_indent;
4299907SJaven.Wu@Sun.COM
4309907SJaven.Wu@Sun.COM nslots = s->m_n_slots;
4319907SJaven.Wu@Sun.COM
4329907SJaven.Wu@Sun.COM slots = mdb_alloc(sizeof (mptsas_cmd_t) * nslots, UM_SLEEP);
4339907SJaven.Wu@Sun.COM
4349907SJaven.Wu@Sun.COM for (i = 0; i < nslots; i++)
4359907SJaven.Wu@Sun.COM if (s->m_slot[i]) {
4369907SJaven.Wu@Sun.COM slots_in_use++;
4379907SJaven.Wu@Sun.COM if (mdb_vread(&slots[i], sizeof (mptsas_cmd_t),
4389907SJaven.Wu@Sun.COM (uintptr_t)s->m_slot[i]) == -1) {
4399907SJaven.Wu@Sun.COM mdb_warn("couldn't read slot");
4409907SJaven.Wu@Sun.COM s->m_slot[i] = NULL;
4419907SJaven.Wu@Sun.COM }
4429907SJaven.Wu@Sun.COM if ((slots[i].cmd_flags & CFLAG_CMDIOC) == 0)
4439907SJaven.Wu@Sun.COM tcmds++;
4449907SJaven.Wu@Sun.COM if (i != slots[i].cmd_slot)
4459907SJaven.Wu@Sun.COM mismatch++;
4469907SJaven.Wu@Sun.COM }
4479907SJaven.Wu@Sun.COM
4489907SJaven.Wu@Sun.COM for (q = m.m_waitq, wq = 0; q; q = c.cmd_linkp, wq++)
4499907SJaven.Wu@Sun.COM if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
4509907SJaven.Wu@Sun.COM mdb_warn("couldn't follow m_waitq");
4519907SJaven.Wu@Sun.COM rv = DCMD_ERR;
4529907SJaven.Wu@Sun.COM goto exit;
4539907SJaven.Wu@Sun.COM }
4549907SJaven.Wu@Sun.COM
4559907SJaven.Wu@Sun.COM for (q = m.m_doneq, dq = 0; q; q = c.cmd_linkp, dq++)
4569907SJaven.Wu@Sun.COM if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
4579907SJaven.Wu@Sun.COM mdb_warn("couldn't follow m_doneq");
4589907SJaven.Wu@Sun.COM rv = DCMD_ERR;
4599907SJaven.Wu@Sun.COM goto exit;
4609907SJaven.Wu@Sun.COM }
4619907SJaven.Wu@Sun.COM
4629907SJaven.Wu@Sun.COM for (i = 0; i < MPTSAS_MAX_TARGETS; i++)
4639907SJaven.Wu@Sun.COM ncmds += s->m_target[i].m_t_ncmds;
4649907SJaven.Wu@Sun.COM
4659907SJaven.Wu@Sun.COM mdb_printf("\n");
4669907SJaven.Wu@Sun.COM mdb_printf(" mpt. slot mptsas_slots slot");
4679907SJaven.Wu@Sun.COM mdb_printf("\n");
4689907SJaven.Wu@Sun.COM mdb_printf("m_ncmds total"
4699907SJaven.Wu@Sun.COM " targ throttle m_t_ncmds targ_tot wq dq");
4709907SJaven.Wu@Sun.COM mdb_printf("\n");
4719907SJaven.Wu@Sun.COM mdb_printf("----------------------------------------------------");
4729907SJaven.Wu@Sun.COM mdb_printf("\n");
4739907SJaven.Wu@Sun.COM
4749907SJaven.Wu@Sun.COM mdb_printf("%7d ", m.m_ncmds);
4759907SJaven.Wu@Sun.COM mdb_printf("%s", (m.m_ncmds == slots_in_use ? " " : "!="));
4769907SJaven.Wu@Sun.COM mdb_printf("%3d total %3d ", slots_in_use, ncmds);
4779907SJaven.Wu@Sun.COM mdb_printf("%s", (tcmds == ncmds ? " " : " !="));
4789907SJaven.Wu@Sun.COM mdb_printf("%3d %2d %2d\n", tcmds, wq, dq);
4799907SJaven.Wu@Sun.COM
4809907SJaven.Wu@Sun.COM saved_indent = mdb_dec_indent(0);
4819907SJaven.Wu@Sun.COM mdb_dec_indent(saved_indent);
4829907SJaven.Wu@Sun.COM
4839907SJaven.Wu@Sun.COM for (i = 0; i < s->m_n_slots; i++)
4849907SJaven.Wu@Sun.COM if (s->m_slot[i]) {
4859907SJaven.Wu@Sun.COM if (!header_output) {
4869907SJaven.Wu@Sun.COM mdb_printf("\n");
4879907SJaven.Wu@Sun.COM mdb_printf("mptsas_cmd slot cmd_slot "
4889907SJaven.Wu@Sun.COM "cmd_flags cmd_pkt_flags scsi_pkt "
4899907SJaven.Wu@Sun.COM " targ,lun [ pkt_cdbp ...\n");
4909907SJaven.Wu@Sun.COM mdb_printf("-------------------------------"
4919907SJaven.Wu@Sun.COM "--------------------------------------"
4929907SJaven.Wu@Sun.COM "--------------------------------------"
4939907SJaven.Wu@Sun.COM "------\n");
4949907SJaven.Wu@Sun.COM header_output = 1;
4959907SJaven.Wu@Sun.COM }
4969907SJaven.Wu@Sun.COM mdb_printf("%16p %4d %s %4d %8x %8x %16p ",
4979907SJaven.Wu@Sun.COM s->m_slot[i], i,
4989907SJaven.Wu@Sun.COM (i == slots[i].cmd_slot?" ":"BAD"),
4999907SJaven.Wu@Sun.COM slots[i].cmd_slot,
5009907SJaven.Wu@Sun.COM slots[i].cmd_flags,
5019907SJaven.Wu@Sun.COM slots[i].cmd_pkt_flags,
5029907SJaven.Wu@Sun.COM slots[i].cmd_pkt);
5039907SJaven.Wu@Sun.COM (void) print_cdb(&slots[i]);
5049907SJaven.Wu@Sun.COM }
5059907SJaven.Wu@Sun.COM
5069907SJaven.Wu@Sun.COM /* print the wait queue */
5079907SJaven.Wu@Sun.COM
5089907SJaven.Wu@Sun.COM for (q = m.m_waitq; q; q = c.cmd_linkp) {
5099907SJaven.Wu@Sun.COM if (q == m.m_waitq)
5109907SJaven.Wu@Sun.COM mdb_printf("\n");
5119907SJaven.Wu@Sun.COM if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
5129907SJaven.Wu@Sun.COM == -1) {
5139907SJaven.Wu@Sun.COM mdb_warn("couldn't follow m_waitq");
5149907SJaven.Wu@Sun.COM rv = DCMD_ERR;
5159907SJaven.Wu@Sun.COM goto exit;
5169907SJaven.Wu@Sun.COM }
5179907SJaven.Wu@Sun.COM mdb_printf("%16p wait n/a %4d %8x %8x %16p ",
5189907SJaven.Wu@Sun.COM q, c.cmd_slot, c.cmd_flags, c.cmd_pkt_flags,
5199907SJaven.Wu@Sun.COM c.cmd_pkt);
5209907SJaven.Wu@Sun.COM print_cdb(&c);
5219907SJaven.Wu@Sun.COM }
5229907SJaven.Wu@Sun.COM
5239907SJaven.Wu@Sun.COM /* print the done queue */
5249907SJaven.Wu@Sun.COM
5259907SJaven.Wu@Sun.COM for (q = m.m_doneq; q; q = c.cmd_linkp) {
5269907SJaven.Wu@Sun.COM if (q == m.m_doneq)
5279907SJaven.Wu@Sun.COM mdb_printf("\n");
5289907SJaven.Wu@Sun.COM if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
5299907SJaven.Wu@Sun.COM == -1) {
5309907SJaven.Wu@Sun.COM mdb_warn("couldn't follow m_doneq");
5319907SJaven.Wu@Sun.COM rv = DCMD_ERR;
5329907SJaven.Wu@Sun.COM goto exit;
5339907SJaven.Wu@Sun.COM }
5349907SJaven.Wu@Sun.COM mdb_printf("%16p done n/a %4d %8x %8x %16p ",
5359907SJaven.Wu@Sun.COM q, c.cmd_slot, c.cmd_flags, c.cmd_pkt_flags,
5369907SJaven.Wu@Sun.COM c.cmd_pkt);
5379907SJaven.Wu@Sun.COM print_cdb(&c);
5389907SJaven.Wu@Sun.COM }
5399907SJaven.Wu@Sun.COM
5409907SJaven.Wu@Sun.COM mdb_inc_indent(saved_indent);
5419907SJaven.Wu@Sun.COM
5429907SJaven.Wu@Sun.COM if (m.m_ncmds != slots_in_use)
5439907SJaven.Wu@Sun.COM mdb_printf("WARNING: mpt.m_ncmds does not match the number of "
5449907SJaven.Wu@Sun.COM "slots in use\n");
5459907SJaven.Wu@Sun.COM
5469907SJaven.Wu@Sun.COM if (tcmds != ncmds)
5479907SJaven.Wu@Sun.COM mdb_printf("WARNING: the total of m_target[].m_t_ncmds does "
5489907SJaven.Wu@Sun.COM "not match the slots in use\n");
5499907SJaven.Wu@Sun.COM
5509907SJaven.Wu@Sun.COM if (mismatch)
5519907SJaven.Wu@Sun.COM mdb_printf("WARNING: corruption in slot table, "
5529907SJaven.Wu@Sun.COM "m_slot[].cmd_slot incorrect\n");
5539907SJaven.Wu@Sun.COM
5549907SJaven.Wu@Sun.COM /* now check for corruptions */
5559907SJaven.Wu@Sun.COM
5569907SJaven.Wu@Sun.COM for (q = m.m_waitq; q; q = c.cmd_linkp) {
5579907SJaven.Wu@Sun.COM for (i = 0; i < nslots; i++)
5589907SJaven.Wu@Sun.COM if (s->m_slot[i] == q)
5599907SJaven.Wu@Sun.COM mdb_printf("WARNING: m_waitq entry"
5609907SJaven.Wu@Sun.COM "(mptsas_cmd_t) %p is in m_slot[%i]\n",
5619907SJaven.Wu@Sun.COM q, i);
5629907SJaven.Wu@Sun.COM
5639907SJaven.Wu@Sun.COM if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
5649907SJaven.Wu@Sun.COM mdb_warn("couldn't follow m_waitq");
5659907SJaven.Wu@Sun.COM rv = DCMD_ERR;
5669907SJaven.Wu@Sun.COM goto exit;
5679907SJaven.Wu@Sun.COM }
5689907SJaven.Wu@Sun.COM }
5699907SJaven.Wu@Sun.COM
5709907SJaven.Wu@Sun.COM for (q = m.m_doneq; q; q = c.cmd_linkp) {
5719907SJaven.Wu@Sun.COM for (i = 0; i < nslots; i++)
5729907SJaven.Wu@Sun.COM if (s->m_slot[i] == q)
5739907SJaven.Wu@Sun.COM mdb_printf("WARNING: m_doneq entry "
5749907SJaven.Wu@Sun.COM "(mptsas_cmd_t) %p is in m_slot[%i]\n", q, i);
5759907SJaven.Wu@Sun.COM
5769907SJaven.Wu@Sun.COM if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
5779907SJaven.Wu@Sun.COM mdb_warn("couldn't follow m_doneq");
5789907SJaven.Wu@Sun.COM rv = DCMD_ERR;
5799907SJaven.Wu@Sun.COM goto exit;
5809907SJaven.Wu@Sun.COM }
5819907SJaven.Wu@Sun.COM if ((c.cmd_flags & CFLAG_FINISHED) == 0)
5829907SJaven.Wu@Sun.COM mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
5839907SJaven.Wu@Sun.COM "should have CFLAG_FINISHED set\n", q);
5849907SJaven.Wu@Sun.COM if (c.cmd_flags & CFLAG_IN_TRANSPORT)
5859907SJaven.Wu@Sun.COM mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
5869907SJaven.Wu@Sun.COM "should not have CFLAG_IN_TRANSPORT set\n", q);
5879907SJaven.Wu@Sun.COM if (c.cmd_flags & CFLAG_CMDARQ)
5889907SJaven.Wu@Sun.COM mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
5899907SJaven.Wu@Sun.COM "should not have CFLAG_CMDARQ set\n", q);
5909907SJaven.Wu@Sun.COM if (c.cmd_flags & CFLAG_COMPLETED)
5919907SJaven.Wu@Sun.COM mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
5929907SJaven.Wu@Sun.COM "should not have CFLAG_COMPLETED set\n", q);
5939907SJaven.Wu@Sun.COM }
5949907SJaven.Wu@Sun.COM
5959907SJaven.Wu@Sun.COM exit:
5969907SJaven.Wu@Sun.COM mdb_free(slots, sizeof (mptsas_cmd_t) * nslots);
5979907SJaven.Wu@Sun.COM return (rv);
5989907SJaven.Wu@Sun.COM #endif
5999907SJaven.Wu@Sun.COM mdb_printf("\n");
6009907SJaven.Wu@Sun.COM mdb_printf("The slot information is not implemented yet\n");
6019907SJaven.Wu@Sun.COM return (0);
6029907SJaven.Wu@Sun.COM }
6039907SJaven.Wu@Sun.COM
6049907SJaven.Wu@Sun.COM void
display_deviceinfo(struct mptsas m)6059907SJaven.Wu@Sun.COM display_deviceinfo(struct mptsas m)
6069907SJaven.Wu@Sun.COM {
6079907SJaven.Wu@Sun.COM char device_path[PATH_MAX];
6089907SJaven.Wu@Sun.COM
6099907SJaven.Wu@Sun.COM *device_path = 0;
6109907SJaven.Wu@Sun.COM if (construct_path((uintptr_t)m.m_dip, device_path) != DCMD_OK) {
6119907SJaven.Wu@Sun.COM strcpy(device_path, "couldn't determine device path");
6129907SJaven.Wu@Sun.COM }
6139907SJaven.Wu@Sun.COM
6149907SJaven.Wu@Sun.COM mdb_printf("\n");
6159907SJaven.Wu@Sun.COM mdb_printf("Path in device tree %s\n", device_path);
6169907SJaven.Wu@Sun.COM #if 0
6179907SJaven.Wu@Sun.COM mdb_printf("base_wwid phys "
6189907SJaven.Wu@Sun.COM "mptid prodid devid revid ssid\n");
6199907SJaven.Wu@Sun.COM mdb_printf("-----------------------------"
6209907SJaven.Wu@Sun.COM "----------------------------------\n");
6219907SJaven.Wu@Sun.COM mdb_printf("%"PRIx64" %2d %3d "
6229907SJaven.Wu@Sun.COM "0x%04x 0x%04x ", m.un.m_base_wwid, m.m_num_phys, m.m_mptid,
6239907SJaven.Wu@Sun.COM m.m_productid, m.m_devid);
6249907SJaven.Wu@Sun.COM switch (m.m_devid) {
6259907SJaven.Wu@Sun.COM case MPTSAS_909:
6269907SJaven.Wu@Sun.COM mdb_printf("(909) ");
6279907SJaven.Wu@Sun.COM break;
6289907SJaven.Wu@Sun.COM case MPTSAS_929:
6299907SJaven.Wu@Sun.COM mdb_printf("(929) ");
6309907SJaven.Wu@Sun.COM break;
6319907SJaven.Wu@Sun.COM case MPTSAS_919:
6329907SJaven.Wu@Sun.COM mdb_printf("(919) ");
6339907SJaven.Wu@Sun.COM break;
6349907SJaven.Wu@Sun.COM case MPTSAS_1030:
6359907SJaven.Wu@Sun.COM mdb_printf("(1030) ");
6369907SJaven.Wu@Sun.COM break;
6379907SJaven.Wu@Sun.COM case MPTSAS_1064:
6389907SJaven.Wu@Sun.COM mdb_printf("(1064) ");
6399907SJaven.Wu@Sun.COM break;
6409907SJaven.Wu@Sun.COM case MPTSAS_1068:
6419907SJaven.Wu@Sun.COM mdb_printf("(1068) ");
6429907SJaven.Wu@Sun.COM break;
6439907SJaven.Wu@Sun.COM case MPTSAS_1064E:
6449907SJaven.Wu@Sun.COM mdb_printf("(1064E) ");
6459907SJaven.Wu@Sun.COM break;
6469907SJaven.Wu@Sun.COM case MPTSAS_1068E:
6479907SJaven.Wu@Sun.COM mdb_printf("(1068E) ");
6489907SJaven.Wu@Sun.COM break;
6499907SJaven.Wu@Sun.COM default:
6509907SJaven.Wu@Sun.COM mdb_printf("(?????) ");
6519907SJaven.Wu@Sun.COM break;
6529907SJaven.Wu@Sun.COM }
6539907SJaven.Wu@Sun.COM mdb_printf("0x%02x 0x%04x\n", m.m_revid, m.m_ssid);
6549907SJaven.Wu@Sun.COM mdb_printf("%s\n", device_path);
6559907SJaven.Wu@Sun.COM
6569907SJaven.Wu@Sun.COM for (i = 0; i < MAX_MPI2_PORTS; i++) {
6579907SJaven.Wu@Sun.COM if (i%4 == 0)
6589907SJaven.Wu@Sun.COM mdb_printf("\n");
6599907SJaven.Wu@Sun.COM
6609907SJaven.Wu@Sun.COM mdb_printf("%d:", i);
6619907SJaven.Wu@Sun.COM
6629907SJaven.Wu@Sun.COM switch (m.m_port_type[i]) {
6639907SJaven.Wu@Sun.COM case MPI2_PORTFACTS_PORTTYPE_INACTIVE:
6649907SJaven.Wu@Sun.COM mdb_printf("inactive ",
6659907SJaven.Wu@Sun.COM m.m_protocol_flags[i]);
6669907SJaven.Wu@Sun.COM break;
6679907SJaven.Wu@Sun.COM case MPI2_PORTFACTS_PORTTYPE_SCSI:
6689907SJaven.Wu@Sun.COM mdb_printf("SCSI (0x%1x) ",
6699907SJaven.Wu@Sun.COM m.m_protocol_flags[i]);
6709907SJaven.Wu@Sun.COM break;
6719907SJaven.Wu@Sun.COM case MPI2_PORTFACTS_PORTTYPE_FC:
6729907SJaven.Wu@Sun.COM mdb_printf("FC (0x%1x) ",
6739907SJaven.Wu@Sun.COM m.m_protocol_flags[i]);
6749907SJaven.Wu@Sun.COM break;
6759907SJaven.Wu@Sun.COM case MPI2_PORTFACTS_PORTTYPE_ISCSI:
6769907SJaven.Wu@Sun.COM mdb_printf("iSCSI (0x%1x) ",
6779907SJaven.Wu@Sun.COM m.m_protocol_flags[i]);
6789907SJaven.Wu@Sun.COM break;
6799907SJaven.Wu@Sun.COM case MPI2_PORTFACTS_PORTTYPE_SAS:
6809907SJaven.Wu@Sun.COM mdb_printf("SAS (0x%1x) ",
6819907SJaven.Wu@Sun.COM m.m_protocol_flags[i]);
6829907SJaven.Wu@Sun.COM break;
6839907SJaven.Wu@Sun.COM default:
6849907SJaven.Wu@Sun.COM mdb_printf("unknown ");
6859907SJaven.Wu@Sun.COM }
6869907SJaven.Wu@Sun.COM }
6879907SJaven.Wu@Sun.COM #endif
6889907SJaven.Wu@Sun.COM mdb_printf("\n");
6899907SJaven.Wu@Sun.COM }
6909907SJaven.Wu@Sun.COM
6919907SJaven.Wu@Sun.COM static int
mptsas_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6929907SJaven.Wu@Sun.COM mptsas_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6939907SJaven.Wu@Sun.COM {
6949907SJaven.Wu@Sun.COM struct mptsas m;
6959907SJaven.Wu@Sun.COM struct mptsas_slots *s;
6969907SJaven.Wu@Sun.COM
6979907SJaven.Wu@Sun.COM int nslots;
6989907SJaven.Wu@Sun.COM int slot_size = 0;
6999907SJaven.Wu@Sun.COM uint_t verbose = FALSE;
7009907SJaven.Wu@Sun.COM uint_t target_info = FALSE;
7019907SJaven.Wu@Sun.COM uint_t slot_info = FALSE;
7029907SJaven.Wu@Sun.COM uint_t device_info = FALSE;
7039907SJaven.Wu@Sun.COM uint_t port_info = FALSE;
7049907SJaven.Wu@Sun.COM int rv = DCMD_OK;
7059907SJaven.Wu@Sun.COM void *mptsas_state;
7069907SJaven.Wu@Sun.COM
7079907SJaven.Wu@Sun.COM if (!(flags & DCMD_ADDRSPEC)) {
7089907SJaven.Wu@Sun.COM mptsas_state = NULL;
7099907SJaven.Wu@Sun.COM if (mdb_readvar(&mptsas_state, "mptsas_state") == -1) {
7109907SJaven.Wu@Sun.COM mdb_warn("can't read mptsas_state");
7119907SJaven.Wu@Sun.COM return (DCMD_ERR);
7129907SJaven.Wu@Sun.COM }
7139907SJaven.Wu@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "mpt_sas`mptsas", argc,
7149907SJaven.Wu@Sun.COM argv, (uintptr_t)mptsas_state) == -1) {
7159907SJaven.Wu@Sun.COM mdb_warn("mdb_pwalk_dcmd failed");
7169907SJaven.Wu@Sun.COM return (DCMD_ERR);
7179907SJaven.Wu@Sun.COM }
7189907SJaven.Wu@Sun.COM return (DCMD_OK);
7199907SJaven.Wu@Sun.COM }
7209907SJaven.Wu@Sun.COM
7219907SJaven.Wu@Sun.COM if (mdb_getopts(argc, argv,
7229907SJaven.Wu@Sun.COM 's', MDB_OPT_SETBITS, TRUE, &slot_info,
7239907SJaven.Wu@Sun.COM 'd', MDB_OPT_SETBITS, TRUE, &device_info,
7249907SJaven.Wu@Sun.COM 't', MDB_OPT_SETBITS, TRUE, &target_info,
7259907SJaven.Wu@Sun.COM 'p', MDB_OPT_SETBITS, TRUE, &port_info,
7269907SJaven.Wu@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose,
7279907SJaven.Wu@Sun.COM NULL) != argc)
7289907SJaven.Wu@Sun.COM return (DCMD_USAGE);
7299907SJaven.Wu@Sun.COM
7309907SJaven.Wu@Sun.COM
7319907SJaven.Wu@Sun.COM if (mdb_vread(&m, sizeof (m), addr) == -1) {
7329907SJaven.Wu@Sun.COM mdb_warn("couldn't read mpt struct at 0x%p", addr);
7339907SJaven.Wu@Sun.COM return (DCMD_ERR);
7349907SJaven.Wu@Sun.COM }
7359907SJaven.Wu@Sun.COM
7369907SJaven.Wu@Sun.COM s = mdb_alloc(sizeof (mptsas_slots_t), UM_SLEEP);
7379907SJaven.Wu@Sun.COM
7389907SJaven.Wu@Sun.COM if (mdb_vread(s, sizeof (mptsas_slots_t),
7399907SJaven.Wu@Sun.COM (uintptr_t)m.m_active) == -1) {
7409907SJaven.Wu@Sun.COM mdb_warn("couldn't read small mptsas_slots_t at 0x%p",
7419907SJaven.Wu@Sun.COM m.m_active);
7429907SJaven.Wu@Sun.COM mdb_free(s, sizeof (mptsas_slots_t));
7439907SJaven.Wu@Sun.COM return (DCMD_ERR);
7449907SJaven.Wu@Sun.COM }
7459907SJaven.Wu@Sun.COM
7469907SJaven.Wu@Sun.COM nslots = s->m_n_slots;
7479907SJaven.Wu@Sun.COM
7489907SJaven.Wu@Sun.COM mdb_free(s, sizeof (mptsas_slots_t));
7499907SJaven.Wu@Sun.COM
7509907SJaven.Wu@Sun.COM slot_size = sizeof (mptsas_slots_t) +
7519907SJaven.Wu@Sun.COM (sizeof (mptsas_cmd_t *) * (nslots-1));
7529907SJaven.Wu@Sun.COM
7539907SJaven.Wu@Sun.COM s = mdb_alloc(slot_size, UM_SLEEP);
7549907SJaven.Wu@Sun.COM
7559907SJaven.Wu@Sun.COM if (mdb_vread(s, slot_size, (uintptr_t)m.m_active) == -1) {
7569907SJaven.Wu@Sun.COM mdb_warn("couldn't read large mptsas_slots_t at 0x%p",
7579907SJaven.Wu@Sun.COM m.m_active);
7589907SJaven.Wu@Sun.COM mdb_free(s, slot_size);
7599907SJaven.Wu@Sun.COM return (DCMD_ERR);
7609907SJaven.Wu@Sun.COM }
7619907SJaven.Wu@Sun.COM
7629907SJaven.Wu@Sun.COM /* processing completed */
7639907SJaven.Wu@Sun.COM
7649907SJaven.Wu@Sun.COM if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) ||
7659907SJaven.Wu@Sun.COM (flags & DCMD_LOOPFIRST) || slot_info || device_info ||
7669907SJaven.Wu@Sun.COM target_info) {
7679907SJaven.Wu@Sun.COM if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST))
7689907SJaven.Wu@Sun.COM mdb_printf("\n");
7699907SJaven.Wu@Sun.COM mdb_printf(" mptsas_t inst ncmds suspend power");
7709907SJaven.Wu@Sun.COM mdb_printf("\n");
7719907SJaven.Wu@Sun.COM mdb_printf("========================================="
7729907SJaven.Wu@Sun.COM "=======================================");
7739907SJaven.Wu@Sun.COM mdb_printf("\n");
7749907SJaven.Wu@Sun.COM }
7759907SJaven.Wu@Sun.COM
7769907SJaven.Wu@Sun.COM mdb_printf("%16p %4d %5d ", addr, m.m_instance, m.m_ncmds);
7779907SJaven.Wu@Sun.COM mdb_printf("%7d", m.m_suspended);
7789907SJaven.Wu@Sun.COM switch (m.m_power_level) {
7799907SJaven.Wu@Sun.COM case PM_LEVEL_D0:
7809907SJaven.Wu@Sun.COM mdb_printf(" ON=D0 ");
7819907SJaven.Wu@Sun.COM break;
7829907SJaven.Wu@Sun.COM case PM_LEVEL_D1:
7839907SJaven.Wu@Sun.COM mdb_printf(" D1 ");
7849907SJaven.Wu@Sun.COM break;
7859907SJaven.Wu@Sun.COM case PM_LEVEL_D2:
7869907SJaven.Wu@Sun.COM mdb_printf(" D2 ");
7879907SJaven.Wu@Sun.COM break;
7889907SJaven.Wu@Sun.COM case PM_LEVEL_D3:
7899907SJaven.Wu@Sun.COM mdb_printf("OFF=D3 ");
7909907SJaven.Wu@Sun.COM break;
7919907SJaven.Wu@Sun.COM default:
7929907SJaven.Wu@Sun.COM mdb_printf("INVALD ");
7939907SJaven.Wu@Sun.COM }
7949907SJaven.Wu@Sun.COM mdb_printf("\n");
7959907SJaven.Wu@Sun.COM
7969907SJaven.Wu@Sun.COM mdb_inc_indent(17);
7979907SJaven.Wu@Sun.COM
7989907SJaven.Wu@Sun.COM if (target_info)
7999907SJaven.Wu@Sun.COM display_targets(s);
8009907SJaven.Wu@Sun.COM
8019907SJaven.Wu@Sun.COM if (port_info)
8029907SJaven.Wu@Sun.COM display_ports(m);
8039907SJaven.Wu@Sun.COM
8049907SJaven.Wu@Sun.COM if (device_info)
8059907SJaven.Wu@Sun.COM display_deviceinfo(m);
8069907SJaven.Wu@Sun.COM
8079907SJaven.Wu@Sun.COM if (slot_info)
8089907SJaven.Wu@Sun.COM display_slotinfo();
8099907SJaven.Wu@Sun.COM
8109907SJaven.Wu@Sun.COM mdb_dec_indent(17);
8119907SJaven.Wu@Sun.COM
8129907SJaven.Wu@Sun.COM mdb_free(s, slot_size);
8139907SJaven.Wu@Sun.COM
8149907SJaven.Wu@Sun.COM return (rv);
8159907SJaven.Wu@Sun.COM }
8169907SJaven.Wu@Sun.COM /*
8179907SJaven.Wu@Sun.COM * Only -t is implemented now, will add more later when the driver is stable
8189907SJaven.Wu@Sun.COM */
8199907SJaven.Wu@Sun.COM void
mptsas_help()8209907SJaven.Wu@Sun.COM mptsas_help()
8219907SJaven.Wu@Sun.COM {
8229907SJaven.Wu@Sun.COM mdb_printf("Prints summary information about each mpt_sas instance, "
8239907SJaven.Wu@Sun.COM "including warning\nmessages when slot usage doesn't match "
8249907SJaven.Wu@Sun.COM "summary information.\n"
8259907SJaven.Wu@Sun.COM "Without the address of a \"struct mptsas\", prints every "
8269907SJaven.Wu@Sun.COM "instance.\n\n"
8279907SJaven.Wu@Sun.COM "Switches:\n"
8289907SJaven.Wu@Sun.COM " -t includes information about targets\n"
8299907SJaven.Wu@Sun.COM " -p includes information about port\n"
8309907SJaven.Wu@Sun.COM " -d includes information about the hardware\n");
8319907SJaven.Wu@Sun.COM }
8329907SJaven.Wu@Sun.COM
8339907SJaven.Wu@Sun.COM static const mdb_dcmd_t dcmds[] = {
8349907SJaven.Wu@Sun.COM { "mptsas", "?[-tpd]", "print mpt_sas information", mptsas_dcmd,
8359907SJaven.Wu@Sun.COM mptsas_help}, { NULL }
8369907SJaven.Wu@Sun.COM };
8379907SJaven.Wu@Sun.COM
8389907SJaven.Wu@Sun.COM static const mdb_modinfo_t modinfo = {
8399907SJaven.Wu@Sun.COM MDB_API_VERSION, dcmds, NULL
8409907SJaven.Wu@Sun.COM };
8419907SJaven.Wu@Sun.COM
8429907SJaven.Wu@Sun.COM const mdb_modinfo_t *
_mdb_init(void)8439907SJaven.Wu@Sun.COM _mdb_init(void)
8449907SJaven.Wu@Sun.COM {
8459907SJaven.Wu@Sun.COM return (&modinfo);
8469907SJaven.Wu@Sun.COM }
847