110696SDavid.Hollister@Sun.COM /* 210696SDavid.Hollister@Sun.COM * CDDL HEADER START 310696SDavid.Hollister@Sun.COM * 410696SDavid.Hollister@Sun.COM * The contents of this file are subject to the terms of the 510696SDavid.Hollister@Sun.COM * Common Development and Distribution License (the "License"). 610696SDavid.Hollister@Sun.COM * You may not use this file except in compliance with the License. 710696SDavid.Hollister@Sun.COM * 810696SDavid.Hollister@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 910696SDavid.Hollister@Sun.COM * or http://www.opensolaris.org/os/licensing. 1010696SDavid.Hollister@Sun.COM * See the License for the specific language governing permissions 1110696SDavid.Hollister@Sun.COM * and limitations under the License. 1210696SDavid.Hollister@Sun.COM * 1310696SDavid.Hollister@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 1410696SDavid.Hollister@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1510696SDavid.Hollister@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 1610696SDavid.Hollister@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 1710696SDavid.Hollister@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 1810696SDavid.Hollister@Sun.COM * 1910696SDavid.Hollister@Sun.COM * CDDL HEADER END 2010696SDavid.Hollister@Sun.COM */ 2110696SDavid.Hollister@Sun.COM /* 2210696SDavid.Hollister@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2310696SDavid.Hollister@Sun.COM * Use is subject to license terms. 2410696SDavid.Hollister@Sun.COM */ 2510696SDavid.Hollister@Sun.COM 2610696SDavid.Hollister@Sun.COM #include <limits.h> 2710696SDavid.Hollister@Sun.COM #include <sys/mdb_modapi.h> 28*11334SReed.Liu@Sun.COM #include <mdb/mdb_ctf.h> 2910696SDavid.Hollister@Sun.COM #include <sys/sysinfo.h> 3011048SDavid.Hollister@Sun.COM #include <sys/byteorder.h> 31*11334SReed.Liu@Sun.COM #include <sys/nvpair.h> 32*11334SReed.Liu@Sun.COM #include <sys/damap.h> 3310696SDavid.Hollister@Sun.COM #include <sys/scsi/scsi.h> 3410696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs.h> 3510696SDavid.Hollister@Sun.COM 36*11334SReed.Liu@Sun.COM /* 37*11334SReed.Liu@Sun.COM * We need use this to pass the settings when display_iport 38*11334SReed.Liu@Sun.COM */ 39*11334SReed.Liu@Sun.COM typedef struct per_iport_setting { 40*11334SReed.Liu@Sun.COM uint_t pis_damap_info; /* -m: DAM/damap */ 41*11334SReed.Liu@Sun.COM uint_t pis_dtc_info; /* -d: device tree children: dev_info/path_info */ 42*11334SReed.Liu@Sun.COM } per_iport_setting_t; 43*11334SReed.Liu@Sun.COM 44*11334SReed.Liu@Sun.COM #define MDB_RD(a, b, c) mdb_vread(a, b, (uintptr_t)c) 45*11334SReed.Liu@Sun.COM #define NOREAD(a, b) mdb_warn("could not read " #a " at 0x%p", b) 4610696SDavid.Hollister@Sun.COM 4710696SDavid.Hollister@Sun.COM static pmcs_hw_t ss; 4810696SDavid.Hollister@Sun.COM static pmcs_xscsi_t **targets = NULL; 4910696SDavid.Hollister@Sun.COM static int target_idx; 5010696SDavid.Hollister@Sun.COM 5110696SDavid.Hollister@Sun.COM static uint32_t sas_phys, sata_phys, exp_phys, num_expanders, empty_phys; 5210696SDavid.Hollister@Sun.COM 5310696SDavid.Hollister@Sun.COM static pmcs_phy_t *pmcs_next_sibling(pmcs_phy_t *phyp); 5410743SDavid.Hollister@Sun.COM static void display_one_work(pmcwork_t *wp, int verbose, int idx); 5510696SDavid.Hollister@Sun.COM 5610696SDavid.Hollister@Sun.COM static void 5710696SDavid.Hollister@Sun.COM print_sas_address(pmcs_phy_t *phy) 5810696SDavid.Hollister@Sun.COM { 5910696SDavid.Hollister@Sun.COM int idx; 6010696SDavid.Hollister@Sun.COM 6110696SDavid.Hollister@Sun.COM for (idx = 0; idx < 8; idx++) { 6210696SDavid.Hollister@Sun.COM mdb_printf("%02x", phy->sas_address[idx]); 6310696SDavid.Hollister@Sun.COM } 6410696SDavid.Hollister@Sun.COM } 6510696SDavid.Hollister@Sun.COM 6610696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 6710696SDavid.Hollister@Sun.COM static void 6810696SDavid.Hollister@Sun.COM display_ic(struct pmcs_hw m, int verbose) 6910696SDavid.Hollister@Sun.COM { 7010696SDavid.Hollister@Sun.COM int msec_per_tick; 7110696SDavid.Hollister@Sun.COM 7210696SDavid.Hollister@Sun.COM if (mdb_readvar(&msec_per_tick, "msec_per_tick") == -1) { 7310696SDavid.Hollister@Sun.COM mdb_warn("can't read msec_per_tick"); 7410696SDavid.Hollister@Sun.COM msec_per_tick = 0; 7510696SDavid.Hollister@Sun.COM } 7610696SDavid.Hollister@Sun.COM 7710696SDavid.Hollister@Sun.COM mdb_printf("\n"); 7810696SDavid.Hollister@Sun.COM mdb_printf("Interrupt coalescing timer info\n"); 7910696SDavid.Hollister@Sun.COM mdb_printf("-------------------------------\n"); 8010696SDavid.Hollister@Sun.COM if (msec_per_tick == 0) { 8110696SDavid.Hollister@Sun.COM mdb_printf("Quantum : ?? ms\n"); 8210696SDavid.Hollister@Sun.COM } else { 8310696SDavid.Hollister@Sun.COM mdb_printf("Quantum : %d ms\n", 8410696SDavid.Hollister@Sun.COM m.io_intr_coal.quantum * msec_per_tick); 8510696SDavid.Hollister@Sun.COM } 8610696SDavid.Hollister@Sun.COM mdb_printf("Timer enabled : "); 8710696SDavid.Hollister@Sun.COM if (m.io_intr_coal.timer_on) { 8810696SDavid.Hollister@Sun.COM mdb_printf("Yes\n"); 8910696SDavid.Hollister@Sun.COM mdb_printf("Coalescing timer value : %d us\n", 9010696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_coal_timer); 9110696SDavid.Hollister@Sun.COM } else { 9210696SDavid.Hollister@Sun.COM mdb_printf("No\n"); 9310696SDavid.Hollister@Sun.COM } 9410696SDavid.Hollister@Sun.COM mdb_printf("Total nsecs between interrupts: %ld\n", 9510696SDavid.Hollister@Sun.COM m.io_intr_coal.nsecs_between_intrs); 9610696SDavid.Hollister@Sun.COM mdb_printf("Time of last I/O interrupt : %ld\n", 9710696SDavid.Hollister@Sun.COM m.io_intr_coal.last_io_comp); 9810696SDavid.Hollister@Sun.COM mdb_printf("Number of I/O interrupts : %d\n", 9910696SDavid.Hollister@Sun.COM m.io_intr_coal.num_intrs); 10010696SDavid.Hollister@Sun.COM mdb_printf("Number of I/O completions : %d\n", 10110696SDavid.Hollister@Sun.COM m.io_intr_coal.num_io_completions); 10210696SDavid.Hollister@Sun.COM mdb_printf("Max I/O completion interrupts : %d\n", 10310696SDavid.Hollister@Sun.COM m.io_intr_coal.max_io_completions); 10410696SDavid.Hollister@Sun.COM mdb_printf("Measured ECHO int latency : %d ns\n", 10510696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_latency); 10610696SDavid.Hollister@Sun.COM mdb_printf("Interrupt threshold : %d\n", 10710696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_threshold); 10810696SDavid.Hollister@Sun.COM } 10910696SDavid.Hollister@Sun.COM 11010696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 11110696SDavid.Hollister@Sun.COM static int 11210696SDavid.Hollister@Sun.COM pmcs_iport_phy_walk_cb(uintptr_t addr, const void *wdata, void *priv) 11310696SDavid.Hollister@Sun.COM { 11410696SDavid.Hollister@Sun.COM struct pmcs_phy phy; 11510696SDavid.Hollister@Sun.COM 11610696SDavid.Hollister@Sun.COM if (mdb_vread(&phy, sizeof (struct pmcs_phy), addr) != 11710696SDavid.Hollister@Sun.COM sizeof (struct pmcs_phy)) { 11810696SDavid.Hollister@Sun.COM return (DCMD_ERR); 11910696SDavid.Hollister@Sun.COM } 12010696SDavid.Hollister@Sun.COM 12110696SDavid.Hollister@Sun.COM mdb_printf("%16p %2d\n", addr, phy.phynum); 12210696SDavid.Hollister@Sun.COM 12310696SDavid.Hollister@Sun.COM return (0); 12410696SDavid.Hollister@Sun.COM } 12510696SDavid.Hollister@Sun.COM 126*11334SReed.Liu@Sun.COM static int 127*11334SReed.Liu@Sun.COM display_iport_damap(dev_info_t *pdip) 128*11334SReed.Liu@Sun.COM { 129*11334SReed.Liu@Sun.COM int rval = DCMD_ERR; 130*11334SReed.Liu@Sun.COM struct dev_info dip; 131*11334SReed.Liu@Sun.COM scsi_hba_tran_t sht; 132*11334SReed.Liu@Sun.COM mdb_ctf_id_t istm_ctfid; /* impl_scsi_tgtmap_t ctf_id */ 133*11334SReed.Liu@Sun.COM ulong_t tmd_offset = 0; /* tgtmap_dam offset to impl_scsi_tgtmap_t */ 134*11334SReed.Liu@Sun.COM uintptr_t dam0; 135*11334SReed.Liu@Sun.COM uintptr_t dam1; 136*11334SReed.Liu@Sun.COM 137*11334SReed.Liu@Sun.COM if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)pdip) != 138*11334SReed.Liu@Sun.COM sizeof (struct dev_info)) { 139*11334SReed.Liu@Sun.COM return (rval); 140*11334SReed.Liu@Sun.COM } 141*11334SReed.Liu@Sun.COM 142*11334SReed.Liu@Sun.COM if (dip.devi_driver_data == NULL) { 143*11334SReed.Liu@Sun.COM return (rval); 144*11334SReed.Liu@Sun.COM } 145*11334SReed.Liu@Sun.COM 146*11334SReed.Liu@Sun.COM if (mdb_vread(&sht, sizeof (scsi_hba_tran_t), 147*11334SReed.Liu@Sun.COM (uintptr_t)dip.devi_driver_data) != sizeof (scsi_hba_tran_t)) { 148*11334SReed.Liu@Sun.COM return (rval); 149*11334SReed.Liu@Sun.COM } 150*11334SReed.Liu@Sun.COM 151*11334SReed.Liu@Sun.COM if (sht.tran_tgtmap == NULL) { 152*11334SReed.Liu@Sun.COM return (rval); 153*11334SReed.Liu@Sun.COM } 154*11334SReed.Liu@Sun.COM 155*11334SReed.Liu@Sun.COM if (mdb_ctf_lookup_by_name("impl_scsi_tgtmap_t", &istm_ctfid) != 0) { 156*11334SReed.Liu@Sun.COM return (rval); 157*11334SReed.Liu@Sun.COM } 158*11334SReed.Liu@Sun.COM 159*11334SReed.Liu@Sun.COM if (mdb_ctf_offsetof(istm_ctfid, "tgtmap_dam", &tmd_offset) != 0) { 160*11334SReed.Liu@Sun.COM return (rval); 161*11334SReed.Liu@Sun.COM } 162*11334SReed.Liu@Sun.COM 163*11334SReed.Liu@Sun.COM tmd_offset /= NBBY; 164*11334SReed.Liu@Sun.COM mdb_vread(&dam0, sizeof (dam0), 165*11334SReed.Liu@Sun.COM (uintptr_t)(tmd_offset + (char *)sht.tran_tgtmap)); 166*11334SReed.Liu@Sun.COM mdb_vread(&dam1, sizeof (dam1), 167*11334SReed.Liu@Sun.COM (uintptr_t)(sizeof (dam0) + tmd_offset + (char *)sht.tran_tgtmap)); 168*11334SReed.Liu@Sun.COM 169*11334SReed.Liu@Sun.COM if (dam0 != NULL) { 170*11334SReed.Liu@Sun.COM rval = mdb_call_dcmd("damap", dam0, DCMD_ADDRSPEC, 0, NULL); 171*11334SReed.Liu@Sun.COM mdb_printf("\n"); 172*11334SReed.Liu@Sun.COM if (rval != DCMD_OK) { 173*11334SReed.Liu@Sun.COM return (rval); 174*11334SReed.Liu@Sun.COM } 175*11334SReed.Liu@Sun.COM } 176*11334SReed.Liu@Sun.COM 177*11334SReed.Liu@Sun.COM if (dam1 != NULL) { 178*11334SReed.Liu@Sun.COM rval = mdb_call_dcmd("damap", dam1, DCMD_ADDRSPEC, 0, NULL); 179*11334SReed.Liu@Sun.COM mdb_printf("\n"); 180*11334SReed.Liu@Sun.COM } 181*11334SReed.Liu@Sun.COM 182*11334SReed.Liu@Sun.COM return (rval); 183*11334SReed.Liu@Sun.COM } 184*11334SReed.Liu@Sun.COM 185*11334SReed.Liu@Sun.COM /* ARGSUSED */ 186*11334SReed.Liu@Sun.COM static int 187*11334SReed.Liu@Sun.COM display_iport_di_cb(uintptr_t addr, const void *wdata, void *priv) 188*11334SReed.Liu@Sun.COM { 189*11334SReed.Liu@Sun.COM uint_t *idx = (uint_t *)priv; 190*11334SReed.Liu@Sun.COM struct dev_info dip; 191*11334SReed.Liu@Sun.COM char devi_name[MAXNAMELEN]; 192*11334SReed.Liu@Sun.COM char devi_addr[MAXNAMELEN]; 193*11334SReed.Liu@Sun.COM 194*11334SReed.Liu@Sun.COM if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)addr) != 195*11334SReed.Liu@Sun.COM sizeof (struct dev_info)) { 196*11334SReed.Liu@Sun.COM return (DCMD_ERR); 197*11334SReed.Liu@Sun.COM } 198*11334SReed.Liu@Sun.COM 199*11334SReed.Liu@Sun.COM if (mdb_readstr(devi_name, sizeof (devi_name), 200*11334SReed.Liu@Sun.COM (uintptr_t)dip.devi_node_name) == -1) { 201*11334SReed.Liu@Sun.COM devi_name[0] = '?'; 202*11334SReed.Liu@Sun.COM devi_name[1] = '\0'; 203*11334SReed.Liu@Sun.COM } 204*11334SReed.Liu@Sun.COM 205*11334SReed.Liu@Sun.COM if (mdb_readstr(devi_addr, sizeof (devi_addr), 206*11334SReed.Liu@Sun.COM (uintptr_t)dip.devi_addr) == -1) { 207*11334SReed.Liu@Sun.COM devi_addr[0] = '?'; 208*11334SReed.Liu@Sun.COM devi_addr[1] = '\0'; 209*11334SReed.Liu@Sun.COM } 210*11334SReed.Liu@Sun.COM 211*11334SReed.Liu@Sun.COM mdb_printf(" %3d: @%-21s%10s@\t%p::devinfo -s\n", 212*11334SReed.Liu@Sun.COM (*idx)++, devi_addr, devi_name, addr); 213*11334SReed.Liu@Sun.COM return (DCMD_OK); 214*11334SReed.Liu@Sun.COM } 215*11334SReed.Liu@Sun.COM 216*11334SReed.Liu@Sun.COM /* ARGSUSED */ 217*11334SReed.Liu@Sun.COM static int 218*11334SReed.Liu@Sun.COM display_iport_pi_cb(uintptr_t addr, const void *wdata, void *priv) 219*11334SReed.Liu@Sun.COM { 220*11334SReed.Liu@Sun.COM uint_t *idx = (uint_t *)priv; 221*11334SReed.Liu@Sun.COM struct mdi_pathinfo mpi; 222*11334SReed.Liu@Sun.COM char pi_addr[MAXNAMELEN]; 223*11334SReed.Liu@Sun.COM 224*11334SReed.Liu@Sun.COM if (mdb_vread(&mpi, sizeof (struct mdi_pathinfo), (uintptr_t)addr) != 225*11334SReed.Liu@Sun.COM sizeof (struct mdi_pathinfo)) { 226*11334SReed.Liu@Sun.COM return (DCMD_ERR); 227*11334SReed.Liu@Sun.COM } 228*11334SReed.Liu@Sun.COM 229*11334SReed.Liu@Sun.COM if (mdb_readstr(pi_addr, sizeof (pi_addr), 230*11334SReed.Liu@Sun.COM (uintptr_t)mpi.pi_addr) == -1) { 231*11334SReed.Liu@Sun.COM pi_addr[0] = '?'; 232*11334SReed.Liu@Sun.COM pi_addr[1] = '\0'; 233*11334SReed.Liu@Sun.COM } 234*11334SReed.Liu@Sun.COM 235*11334SReed.Liu@Sun.COM mdb_printf(" %3d: @%-21s %p::print struct mdi_pathinfo\n", 236*11334SReed.Liu@Sun.COM (*idx)++, pi_addr, addr); 237*11334SReed.Liu@Sun.COM return (DCMD_OK); 238*11334SReed.Liu@Sun.COM } 239*11334SReed.Liu@Sun.COM 240*11334SReed.Liu@Sun.COM static int 241*11334SReed.Liu@Sun.COM display_iport_dtc(dev_info_t *pdip) 242*11334SReed.Liu@Sun.COM { 243*11334SReed.Liu@Sun.COM int rval = DCMD_ERR; 244*11334SReed.Liu@Sun.COM struct dev_info dip; 245*11334SReed.Liu@Sun.COM struct mdi_phci phci; 246*11334SReed.Liu@Sun.COM uint_t didx = 1; 247*11334SReed.Liu@Sun.COM uint_t pidx = 1; 248*11334SReed.Liu@Sun.COM 249*11334SReed.Liu@Sun.COM if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)pdip) != 250*11334SReed.Liu@Sun.COM sizeof (struct dev_info)) { 251*11334SReed.Liu@Sun.COM return (rval); 252*11334SReed.Liu@Sun.COM } 253*11334SReed.Liu@Sun.COM 254*11334SReed.Liu@Sun.COM mdb_printf("Device tree children - dev_info:\n"); 255*11334SReed.Liu@Sun.COM if (dip.devi_child == NULL) { 256*11334SReed.Liu@Sun.COM mdb_printf("\tdevi_child is NULL, no dev_info\n\n"); 257*11334SReed.Liu@Sun.COM goto skip_di; 258*11334SReed.Liu@Sun.COM } 259*11334SReed.Liu@Sun.COM 260*11334SReed.Liu@Sun.COM /* 261*11334SReed.Liu@Sun.COM * First, we dump the iport's children dev_info node information. 262*11334SReed.Liu@Sun.COM * use existing walker: devinfo_siblings 263*11334SReed.Liu@Sun.COM */ 264*11334SReed.Liu@Sun.COM mdb_printf("\t#: @unit-address name@\tdrill-down\n"); 265*11334SReed.Liu@Sun.COM rval = mdb_pwalk("devinfo_siblings", display_iport_di_cb, 266*11334SReed.Liu@Sun.COM (void *)&didx, (uintptr_t)dip.devi_child); 267*11334SReed.Liu@Sun.COM mdb_printf("\n"); 268*11334SReed.Liu@Sun.COM 269*11334SReed.Liu@Sun.COM skip_di: 270*11334SReed.Liu@Sun.COM /* 271*11334SReed.Liu@Sun.COM * Then we try to dump the iport's path_info node information. 272*11334SReed.Liu@Sun.COM * use existing walker: mdipi_phci_list 273*11334SReed.Liu@Sun.COM */ 274*11334SReed.Liu@Sun.COM mdb_printf("Device tree children - path_info:\n"); 275*11334SReed.Liu@Sun.COM if (mdb_vread(&phci, sizeof (struct mdi_phci), 276*11334SReed.Liu@Sun.COM (uintptr_t)dip.devi_mdi_xhci) != sizeof (struct mdi_phci)) { 277*11334SReed.Liu@Sun.COM mdb_printf("\tdevi_mdi_xhci is NULL, no path_info\n\n"); 278*11334SReed.Liu@Sun.COM return (rval); 279*11334SReed.Liu@Sun.COM } 280*11334SReed.Liu@Sun.COM 281*11334SReed.Liu@Sun.COM if (phci.ph_path_head == NULL) { 282*11334SReed.Liu@Sun.COM mdb_printf("\tph_path_head is NULL, no path_info\n\n"); 283*11334SReed.Liu@Sun.COM return (rval); 284*11334SReed.Liu@Sun.COM } 285*11334SReed.Liu@Sun.COM 286*11334SReed.Liu@Sun.COM mdb_printf("\t#: @unit-address drill-down\n"); 287*11334SReed.Liu@Sun.COM rval = mdb_pwalk("mdipi_phci_list", display_iport_pi_cb, 288*11334SReed.Liu@Sun.COM (void *)&pidx, (uintptr_t)phci.ph_path_head); 289*11334SReed.Liu@Sun.COM mdb_printf("\n"); 290*11334SReed.Liu@Sun.COM return (rval); 291*11334SReed.Liu@Sun.COM } 292*11334SReed.Liu@Sun.COM 293*11334SReed.Liu@Sun.COM static void 294*11334SReed.Liu@Sun.COM display_iport_more(dev_info_t *dip, per_iport_setting_t *pis) 295*11334SReed.Liu@Sun.COM { 296*11334SReed.Liu@Sun.COM if (pis->pis_damap_info) { 297*11334SReed.Liu@Sun.COM (void) display_iport_damap(dip); 298*11334SReed.Liu@Sun.COM } 299*11334SReed.Liu@Sun.COM 300*11334SReed.Liu@Sun.COM if (pis->pis_dtc_info) { 301*11334SReed.Liu@Sun.COM (void) display_iport_dtc(dip); 302*11334SReed.Liu@Sun.COM } 303*11334SReed.Liu@Sun.COM } 304*11334SReed.Liu@Sun.COM 30510696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 30610696SDavid.Hollister@Sun.COM static int 30710696SDavid.Hollister@Sun.COM pmcs_iport_walk_cb(uintptr_t addr, const void *wdata, void *priv) 30810696SDavid.Hollister@Sun.COM { 30910696SDavid.Hollister@Sun.COM struct pmcs_iport iport; 31010696SDavid.Hollister@Sun.COM uintptr_t list_addr; 31110696SDavid.Hollister@Sun.COM char *ua_state; 31210696SDavid.Hollister@Sun.COM char portid[4]; 31310696SDavid.Hollister@Sun.COM char unit_address[34]; 314*11334SReed.Liu@Sun.COM per_iport_setting_t *pis = (per_iport_setting_t *)priv; 31510696SDavid.Hollister@Sun.COM 31610696SDavid.Hollister@Sun.COM if (mdb_vread(&iport, sizeof (struct pmcs_iport), addr) != 31710696SDavid.Hollister@Sun.COM sizeof (struct pmcs_iport)) { 31810696SDavid.Hollister@Sun.COM return (DCMD_ERR); 31910696SDavid.Hollister@Sun.COM } 32010696SDavid.Hollister@Sun.COM 32110696SDavid.Hollister@Sun.COM if (mdb_readstr(unit_address, sizeof (unit_address), 32210696SDavid.Hollister@Sun.COM (uintptr_t)(iport.ua)) == -1) { 32310696SDavid.Hollister@Sun.COM strncpy(unit_address, "Unset", sizeof (unit_address)); 32410696SDavid.Hollister@Sun.COM } 32510696SDavid.Hollister@Sun.COM 32610696SDavid.Hollister@Sun.COM if (iport.portid == 0xffff) { 32710696SDavid.Hollister@Sun.COM mdb_snprintf(portid, sizeof (portid), "%s", "-"); 32810696SDavid.Hollister@Sun.COM } else { 32910696SDavid.Hollister@Sun.COM mdb_snprintf(portid, sizeof (portid), "%d", iport.portid); 33010696SDavid.Hollister@Sun.COM } 33110696SDavid.Hollister@Sun.COM 33210696SDavid.Hollister@Sun.COM switch (iport.ua_state) { 33310696SDavid.Hollister@Sun.COM case UA_INACTIVE: 33410696SDavid.Hollister@Sun.COM ua_state = "Inactive"; 33510696SDavid.Hollister@Sun.COM break; 33610696SDavid.Hollister@Sun.COM case UA_PEND_ACTIVATE: 33710696SDavid.Hollister@Sun.COM ua_state = "PendActivate"; 33810696SDavid.Hollister@Sun.COM break; 33910696SDavid.Hollister@Sun.COM case UA_ACTIVE: 34010696SDavid.Hollister@Sun.COM ua_state = "Active"; 34110696SDavid.Hollister@Sun.COM break; 34210696SDavid.Hollister@Sun.COM case UA_PEND_DEACTIVATE: 34310696SDavid.Hollister@Sun.COM ua_state = "PendDeactivate"; 34410696SDavid.Hollister@Sun.COM break; 34510696SDavid.Hollister@Sun.COM default: 34610696SDavid.Hollister@Sun.COM ua_state = "Unknown"; 34710696SDavid.Hollister@Sun.COM } 34810696SDavid.Hollister@Sun.COM 34910696SDavid.Hollister@Sun.COM if (strlen(unit_address) < 3) { 35010696SDavid.Hollister@Sun.COM /* Standard iport unit address */ 35110696SDavid.Hollister@Sun.COM mdb_printf("UA %-16s %16s %8s %8s %16s", "Iport", "UA State", 35210696SDavid.Hollister@Sun.COM "PortID", "NumPhys", "DIP\n"); 35310696SDavid.Hollister@Sun.COM mdb_printf("%2s %16p %16s %8s %8d %16p\n", unit_address, addr, 35410696SDavid.Hollister@Sun.COM ua_state, portid, iport.nphy, iport.dip); 35510696SDavid.Hollister@Sun.COM } else { 35610696SDavid.Hollister@Sun.COM /* Temporary iport unit address */ 35710696SDavid.Hollister@Sun.COM mdb_printf("%-32s %16s %20s %8s %8s %16s", "UA", "Iport", 35810696SDavid.Hollister@Sun.COM "UA State", "PortID", "NumPhys", "DIP\n"); 35910696SDavid.Hollister@Sun.COM mdb_printf("%32s %16p %20s %8s %8d %16p\n", unit_address, addr, 36010696SDavid.Hollister@Sun.COM ua_state, portid, iport.nphy, iport.dip); 36110696SDavid.Hollister@Sun.COM } 36210696SDavid.Hollister@Sun.COM 36310696SDavid.Hollister@Sun.COM if (iport.nphy > 0) { 36410696SDavid.Hollister@Sun.COM mdb_inc_indent(4); 36510696SDavid.Hollister@Sun.COM mdb_printf("%-18s %8s", "Phy", "PhyNum\n"); 36610696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 36710696SDavid.Hollister@Sun.COM list_addr = 36810696SDavid.Hollister@Sun.COM (uintptr_t)(addr + offsetof(struct pmcs_iport, phys)); 36910696SDavid.Hollister@Sun.COM if (mdb_pwalk("list", pmcs_iport_phy_walk_cb, NULL, 37010696SDavid.Hollister@Sun.COM list_addr) == -1) { 37110696SDavid.Hollister@Sun.COM mdb_warn("pmcs iport walk failed"); 37210696SDavid.Hollister@Sun.COM } 37310696SDavid.Hollister@Sun.COM mdb_dec_indent(6); 37410696SDavid.Hollister@Sun.COM mdb_printf("\n"); 37510696SDavid.Hollister@Sun.COM } 37610696SDavid.Hollister@Sun.COM 377*11334SReed.Liu@Sun.COM /* 378*11334SReed.Liu@Sun.COM * See if we need to show more information based on 'd' or 'm' options 379*11334SReed.Liu@Sun.COM */ 380*11334SReed.Liu@Sun.COM display_iport_more(iport.dip, pis); 381*11334SReed.Liu@Sun.COM 38210696SDavid.Hollister@Sun.COM return (0); 38310696SDavid.Hollister@Sun.COM } 38410696SDavid.Hollister@Sun.COM 38510696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 38610696SDavid.Hollister@Sun.COM static void 387*11334SReed.Liu@Sun.COM display_iport(struct pmcs_hw m, uintptr_t addr, int verbose, 388*11334SReed.Liu@Sun.COM per_iport_setting_t *pis) 38910696SDavid.Hollister@Sun.COM { 39010696SDavid.Hollister@Sun.COM uintptr_t list_addr; 39110696SDavid.Hollister@Sun.COM 39210696SDavid.Hollister@Sun.COM if (m.iports_attached) { 39310696SDavid.Hollister@Sun.COM mdb_printf("Iport information:\n"); 39410696SDavid.Hollister@Sun.COM mdb_printf("-----------------\n"); 39510696SDavid.Hollister@Sun.COM } else { 39610696SDavid.Hollister@Sun.COM mdb_printf("No Iports found.\n\n"); 39710696SDavid.Hollister@Sun.COM return; 39810696SDavid.Hollister@Sun.COM } 39910696SDavid.Hollister@Sun.COM 40010696SDavid.Hollister@Sun.COM list_addr = (uintptr_t)(addr + offsetof(struct pmcs_hw, iports)); 40110696SDavid.Hollister@Sun.COM 402*11334SReed.Liu@Sun.COM if (mdb_pwalk("list", pmcs_iport_walk_cb, pis, list_addr) == -1) { 40310696SDavid.Hollister@Sun.COM mdb_warn("pmcs iport walk failed"); 40410696SDavid.Hollister@Sun.COM } 40510696SDavid.Hollister@Sun.COM 40610696SDavid.Hollister@Sun.COM mdb_printf("\n"); 40710696SDavid.Hollister@Sun.COM } 40810696SDavid.Hollister@Sun.COM 40911048SDavid.Hollister@Sun.COM /* ARGSUSED */ 41011048SDavid.Hollister@Sun.COM static int 41111048SDavid.Hollister@Sun.COM pmcs_utarget_walk_cb(uintptr_t addr, const void *wdata, void *priv) 41211048SDavid.Hollister@Sun.COM { 41311048SDavid.Hollister@Sun.COM pmcs_phy_t phy; 41411048SDavid.Hollister@Sun.COM 41511048SDavid.Hollister@Sun.COM if (mdb_vread(&phy, sizeof (pmcs_phy_t), (uintptr_t)addr) == -1) { 41611048SDavid.Hollister@Sun.COM mdb_warn("pmcs_utarget_walk_cb: Failed to read PHY at %p", 41711048SDavid.Hollister@Sun.COM (void *)addr); 41811048SDavid.Hollister@Sun.COM return (DCMD_ERR); 41911048SDavid.Hollister@Sun.COM } 42011048SDavid.Hollister@Sun.COM 42111048SDavid.Hollister@Sun.COM if (phy.configured && (phy.target == NULL)) { 42211048SDavid.Hollister@Sun.COM mdb_printf("SAS address: "); 42311048SDavid.Hollister@Sun.COM print_sas_address(&phy); 42411048SDavid.Hollister@Sun.COM mdb_printf(" DType: "); 42511048SDavid.Hollister@Sun.COM switch (phy.dtype) { 42611048SDavid.Hollister@Sun.COM case SAS: 42711048SDavid.Hollister@Sun.COM mdb_printf("%4s", "SAS"); 42811048SDavid.Hollister@Sun.COM break; 42911048SDavid.Hollister@Sun.COM case SATA: 43011048SDavid.Hollister@Sun.COM mdb_printf("%4s", "SATA"); 43111048SDavid.Hollister@Sun.COM break; 43211048SDavid.Hollister@Sun.COM case EXPANDER: 43311048SDavid.Hollister@Sun.COM mdb_printf("%4s", "SMP"); 43411048SDavid.Hollister@Sun.COM break; 43511048SDavid.Hollister@Sun.COM default: 43611048SDavid.Hollister@Sun.COM mdb_printf("%4s", "N/A"); 43711048SDavid.Hollister@Sun.COM break; 43811048SDavid.Hollister@Sun.COM } 43911048SDavid.Hollister@Sun.COM mdb_printf(" Path: %s\n", phy.path); 44011048SDavid.Hollister@Sun.COM } 44111048SDavid.Hollister@Sun.COM 44211048SDavid.Hollister@Sun.COM return (0); 44311048SDavid.Hollister@Sun.COM } 44411048SDavid.Hollister@Sun.COM 44511048SDavid.Hollister@Sun.COM static void 44611048SDavid.Hollister@Sun.COM display_unconfigured_targets(uintptr_t addr) 44711048SDavid.Hollister@Sun.COM { 44811048SDavid.Hollister@Sun.COM mdb_printf("Unconfigured target SAS address:\n\n"); 44911048SDavid.Hollister@Sun.COM 45011048SDavid.Hollister@Sun.COM if (mdb_pwalk("pmcs_phys", pmcs_utarget_walk_cb, NULL, addr) == -1) { 45111048SDavid.Hollister@Sun.COM mdb_warn("pmcs phys walk failed"); 45211048SDavid.Hollister@Sun.COM } 45311048SDavid.Hollister@Sun.COM } 45411048SDavid.Hollister@Sun.COM 45510743SDavid.Hollister@Sun.COM static void 45610743SDavid.Hollister@Sun.COM display_completion_queue(struct pmcs_hw ss) 45710743SDavid.Hollister@Sun.COM { 45810743SDavid.Hollister@Sun.COM pmcs_iocomp_cb_t ccb, *ccbp; 45910743SDavid.Hollister@Sun.COM pmcwork_t work; 46010743SDavid.Hollister@Sun.COM 46110743SDavid.Hollister@Sun.COM if (ss.iocomp_cb_head == NULL) { 46210743SDavid.Hollister@Sun.COM mdb_printf("Completion queue is empty.\n"); 46310743SDavid.Hollister@Sun.COM return; 46410743SDavid.Hollister@Sun.COM } 46510743SDavid.Hollister@Sun.COM 46610743SDavid.Hollister@Sun.COM ccbp = ss.iocomp_cb_head; 46710743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D\n", 46810743SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 46910743SDavid.Hollister@Sun.COM 47010743SDavid.Hollister@Sun.COM while (ccbp) { 47110743SDavid.Hollister@Sun.COM if (mdb_vread(&ccb, sizeof (pmcs_iocomp_cb_t), 47210743SDavid.Hollister@Sun.COM (uintptr_t)ccbp) != sizeof (pmcs_iocomp_cb_t)) { 47310743SDavid.Hollister@Sun.COM mdb_warn("Unable to read completion queue entry\n"); 47410743SDavid.Hollister@Sun.COM return; 47510743SDavid.Hollister@Sun.COM } 47610743SDavid.Hollister@Sun.COM 47710743SDavid.Hollister@Sun.COM if (mdb_vread(&work, sizeof (pmcwork_t), (uintptr_t)ccb.pwrk) 47810743SDavid.Hollister@Sun.COM != sizeof (pmcwork_t)) { 47910743SDavid.Hollister@Sun.COM mdb_warn("Unable to read work structure\n"); 48010743SDavid.Hollister@Sun.COM return; 48110743SDavid.Hollister@Sun.COM } 48210743SDavid.Hollister@Sun.COM 48310743SDavid.Hollister@Sun.COM /* 48410743SDavid.Hollister@Sun.COM * Only print the work structure if it's still active. If 48510743SDavid.Hollister@Sun.COM * it's not, it's been completed since we started looking at 48610743SDavid.Hollister@Sun.COM * it. 48710743SDavid.Hollister@Sun.COM */ 48810743SDavid.Hollister@Sun.COM if (work.state != PMCS_WORK_STATE_NIL) { 48910743SDavid.Hollister@Sun.COM display_one_work(&work, 0, 0); 49010743SDavid.Hollister@Sun.COM } 49110743SDavid.Hollister@Sun.COM ccbp = ccb.next; 49210743SDavid.Hollister@Sun.COM } 49310743SDavid.Hollister@Sun.COM } 49410743SDavid.Hollister@Sun.COM 49510696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 49610696SDavid.Hollister@Sun.COM static void 49710696SDavid.Hollister@Sun.COM display_hwinfo(struct pmcs_hw m, int verbose) 49810696SDavid.Hollister@Sun.COM { 49910696SDavid.Hollister@Sun.COM struct pmcs_hw *mp = &m; 50010696SDavid.Hollister@Sun.COM char *fwsupport; 50110696SDavid.Hollister@Sun.COM 50210696SDavid.Hollister@Sun.COM switch (PMCS_FW_TYPE(mp)) { 50310696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_RELEASED: 50410696SDavid.Hollister@Sun.COM fwsupport = "Released"; 50510696SDavid.Hollister@Sun.COM break; 50610696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_DEVELOPMENT: 50710696SDavid.Hollister@Sun.COM fwsupport = "Development"; 50810696SDavid.Hollister@Sun.COM break; 50910696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_ALPHA: 51010696SDavid.Hollister@Sun.COM fwsupport = "Alpha"; 51110696SDavid.Hollister@Sun.COM break; 51210696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_BETA: 51310696SDavid.Hollister@Sun.COM fwsupport = "Beta"; 51410696SDavid.Hollister@Sun.COM break; 51510696SDavid.Hollister@Sun.COM default: 51610696SDavid.Hollister@Sun.COM fwsupport = "Special"; 51710696SDavid.Hollister@Sun.COM break; 51810696SDavid.Hollister@Sun.COM } 51910696SDavid.Hollister@Sun.COM 52010696SDavid.Hollister@Sun.COM mdb_printf("\nHardware information:\n"); 52110696SDavid.Hollister@Sun.COM mdb_printf("---------------------\n"); 52210696SDavid.Hollister@Sun.COM 52310696SDavid.Hollister@Sun.COM mdb_printf("Chip revision: %c\n", 'A' + m.chiprev); 52410696SDavid.Hollister@Sun.COM mdb_printf("SAS WWID: %"PRIx64"\n", m.sas_wwns[0]); 52510696SDavid.Hollister@Sun.COM mdb_printf("Firmware version: %x.%x.%x (%s)\n", 52610696SDavid.Hollister@Sun.COM PMCS_FW_MAJOR(mp), PMCS_FW_MINOR(mp), PMCS_FW_MICRO(mp), 52710696SDavid.Hollister@Sun.COM fwsupport); 52810696SDavid.Hollister@Sun.COM 52910696SDavid.Hollister@Sun.COM mdb_printf("Number of PHYs: %d\n", m.nphy); 53010696SDavid.Hollister@Sun.COM mdb_printf("Maximum commands: %d\n", m.max_cmd); 53110696SDavid.Hollister@Sun.COM mdb_printf("Maximum devices: %d\n", m.max_dev); 53210696SDavid.Hollister@Sun.COM mdb_printf("I/O queue depth: %d\n", m.ioq_depth); 53310696SDavid.Hollister@Sun.COM if (m.fwlog == 0) { 53410696SDavid.Hollister@Sun.COM mdb_printf("Firmware logging: Disabled\n"); 53510696SDavid.Hollister@Sun.COM } else { 53610696SDavid.Hollister@Sun.COM mdb_printf("Firmware logging: Enabled (%d)\n", m.fwlog); 53710696SDavid.Hollister@Sun.COM } 53810696SDavid.Hollister@Sun.COM } 53910696SDavid.Hollister@Sun.COM 54010696SDavid.Hollister@Sun.COM static void 54110696SDavid.Hollister@Sun.COM display_targets(struct pmcs_hw m, int verbose, int totals_only) 54210696SDavid.Hollister@Sun.COM { 54310696SDavid.Hollister@Sun.COM char *dtype; 54410696SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 54510696SDavid.Hollister@Sun.COM pmcs_phy_t phy; 54610696SDavid.Hollister@Sun.COM uint16_t max_dev, idx; 54710696SDavid.Hollister@Sun.COM uint32_t sas_targets = 0, smp_targets = 0, sata_targets = 0; 54810696SDavid.Hollister@Sun.COM 54910696SDavid.Hollister@Sun.COM max_dev = m.max_dev; 55010696SDavid.Hollister@Sun.COM 55110696SDavid.Hollister@Sun.COM if (targets == NULL) { 55210696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * max_dev, UM_SLEEP); 55310696SDavid.Hollister@Sun.COM } 55410696SDavid.Hollister@Sun.COM 55510696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * max_dev, m.targets) == -1) { 55610696SDavid.Hollister@Sun.COM NOREAD(targets, m.targets); 55710696SDavid.Hollister@Sun.COM return; 55810696SDavid.Hollister@Sun.COM } 55910696SDavid.Hollister@Sun.COM 56010696SDavid.Hollister@Sun.COM if (!totals_only) { 56110696SDavid.Hollister@Sun.COM mdb_printf("\nTarget information:\n"); 56210696SDavid.Hollister@Sun.COM mdb_printf("---------------------------------------\n"); 56310696SDavid.Hollister@Sun.COM mdb_printf("VTGT %-16s %-16s %-5s %8s %s", "SAS Address", 56410696SDavid.Hollister@Sun.COM "PHY Address", "DType", "Active", "DS"); 56510696SDavid.Hollister@Sun.COM mdb_printf("\n"); 56610696SDavid.Hollister@Sun.COM } 56710696SDavid.Hollister@Sun.COM 56810696SDavid.Hollister@Sun.COM for (idx = 0; idx < max_dev; idx++) { 56910696SDavid.Hollister@Sun.COM if (targets[idx] == NULL) { 57010696SDavid.Hollister@Sun.COM continue; 57110696SDavid.Hollister@Sun.COM } 57210696SDavid.Hollister@Sun.COM 57310696SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), targets[idx]) == -1) { 57410696SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, targets[idx]); 57510696SDavid.Hollister@Sun.COM continue; 57610696SDavid.Hollister@Sun.COM } 57710696SDavid.Hollister@Sun.COM 57810696SDavid.Hollister@Sun.COM /* 57910755SJesse.Butler@Sun.COM * It has to be new or assigned to be of interest. 58010696SDavid.Hollister@Sun.COM */ 58110755SJesse.Butler@Sun.COM if (xs.new == 0 && xs.assigned == 0) { 58210696SDavid.Hollister@Sun.COM continue; 58310696SDavid.Hollister@Sun.COM } 58410696SDavid.Hollister@Sun.COM 58510696SDavid.Hollister@Sun.COM switch (xs.dtype) { 58610696SDavid.Hollister@Sun.COM case NOTHING: 58710696SDavid.Hollister@Sun.COM dtype = "None"; 58810696SDavid.Hollister@Sun.COM break; 58910696SDavid.Hollister@Sun.COM case SATA: 59010696SDavid.Hollister@Sun.COM dtype = "SATA"; 59110696SDavid.Hollister@Sun.COM sata_targets++; 59210696SDavid.Hollister@Sun.COM break; 59310696SDavid.Hollister@Sun.COM case SAS: 59410696SDavid.Hollister@Sun.COM dtype = "SAS"; 59510696SDavid.Hollister@Sun.COM sas_targets++; 59610696SDavid.Hollister@Sun.COM break; 59710696SDavid.Hollister@Sun.COM case EXPANDER: 59810696SDavid.Hollister@Sun.COM dtype = "SMP"; 59910696SDavid.Hollister@Sun.COM smp_targets++; 60010696SDavid.Hollister@Sun.COM break; 60110696SDavid.Hollister@Sun.COM } 60210696SDavid.Hollister@Sun.COM 60310696SDavid.Hollister@Sun.COM if (totals_only) { 60410696SDavid.Hollister@Sun.COM continue; 60510696SDavid.Hollister@Sun.COM } 60610696SDavid.Hollister@Sun.COM 60710696SDavid.Hollister@Sun.COM if (xs.phy) { 60810696SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), xs.phy) == -1) { 60910696SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, xs.phy); 61010696SDavid.Hollister@Sun.COM continue; 61110696SDavid.Hollister@Sun.COM } 61210696SDavid.Hollister@Sun.COM mdb_printf("%4d ", idx); 61310696SDavid.Hollister@Sun.COM print_sas_address(&phy); 61410696SDavid.Hollister@Sun.COM mdb_printf(" %16p", xs.phy); 61510696SDavid.Hollister@Sun.COM } else { 61610696SDavid.Hollister@Sun.COM mdb_printf("%4d %16s", idx, "<no phy avail>"); 61710696SDavid.Hollister@Sun.COM } 61810696SDavid.Hollister@Sun.COM mdb_printf(" %5s", dtype); 61910696SDavid.Hollister@Sun.COM mdb_printf(" %8d", xs.actv_cnt); 62010696SDavid.Hollister@Sun.COM mdb_printf(" %2d", xs.dev_state); 62110696SDavid.Hollister@Sun.COM 62210696SDavid.Hollister@Sun.COM if (verbose) { 62310696SDavid.Hollister@Sun.COM if (xs.new) { 62410696SDavid.Hollister@Sun.COM mdb_printf(" new"); 62510755SJesse.Butler@Sun.COM } 62610755SJesse.Butler@Sun.COM if (xs.assigned) { 62710696SDavid.Hollister@Sun.COM mdb_printf(" assigned"); 62810696SDavid.Hollister@Sun.COM } 62910696SDavid.Hollister@Sun.COM if (xs.draining) { 63010696SDavid.Hollister@Sun.COM mdb_printf(" draining"); 63110696SDavid.Hollister@Sun.COM } 63210696SDavid.Hollister@Sun.COM if (xs.reset_wait) { 63310696SDavid.Hollister@Sun.COM mdb_printf(" reset_wait"); 63410696SDavid.Hollister@Sun.COM } 63510696SDavid.Hollister@Sun.COM if (xs.resetting) { 63610696SDavid.Hollister@Sun.COM mdb_printf(" resetting"); 63710696SDavid.Hollister@Sun.COM } 63810696SDavid.Hollister@Sun.COM if (xs.recover_wait) { 63910696SDavid.Hollister@Sun.COM mdb_printf(" recover_wait"); 64010696SDavid.Hollister@Sun.COM } 64110696SDavid.Hollister@Sun.COM if (xs.recovering) { 64210696SDavid.Hollister@Sun.COM mdb_printf(" recovering"); 64310696SDavid.Hollister@Sun.COM } 64410696SDavid.Hollister@Sun.COM if (xs.event_recovery) { 64510696SDavid.Hollister@Sun.COM mdb_printf(" event recovery"); 64610696SDavid.Hollister@Sun.COM } 64710696SDavid.Hollister@Sun.COM if (xs.special_running) { 64810696SDavid.Hollister@Sun.COM mdb_printf(" special_active"); 64910696SDavid.Hollister@Sun.COM } 65010696SDavid.Hollister@Sun.COM if (xs.ncq) { 65110696SDavid.Hollister@Sun.COM mdb_printf(" ncq_tagmap=0x%x qdepth=%d", 65210696SDavid.Hollister@Sun.COM xs.tagmap, xs.qdepth); 65310696SDavid.Hollister@Sun.COM } else if (xs.pio) { 65410696SDavid.Hollister@Sun.COM mdb_printf(" pio"); 65510696SDavid.Hollister@Sun.COM } 65610696SDavid.Hollister@Sun.COM } 65710696SDavid.Hollister@Sun.COM 65810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 65910696SDavid.Hollister@Sun.COM } 66010696SDavid.Hollister@Sun.COM 66110696SDavid.Hollister@Sun.COM if (!totals_only) { 66210696SDavid.Hollister@Sun.COM mdb_printf("\n"); 66310696SDavid.Hollister@Sun.COM } 66410696SDavid.Hollister@Sun.COM 66510696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP)\n", 66610696SDavid.Hollister@Sun.COM "Configured targets:", (sas_targets + sata_targets + smp_targets), 66710696SDavid.Hollister@Sun.COM sas_targets, sata_targets, smp_targets); 66810696SDavid.Hollister@Sun.COM } 66910696SDavid.Hollister@Sun.COM 67010743SDavid.Hollister@Sun.COM static char * 67110743SDavid.Hollister@Sun.COM work_state_to_string(uint32_t state) 67210743SDavid.Hollister@Sun.COM { 67310743SDavid.Hollister@Sun.COM char *state_string; 67410743SDavid.Hollister@Sun.COM 67510743SDavid.Hollister@Sun.COM switch (state) { 67610743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_NIL: 67710743SDavid.Hollister@Sun.COM state_string = "Free"; 67810743SDavid.Hollister@Sun.COM break; 67910743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_READY: 68010743SDavid.Hollister@Sun.COM state_string = "Ready"; 68110743SDavid.Hollister@Sun.COM break; 68210743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_ONCHIP: 68310743SDavid.Hollister@Sun.COM state_string = "On Chip"; 68410743SDavid.Hollister@Sun.COM break; 68510743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_INTR: 68610743SDavid.Hollister@Sun.COM state_string = "In Intr"; 68710743SDavid.Hollister@Sun.COM break; 68810743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_IOCOMPQ: 68910743SDavid.Hollister@Sun.COM state_string = "I/O Comp"; 69010743SDavid.Hollister@Sun.COM break; 69110743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_ABORTED: 69210743SDavid.Hollister@Sun.COM state_string = "I/O Aborted"; 69310743SDavid.Hollister@Sun.COM break; 69410743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_TIMED_OUT: 69510743SDavid.Hollister@Sun.COM state_string = "I/O Timed Out"; 69610743SDavid.Hollister@Sun.COM break; 69710743SDavid.Hollister@Sun.COM default: 69810743SDavid.Hollister@Sun.COM state_string = "INVALID"; 69910743SDavid.Hollister@Sun.COM break; 70010743SDavid.Hollister@Sun.COM } 70110743SDavid.Hollister@Sun.COM 70210743SDavid.Hollister@Sun.COM return (state_string); 70310743SDavid.Hollister@Sun.COM } 70410743SDavid.Hollister@Sun.COM 70510743SDavid.Hollister@Sun.COM static void 70610743SDavid.Hollister@Sun.COM display_one_work(pmcwork_t *wp, int verbose, int idx) 70710743SDavid.Hollister@Sun.COM { 70810743SDavid.Hollister@Sun.COM char *state, *last_state; 70910743SDavid.Hollister@Sun.COM char *path; 71010743SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 71110743SDavid.Hollister@Sun.COM pmcs_phy_t phy; 71210743SDavid.Hollister@Sun.COM int tgt; 71310743SDavid.Hollister@Sun.COM 71410743SDavid.Hollister@Sun.COM state = work_state_to_string(wp->state); 71510743SDavid.Hollister@Sun.COM last_state = work_state_to_string(wp->last_state); 71610743SDavid.Hollister@Sun.COM 71710743SDavid.Hollister@Sun.COM if (wp->ssp_event && wp->ssp_event != 0xffffffff) { 71810743SDavid.Hollister@Sun.COM mdb_printf("SSP event 0x%x", wp->ssp_event); 71910743SDavid.Hollister@Sun.COM } 72010743SDavid.Hollister@Sun.COM 72110743SDavid.Hollister@Sun.COM tgt = -1; 72210743SDavid.Hollister@Sun.COM if (wp->xp) { 72310743SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), wp->xp) == -1) { 72410743SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, wp->xp); 72510743SDavid.Hollister@Sun.COM } else { 72610743SDavid.Hollister@Sun.COM tgt = xs.target_num; 72710743SDavid.Hollister@Sun.COM } 72810743SDavid.Hollister@Sun.COM } 72910743SDavid.Hollister@Sun.COM if (wp->phy) { 73010743SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), wp->phy) == -1) { 73110743SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, wp->phy); 73210743SDavid.Hollister@Sun.COM } 73310743SDavid.Hollister@Sun.COM path = phy.path; 73410743SDavid.Hollister@Sun.COM } else { 73510743SDavid.Hollister@Sun.COM path = "N/A"; 73610743SDavid.Hollister@Sun.COM } 73710743SDavid.Hollister@Sun.COM 73810743SDavid.Hollister@Sun.COM if (verbose) { 73910743SDavid.Hollister@Sun.COM mdb_printf("%4d ", idx); 74010743SDavid.Hollister@Sun.COM } 74110743SDavid.Hollister@Sun.COM if (tgt == -1) { 74210743SDavid.Hollister@Sun.COM mdb_printf("%08x %10s %20s N/A %8u %1d %1d ", 74310743SDavid.Hollister@Sun.COM wp->htag, state, path, wp->timer, 74410743SDavid.Hollister@Sun.COM wp->onwire, wp->dead); 74510743SDavid.Hollister@Sun.COM } else { 74610743SDavid.Hollister@Sun.COM mdb_printf("%08x %10s %20s %8d %8u %1d %1d ", 74710743SDavid.Hollister@Sun.COM wp->htag, state, path, tgt, wp->timer, 74810743SDavid.Hollister@Sun.COM wp->onwire, wp->dead); 74910743SDavid.Hollister@Sun.COM } 75010743SDavid.Hollister@Sun.COM if (verbose) { 75110743SDavid.Hollister@Sun.COM mdb_printf("%08x %10s 0x%016p 0x%016p\n", 75210743SDavid.Hollister@Sun.COM wp->last_htag, last_state, wp->last_phy, wp->last_xp); 75310743SDavid.Hollister@Sun.COM } else { 75410743SDavid.Hollister@Sun.COM mdb_printf("\n"); 75510743SDavid.Hollister@Sun.COM } 75610743SDavid.Hollister@Sun.COM } 75710743SDavid.Hollister@Sun.COM 75810696SDavid.Hollister@Sun.COM static void 75910696SDavid.Hollister@Sun.COM display_work(struct pmcs_hw m, int verbose) 76010696SDavid.Hollister@Sun.COM { 76110696SDavid.Hollister@Sun.COM int idx; 76210743SDavid.Hollister@Sun.COM boolean_t header_printed = B_FALSE; 76310696SDavid.Hollister@Sun.COM pmcwork_t work, *wp = &work; 76410696SDavid.Hollister@Sun.COM uintptr_t _wp; 76510696SDavid.Hollister@Sun.COM 76610696SDavid.Hollister@Sun.COM mdb_printf("\nActive Work structure information:\n"); 76710696SDavid.Hollister@Sun.COM mdb_printf("----------------------------------\n"); 76810696SDavid.Hollister@Sun.COM 76910696SDavid.Hollister@Sun.COM _wp = (uintptr_t)m.work; 77010696SDavid.Hollister@Sun.COM 77110696SDavid.Hollister@Sun.COM for (idx = 0; idx < m.max_cmd; idx++, _wp += sizeof (pmcwork_t)) { 77210696SDavid.Hollister@Sun.COM if (MDB_RD(&work, sizeof (pmcwork_t), _wp) == -1) { 77310696SDavid.Hollister@Sun.COM NOREAD(pmcwork_t, _wp); 77410696SDavid.Hollister@Sun.COM continue; 77510696SDavid.Hollister@Sun.COM } 77610743SDavid.Hollister@Sun.COM 77710743SDavid.Hollister@Sun.COM if (!verbose && (wp->htag == PMCS_TAG_TYPE_FREE)) { 77810696SDavid.Hollister@Sun.COM continue; 77910696SDavid.Hollister@Sun.COM } 78010743SDavid.Hollister@Sun.COM 78110743SDavid.Hollister@Sun.COM if (header_printed == B_FALSE) { 78210743SDavid.Hollister@Sun.COM if (verbose) { 78310743SDavid.Hollister@Sun.COM mdb_printf("%4s ", "Idx"); 78410743SDavid.Hollister@Sun.COM } 78510743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D ", 78610696SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 78710743SDavid.Hollister@Sun.COM if (verbose) { 78810743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %18s %18s\n", "LastHTAG", 78910743SDavid.Hollister@Sun.COM "LastState", "LastPHY", "LastTgt"); 79010743SDavid.Hollister@Sun.COM } else { 79110743SDavid.Hollister@Sun.COM mdb_printf("\n"); 79210743SDavid.Hollister@Sun.COM } 79310743SDavid.Hollister@Sun.COM header_printed = B_TRUE; 79410696SDavid.Hollister@Sun.COM } 79510743SDavid.Hollister@Sun.COM 79610743SDavid.Hollister@Sun.COM display_one_work(wp, verbose, idx); 79710696SDavid.Hollister@Sun.COM } 79810696SDavid.Hollister@Sun.COM } 79910696SDavid.Hollister@Sun.COM 80010696SDavid.Hollister@Sun.COM static void 80110743SDavid.Hollister@Sun.COM print_spcmd(pmcs_cmd_t *sp, void *kaddr, int printhdr, int verbose) 80210696SDavid.Hollister@Sun.COM { 80310743SDavid.Hollister@Sun.COM int cdb_size, idx; 80410743SDavid.Hollister@Sun.COM struct scsi_pkt pkt; 80510743SDavid.Hollister@Sun.COM uchar_t cdb[256]; 80610743SDavid.Hollister@Sun.COM 80710696SDavid.Hollister@Sun.COM if (printhdr) { 80810743SDavid.Hollister@Sun.COM if (verbose) { 80910743SDavid.Hollister@Sun.COM mdb_printf("%16s %16s %16s %8s %s CDB\n", "Command", 81010743SDavid.Hollister@Sun.COM "SCSA pkt", "DMA Chunks", "HTAG", "SATL Tag"); 81110743SDavid.Hollister@Sun.COM } else { 81210743SDavid.Hollister@Sun.COM mdb_printf("%16s %16s %16s %8s %s\n", "Command", 81310743SDavid.Hollister@Sun.COM "SCSA pkt", "DMA Chunks", "HTAG", "SATL Tag"); 81410743SDavid.Hollister@Sun.COM } 81510696SDavid.Hollister@Sun.COM } 81610743SDavid.Hollister@Sun.COM 81710743SDavid.Hollister@Sun.COM mdb_printf("%16p %16p %16p %08x %08x ", 81810696SDavid.Hollister@Sun.COM kaddr, sp->cmd_pkt, sp->cmd_clist, sp->cmd_tag, sp->cmd_satltag); 81910743SDavid.Hollister@Sun.COM 82010743SDavid.Hollister@Sun.COM /* 82110743SDavid.Hollister@Sun.COM * If we're printing verbose, dump the CDB as well. 82210743SDavid.Hollister@Sun.COM */ 82310743SDavid.Hollister@Sun.COM if (verbose) { 82410743SDavid.Hollister@Sun.COM if (sp->cmd_pkt) { 82510743SDavid.Hollister@Sun.COM if (mdb_vread(&pkt, sizeof (struct scsi_pkt), 82610743SDavid.Hollister@Sun.COM (uintptr_t)sp->cmd_pkt) != 82710743SDavid.Hollister@Sun.COM sizeof (struct scsi_pkt)) { 82810743SDavid.Hollister@Sun.COM mdb_warn("Unable to read SCSI pkt\n"); 82910743SDavid.Hollister@Sun.COM return; 83010743SDavid.Hollister@Sun.COM } 83110743SDavid.Hollister@Sun.COM cdb_size = pkt.pkt_cdblen; 83210743SDavid.Hollister@Sun.COM if (mdb_vread(&cdb[0], cdb_size, 83310743SDavid.Hollister@Sun.COM (uintptr_t)pkt.pkt_cdbp) != cdb_size) { 83410743SDavid.Hollister@Sun.COM mdb_warn("Unable to read CDB\n"); 83510743SDavid.Hollister@Sun.COM return; 83610743SDavid.Hollister@Sun.COM } 83710743SDavid.Hollister@Sun.COM 83810743SDavid.Hollister@Sun.COM for (idx = 0; idx < cdb_size; idx++) { 83910743SDavid.Hollister@Sun.COM mdb_printf("%02x ", cdb[idx]); 84010743SDavid.Hollister@Sun.COM } 84110743SDavid.Hollister@Sun.COM } else { 84210743SDavid.Hollister@Sun.COM mdb_printf("N/A"); 84310743SDavid.Hollister@Sun.COM } 84410743SDavid.Hollister@Sun.COM 84510743SDavid.Hollister@Sun.COM mdb_printf("\n"); 84610743SDavid.Hollister@Sun.COM } else { 84710743SDavid.Hollister@Sun.COM mdb_printf("\n"); 84810743SDavid.Hollister@Sun.COM } 84910696SDavid.Hollister@Sun.COM } 85010696SDavid.Hollister@Sun.COM 85110696SDavid.Hollister@Sun.COM /*ARGSUSED1*/ 85210696SDavid.Hollister@Sun.COM static void 85310696SDavid.Hollister@Sun.COM display_waitqs(struct pmcs_hw m, int verbose) 85410696SDavid.Hollister@Sun.COM { 85510696SDavid.Hollister@Sun.COM pmcs_cmd_t *sp, s; 85610696SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 85710696SDavid.Hollister@Sun.COM int first, i; 85810696SDavid.Hollister@Sun.COM int max_dev = m.max_dev; 85910696SDavid.Hollister@Sun.COM 86010696SDavid.Hollister@Sun.COM sp = m.dq.stqh_first; 86110696SDavid.Hollister@Sun.COM first = 1; 86210696SDavid.Hollister@Sun.COM while (sp) { 86310696SDavid.Hollister@Sun.COM if (first) { 86410696SDavid.Hollister@Sun.COM mdb_printf("\nDead Command Queue:\n"); 86510696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 86610696SDavid.Hollister@Sun.COM } 86710696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 86810696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 86910696SDavid.Hollister@Sun.COM break; 87010696SDavid.Hollister@Sun.COM } 87110743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 87210696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 87310696SDavid.Hollister@Sun.COM first = 0; 87410696SDavid.Hollister@Sun.COM } 87510696SDavid.Hollister@Sun.COM 87610696SDavid.Hollister@Sun.COM sp = m.cq.stqh_first; 87710696SDavid.Hollister@Sun.COM first = 1; 87810696SDavid.Hollister@Sun.COM while (sp) { 87910696SDavid.Hollister@Sun.COM if (first) { 88010696SDavid.Hollister@Sun.COM mdb_printf("\nCompletion Command Queue:\n"); 88110696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 88210696SDavid.Hollister@Sun.COM } 88310696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 88410696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 88510696SDavid.Hollister@Sun.COM break; 88610696SDavid.Hollister@Sun.COM } 88710743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 88810696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 88910696SDavid.Hollister@Sun.COM first = 0; 89010696SDavid.Hollister@Sun.COM } 89110696SDavid.Hollister@Sun.COM 89210696SDavid.Hollister@Sun.COM 89310696SDavid.Hollister@Sun.COM if (targets == NULL) { 89410696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * max_dev, UM_SLEEP); 89510696SDavid.Hollister@Sun.COM } 89610696SDavid.Hollister@Sun.COM 89710696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * max_dev, m.targets) == -1) { 89810696SDavid.Hollister@Sun.COM NOREAD(targets, m.targets); 89910696SDavid.Hollister@Sun.COM return; 90010696SDavid.Hollister@Sun.COM } 90110696SDavid.Hollister@Sun.COM 90210696SDavid.Hollister@Sun.COM for (i = 0; i < max_dev; i++) { 90310696SDavid.Hollister@Sun.COM if (targets[i] == NULL) { 90410696SDavid.Hollister@Sun.COM continue; 90510696SDavid.Hollister@Sun.COM } 90610696SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), targets[i]) == -1) { 90710696SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, targets[i]); 90810696SDavid.Hollister@Sun.COM continue; 90910696SDavid.Hollister@Sun.COM } 91010696SDavid.Hollister@Sun.COM sp = xs.wq.stqh_first; 91110696SDavid.Hollister@Sun.COM first = 1; 91210696SDavid.Hollister@Sun.COM while (sp) { 91310696SDavid.Hollister@Sun.COM if (first) { 91410696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Wait Queue:\n", 91510696SDavid.Hollister@Sun.COM xs.target_num); 91610696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 91710696SDavid.Hollister@Sun.COM } 91810696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 91910696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 92010696SDavid.Hollister@Sun.COM break; 92110696SDavid.Hollister@Sun.COM } 92210743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 92310696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 92410696SDavid.Hollister@Sun.COM first = 0; 92510696SDavid.Hollister@Sun.COM } 92610696SDavid.Hollister@Sun.COM sp = xs.aq.stqh_first; 92710696SDavid.Hollister@Sun.COM first = 1; 92810696SDavid.Hollister@Sun.COM while (sp) { 92910696SDavid.Hollister@Sun.COM if (first) { 93010696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Active Queue:\n", 93110696SDavid.Hollister@Sun.COM xs.target_num); 93210696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 93310696SDavid.Hollister@Sun.COM } 93410696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 93510696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 93610696SDavid.Hollister@Sun.COM break; 93710696SDavid.Hollister@Sun.COM } 93810743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 93910696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 94010696SDavid.Hollister@Sun.COM first = 0; 94110696SDavid.Hollister@Sun.COM } 94210696SDavid.Hollister@Sun.COM sp = xs.sq.stqh_first; 94310696SDavid.Hollister@Sun.COM first = 1; 94410696SDavid.Hollister@Sun.COM while (sp) { 94510696SDavid.Hollister@Sun.COM if (first) { 94610696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Special Queue:\n", 94710696SDavid.Hollister@Sun.COM xs.target_num); 94810696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 94910696SDavid.Hollister@Sun.COM } 95010696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 95110696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 95210696SDavid.Hollister@Sun.COM break; 95310696SDavid.Hollister@Sun.COM } 95410743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 95510696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 95610696SDavid.Hollister@Sun.COM first = 0; 95710696SDavid.Hollister@Sun.COM } 95810696SDavid.Hollister@Sun.COM } 95910696SDavid.Hollister@Sun.COM } 96010696SDavid.Hollister@Sun.COM 96110696SDavid.Hollister@Sun.COM static char * 96210696SDavid.Hollister@Sun.COM ibq_type(int qnum) 96310696SDavid.Hollister@Sun.COM { 96410696SDavid.Hollister@Sun.COM if (qnum < 0 || qnum >= PMCS_NIQ) { 96510696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 96610696SDavid.Hollister@Sun.COM } 96710696SDavid.Hollister@Sun.COM 96810696SDavid.Hollister@Sun.COM if (qnum < PMCS_IQ_OTHER) { 96910696SDavid.Hollister@Sun.COM return ("I/O"); 97010696SDavid.Hollister@Sun.COM } 97110696SDavid.Hollister@Sun.COM 97210696SDavid.Hollister@Sun.COM return ("Other"); 97310696SDavid.Hollister@Sun.COM } 97410696SDavid.Hollister@Sun.COM 97510696SDavid.Hollister@Sun.COM static char * 97610696SDavid.Hollister@Sun.COM obq_type(int qnum) 97710696SDavid.Hollister@Sun.COM { 97810696SDavid.Hollister@Sun.COM switch (qnum) { 97910696SDavid.Hollister@Sun.COM case PMCS_OQ_IODONE: 98010696SDavid.Hollister@Sun.COM return ("I/O"); 98110696SDavid.Hollister@Sun.COM break; 98210696SDavid.Hollister@Sun.COM case PMCS_OQ_GENERAL: 98310696SDavid.Hollister@Sun.COM return ("General"); 98410696SDavid.Hollister@Sun.COM break; 98510696SDavid.Hollister@Sun.COM case PMCS_OQ_EVENTS: 98610696SDavid.Hollister@Sun.COM return ("Events"); 98710696SDavid.Hollister@Sun.COM break; 98810696SDavid.Hollister@Sun.COM default: 98910696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 99010696SDavid.Hollister@Sun.COM } 99110696SDavid.Hollister@Sun.COM } 99210696SDavid.Hollister@Sun.COM 99310696SDavid.Hollister@Sun.COM static char * 99410696SDavid.Hollister@Sun.COM iomb_cat(uint32_t cat) 99510696SDavid.Hollister@Sun.COM { 99610696SDavid.Hollister@Sun.COM switch (cat) { 99710696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_NET: 99810696SDavid.Hollister@Sun.COM return ("NET"); 99910696SDavid.Hollister@Sun.COM break; 100010696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_FC: 100110696SDavid.Hollister@Sun.COM return ("FC"); 100210696SDavid.Hollister@Sun.COM break; 100310696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_SAS: 100410696SDavid.Hollister@Sun.COM return ("SAS"); 100510696SDavid.Hollister@Sun.COM break; 100610696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_SCSI: 100710696SDavid.Hollister@Sun.COM return ("SCSI"); 100810696SDavid.Hollister@Sun.COM break; 100910696SDavid.Hollister@Sun.COM default: 101010696SDavid.Hollister@Sun.COM return ("???"); 101110696SDavid.Hollister@Sun.COM } 101210696SDavid.Hollister@Sun.COM } 101310696SDavid.Hollister@Sun.COM 101410696SDavid.Hollister@Sun.COM static char * 101510696SDavid.Hollister@Sun.COM inbound_iomb_opcode(uint32_t opcode) 101610696SDavid.Hollister@Sun.COM { 101710696SDavid.Hollister@Sun.COM switch (opcode) { 101810696SDavid.Hollister@Sun.COM case PMCIN_ECHO: 101910696SDavid.Hollister@Sun.COM return ("ECHO"); 102010696SDavid.Hollister@Sun.COM break; 102110696SDavid.Hollister@Sun.COM case PMCIN_GET_INFO: 102210696SDavid.Hollister@Sun.COM return ("GET_INFO"); 102310696SDavid.Hollister@Sun.COM break; 102410696SDavid.Hollister@Sun.COM case PMCIN_GET_VPD: 102510696SDavid.Hollister@Sun.COM return ("GET_VPD"); 102610696SDavid.Hollister@Sun.COM break; 102710696SDavid.Hollister@Sun.COM case PMCIN_PHY_START: 102810696SDavid.Hollister@Sun.COM return ("PHY_START"); 102910696SDavid.Hollister@Sun.COM break; 103010696SDavid.Hollister@Sun.COM case PMCIN_PHY_STOP: 103110696SDavid.Hollister@Sun.COM return ("PHY_STOP"); 103210696SDavid.Hollister@Sun.COM break; 103310696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_IO_START: 103410696SDavid.Hollister@Sun.COM return ("INI_IO_START"); 103510696SDavid.Hollister@Sun.COM break; 103610696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_TM_START: 103710696SDavid.Hollister@Sun.COM return ("INI_TM_START"); 103810696SDavid.Hollister@Sun.COM break; 103910696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EXT_IO_START: 104010696SDavid.Hollister@Sun.COM return ("INI_EXT_IO_START"); 104110696SDavid.Hollister@Sun.COM break; 104210696SDavid.Hollister@Sun.COM case PMCIN_DEVICE_HANDLE_ACCEPT: 104310696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_ACCEPT"); 104410696SDavid.Hollister@Sun.COM break; 104510696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_IO_START: 104610696SDavid.Hollister@Sun.COM return ("TGT_IO_START"); 104710696SDavid.Hollister@Sun.COM break; 104810696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_RESPONSE_START: 104910696SDavid.Hollister@Sun.COM return ("TGT_RESPONSE_START"); 105010696SDavid.Hollister@Sun.COM break; 105110696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EDC_EXT_IO_START: 105210696SDavid.Hollister@Sun.COM return ("INI_EDC_EXT_IO_START"); 105310696SDavid.Hollister@Sun.COM break; 105410696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EDC_EXT_IO_START1: 105510696SDavid.Hollister@Sun.COM return ("INI_EDC_EXT_IO_START1"); 105610696SDavid.Hollister@Sun.COM break; 105710696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_EDC_IO_START: 105810696SDavid.Hollister@Sun.COM return ("TGT_EDC_IO_START"); 105910696SDavid.Hollister@Sun.COM break; 106010696SDavid.Hollister@Sun.COM case PMCIN_SSP_ABORT: 106110696SDavid.Hollister@Sun.COM return ("SSP_ABORT"); 106210696SDavid.Hollister@Sun.COM break; 106310696SDavid.Hollister@Sun.COM case PMCIN_DEREGISTER_DEVICE_HANDLE: 106410696SDavid.Hollister@Sun.COM return ("DEREGISTER_DEVICE_HANDLE"); 106510696SDavid.Hollister@Sun.COM break; 106610696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_HANDLE: 106710696SDavid.Hollister@Sun.COM return ("GET_DEVICE_HANDLE"); 106810696SDavid.Hollister@Sun.COM break; 106910696SDavid.Hollister@Sun.COM case PMCIN_SMP_REQUEST: 107010696SDavid.Hollister@Sun.COM return ("SMP_REQUEST"); 107110696SDavid.Hollister@Sun.COM break; 107210696SDavid.Hollister@Sun.COM case PMCIN_SMP_RESPONSE: 107310696SDavid.Hollister@Sun.COM return ("SMP_RESPONSE"); 107410696SDavid.Hollister@Sun.COM break; 107510696SDavid.Hollister@Sun.COM case PMCIN_SMP_ABORT: 107610696SDavid.Hollister@Sun.COM return ("SMP_ABORT"); 107710696SDavid.Hollister@Sun.COM break; 107810696SDavid.Hollister@Sun.COM case PMCIN_ASSISTED_DISCOVERY: 107910696SDavid.Hollister@Sun.COM return ("ASSISTED_DISCOVERY"); 108010696SDavid.Hollister@Sun.COM break; 108110696SDavid.Hollister@Sun.COM case PMCIN_REGISTER_DEVICE: 108210696SDavid.Hollister@Sun.COM return ("REGISTER_DEVICE"); 108310696SDavid.Hollister@Sun.COM break; 108410696SDavid.Hollister@Sun.COM case PMCIN_SATA_HOST_IO_START: 108510696SDavid.Hollister@Sun.COM return ("SATA_HOST_IO_START"); 108610696SDavid.Hollister@Sun.COM break; 108710696SDavid.Hollister@Sun.COM case PMCIN_SATA_ABORT: 108810696SDavid.Hollister@Sun.COM return ("SATA_ABORT"); 108910696SDavid.Hollister@Sun.COM break; 109010696SDavid.Hollister@Sun.COM case PMCIN_LOCAL_PHY_CONTROL: 109110696SDavid.Hollister@Sun.COM return ("LOCAL_PHY_CONTROL"); 109210696SDavid.Hollister@Sun.COM break; 109310696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_INFO: 109410696SDavid.Hollister@Sun.COM return ("GET_DEVICE_INFO"); 109510696SDavid.Hollister@Sun.COM break; 109610696SDavid.Hollister@Sun.COM case PMCIN_TWI: 109710696SDavid.Hollister@Sun.COM return ("TWI"); 109810696SDavid.Hollister@Sun.COM break; 109910696SDavid.Hollister@Sun.COM case PMCIN_FW_FLASH_UPDATE: 110010696SDavid.Hollister@Sun.COM return ("FW_FLASH_UPDATE"); 110110696SDavid.Hollister@Sun.COM break; 110210696SDavid.Hollister@Sun.COM case PMCIN_SET_VPD: 110310696SDavid.Hollister@Sun.COM return ("SET_VPD"); 110410696SDavid.Hollister@Sun.COM break; 110510696SDavid.Hollister@Sun.COM case PMCIN_GPIO: 110610696SDavid.Hollister@Sun.COM return ("GPIO"); 110710696SDavid.Hollister@Sun.COM break; 110810696SDavid.Hollister@Sun.COM case PMCIN_SAS_DIAG_MODE_START_END: 110910696SDavid.Hollister@Sun.COM return ("SAS_DIAG_MODE_START_END"); 111010696SDavid.Hollister@Sun.COM break; 111110696SDavid.Hollister@Sun.COM case PMCIN_SAS_DIAG_EXECUTE: 111210696SDavid.Hollister@Sun.COM return ("SAS_DIAG_EXECUTE"); 111310696SDavid.Hollister@Sun.COM break; 111410696SDavid.Hollister@Sun.COM case PMCIN_SAW_HW_EVENT_ACK: 111510696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT_ACK"); 111610696SDavid.Hollister@Sun.COM break; 111710696SDavid.Hollister@Sun.COM case PMCIN_GET_TIME_STAMP: 111810696SDavid.Hollister@Sun.COM return ("GET_TIME_STAMP"); 111910696SDavid.Hollister@Sun.COM break; 112010696SDavid.Hollister@Sun.COM case PMCIN_PORT_CONTROL: 112110696SDavid.Hollister@Sun.COM return ("PORT_CONTROL"); 112210696SDavid.Hollister@Sun.COM break; 112310696SDavid.Hollister@Sun.COM case PMCIN_GET_NVMD_DATA: 112410696SDavid.Hollister@Sun.COM return ("GET_NVMD_DATA"); 112510696SDavid.Hollister@Sun.COM break; 112610696SDavid.Hollister@Sun.COM case PMCIN_SET_NVMD_DATA: 112710696SDavid.Hollister@Sun.COM return ("SET_NVMD_DATA"); 112810696SDavid.Hollister@Sun.COM break; 112910696SDavid.Hollister@Sun.COM case PMCIN_SET_DEVICE_STATE: 113010696SDavid.Hollister@Sun.COM return ("SET_DEVICE_STATE"); 113110696SDavid.Hollister@Sun.COM break; 113210696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_STATE: 113310696SDavid.Hollister@Sun.COM return ("GET_DEVICE_STATE"); 113410696SDavid.Hollister@Sun.COM break; 113510696SDavid.Hollister@Sun.COM default: 113610696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 113710696SDavid.Hollister@Sun.COM break; 113810696SDavid.Hollister@Sun.COM } 113910696SDavid.Hollister@Sun.COM } 114010696SDavid.Hollister@Sun.COM 114110696SDavid.Hollister@Sun.COM static char * 114210696SDavid.Hollister@Sun.COM outbound_iomb_opcode(uint32_t opcode) 114310696SDavid.Hollister@Sun.COM { 114410696SDavid.Hollister@Sun.COM switch (opcode) { 114510696SDavid.Hollister@Sun.COM case PMCOUT_ECHO: 114610696SDavid.Hollister@Sun.COM return ("ECHO"); 114710696SDavid.Hollister@Sun.COM break; 114810696SDavid.Hollister@Sun.COM case PMCOUT_GET_INFO: 114910696SDavid.Hollister@Sun.COM return ("GET_INFO"); 115010696SDavid.Hollister@Sun.COM break; 115110696SDavid.Hollister@Sun.COM case PMCOUT_GET_VPD: 115210696SDavid.Hollister@Sun.COM return ("GET_VPD"); 115310696SDavid.Hollister@Sun.COM break; 115410696SDavid.Hollister@Sun.COM case PMCOUT_SAS_HW_EVENT: 115510696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT"); 115610696SDavid.Hollister@Sun.COM break; 115710696SDavid.Hollister@Sun.COM case PMCOUT_SSP_COMPLETION: 115810696SDavid.Hollister@Sun.COM return ("SSP_COMPLETION"); 115910696SDavid.Hollister@Sun.COM break; 116010696SDavid.Hollister@Sun.COM case PMCOUT_SMP_COMPLETION: 116110696SDavid.Hollister@Sun.COM return ("SMP_COMPLETION"); 116210696SDavid.Hollister@Sun.COM break; 116310696SDavid.Hollister@Sun.COM case PMCOUT_LOCAL_PHY_CONTROL: 116410696SDavid.Hollister@Sun.COM return ("LOCAL_PHY_CONTROL"); 116510696SDavid.Hollister@Sun.COM break; 116610696SDavid.Hollister@Sun.COM case PMCOUT_SAS_ASSISTED_DISCOVERY_EVENT: 116710696SDavid.Hollister@Sun.COM return ("SAS_ASSISTED_DISCOVERY_SENT"); 116810696SDavid.Hollister@Sun.COM break; 116910696SDavid.Hollister@Sun.COM case PMCOUT_SATA_ASSISTED_DISCOVERY_EVENT: 117010696SDavid.Hollister@Sun.COM return ("SATA_ASSISTED_DISCOVERY_SENT"); 117110696SDavid.Hollister@Sun.COM break; 117210696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_REGISTRATION: 117310696SDavid.Hollister@Sun.COM return ("DEVICE_REGISTRATION"); 117410696SDavid.Hollister@Sun.COM break; 117510696SDavid.Hollister@Sun.COM case PMCOUT_DEREGISTER_DEVICE_HANDLE: 117610696SDavid.Hollister@Sun.COM return ("DEREGISTER_DEVICE_HANDLE"); 117710696SDavid.Hollister@Sun.COM break; 117810696SDavid.Hollister@Sun.COM case PMCOUT_GET_DEVICE_HANDLE: 117910696SDavid.Hollister@Sun.COM return ("GET_DEVICE_HANDLE"); 118010696SDavid.Hollister@Sun.COM break; 118110696SDavid.Hollister@Sun.COM case PMCOUT_SATA_COMPLETION: 118210696SDavid.Hollister@Sun.COM return ("SATA_COMPLETION"); 118310696SDavid.Hollister@Sun.COM break; 118410696SDavid.Hollister@Sun.COM case PMCOUT_SATA_EVENT: 118510696SDavid.Hollister@Sun.COM return ("SATA_EVENT"); 118610696SDavid.Hollister@Sun.COM break; 118710696SDavid.Hollister@Sun.COM case PMCOUT_SSP_EVENT: 118810696SDavid.Hollister@Sun.COM return ("SSP_EVENT"); 118910696SDavid.Hollister@Sun.COM break; 119010696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_HANDLE_ARRIVED: 119110696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_ARRIVED"); 119210696SDavid.Hollister@Sun.COM break; 119310696SDavid.Hollister@Sun.COM case PMCOUT_SMP_REQUEST_RECEIVED: 119410696SDavid.Hollister@Sun.COM return ("SMP_REQUEST_RECEIVED"); 119510696SDavid.Hollister@Sun.COM break; 119610696SDavid.Hollister@Sun.COM case PMCOUT_SSP_REQUEST_RECEIVED: 119710696SDavid.Hollister@Sun.COM return ("SSP_REQUEST_RECEIVED"); 119810696SDavid.Hollister@Sun.COM break; 119910696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_INFO: 120010696SDavid.Hollister@Sun.COM return ("DEVICE_INFO"); 120110696SDavid.Hollister@Sun.COM break; 120210696SDavid.Hollister@Sun.COM case PMCOUT_FW_FLASH_UPDATE: 120310696SDavid.Hollister@Sun.COM return ("FW_FLASH_UPDATE"); 120410696SDavid.Hollister@Sun.COM break; 120510696SDavid.Hollister@Sun.COM case PMCOUT_SET_VPD: 120610696SDavid.Hollister@Sun.COM return ("SET_VPD"); 120710696SDavid.Hollister@Sun.COM break; 120810696SDavid.Hollister@Sun.COM case PMCOUT_GPIO: 120910696SDavid.Hollister@Sun.COM return ("GPIO"); 121010696SDavid.Hollister@Sun.COM break; 121110696SDavid.Hollister@Sun.COM case PMCOUT_GPIO_EVENT: 121210696SDavid.Hollister@Sun.COM return ("GPIO_EVENT"); 121310696SDavid.Hollister@Sun.COM break; 121410696SDavid.Hollister@Sun.COM case PMCOUT_GENERAL_EVENT: 121510696SDavid.Hollister@Sun.COM return ("GENERAL_EVENT"); 121610696SDavid.Hollister@Sun.COM break; 121710696SDavid.Hollister@Sun.COM case PMCOUT_TWI: 121810696SDavid.Hollister@Sun.COM return ("TWI"); 121910696SDavid.Hollister@Sun.COM break; 122010696SDavid.Hollister@Sun.COM case PMCOUT_SSP_ABORT: 122110696SDavid.Hollister@Sun.COM return ("SSP_ABORT"); 122210696SDavid.Hollister@Sun.COM break; 122310696SDavid.Hollister@Sun.COM case PMCOUT_SATA_ABORT: 122410696SDavid.Hollister@Sun.COM return ("SATA_ABORT"); 122510696SDavid.Hollister@Sun.COM break; 122610696SDavid.Hollister@Sun.COM case PMCOUT_SAS_DIAG_MODE_START_END: 122710696SDavid.Hollister@Sun.COM return ("SAS_DIAG_MODE_START_END"); 122810696SDavid.Hollister@Sun.COM break; 122910696SDavid.Hollister@Sun.COM case PMCOUT_SAS_DIAG_EXECUTE: 123010696SDavid.Hollister@Sun.COM return ("SAS_DIAG_EXECUTE"); 123110696SDavid.Hollister@Sun.COM break; 123210696SDavid.Hollister@Sun.COM case PMCOUT_GET_TIME_STAMP: 123310696SDavid.Hollister@Sun.COM return ("GET_TIME_STAMP"); 123410696SDavid.Hollister@Sun.COM break; 123510696SDavid.Hollister@Sun.COM case PMCOUT_SAS_HW_EVENT_ACK_ACK: 123610696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT_ACK_ACK"); 123710696SDavid.Hollister@Sun.COM break; 123810696SDavid.Hollister@Sun.COM case PMCOUT_PORT_CONTROL: 123910696SDavid.Hollister@Sun.COM return ("PORT_CONTROL"); 124010696SDavid.Hollister@Sun.COM break; 124110696SDavid.Hollister@Sun.COM case PMCOUT_SKIP_ENTRIES: 124210696SDavid.Hollister@Sun.COM return ("SKIP_ENTRIES"); 124310696SDavid.Hollister@Sun.COM break; 124410696SDavid.Hollister@Sun.COM case PMCOUT_SMP_ABORT: 124510696SDavid.Hollister@Sun.COM return ("SMP_ABORT"); 124610696SDavid.Hollister@Sun.COM break; 124710696SDavid.Hollister@Sun.COM case PMCOUT_GET_NVMD_DATA: 124810696SDavid.Hollister@Sun.COM return ("GET_NVMD_DATA"); 124910696SDavid.Hollister@Sun.COM break; 125010696SDavid.Hollister@Sun.COM case PMCOUT_SET_NVMD_DATA: 125110696SDavid.Hollister@Sun.COM return ("SET_NVMD_DATA"); 125210696SDavid.Hollister@Sun.COM break; 125310696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_HANDLE_REMOVED: 125410696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_REMOVED"); 125510696SDavid.Hollister@Sun.COM break; 125610696SDavid.Hollister@Sun.COM case PMCOUT_SET_DEVICE_STATE: 125710696SDavid.Hollister@Sun.COM return ("SET_DEVICE_STATE"); 125810696SDavid.Hollister@Sun.COM break; 125910696SDavid.Hollister@Sun.COM case PMCOUT_GET_DEVICE_STATE: 126010696SDavid.Hollister@Sun.COM return ("GET_DEVICE_STATE"); 126110696SDavid.Hollister@Sun.COM break; 126210696SDavid.Hollister@Sun.COM case PMCOUT_SET_DEVICE_INFO: 126310696SDavid.Hollister@Sun.COM return ("SET_DEVICE_INFO"); 126410696SDavid.Hollister@Sun.COM break; 126510696SDavid.Hollister@Sun.COM default: 126610696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 126710696SDavid.Hollister@Sun.COM break; 126810696SDavid.Hollister@Sun.COM } 126910696SDavid.Hollister@Sun.COM } 127010696SDavid.Hollister@Sun.COM 127110696SDavid.Hollister@Sun.COM static void 127210696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(uint32_t *qentryp, int idx) 127310696SDavid.Hollister@Sun.COM { 127410696SDavid.Hollister@Sun.COM int qeidx; 127510696SDavid.Hollister@Sun.COM uint32_t word0 = LE_32(*qentryp); 127610696SDavid.Hollister@Sun.COM 127710696SDavid.Hollister@Sun.COM mdb_printf("Entry #%02d\n", idx); 127810696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 127910696SDavid.Hollister@Sun.COM 128010696SDavid.Hollister@Sun.COM mdb_printf("Header: 0x%08x (", word0); 128110696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_VALID) { 128210696SDavid.Hollister@Sun.COM mdb_printf("VALID, "); 128310696SDavid.Hollister@Sun.COM } 128410696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_HIPRI) { 128510696SDavid.Hollister@Sun.COM mdb_printf("HIPRI, "); 128610696SDavid.Hollister@Sun.COM } 128710696SDavid.Hollister@Sun.COM mdb_printf("OBID=%d, ", 128810696SDavid.Hollister@Sun.COM (word0 & PMCS_IOMB_OBID_MASK) >> PMCS_IOMB_OBID_SHIFT); 128910696SDavid.Hollister@Sun.COM mdb_printf("CAT=%s, ", 129010696SDavid.Hollister@Sun.COM iomb_cat((word0 & PMCS_IOMB_CAT_MASK) >> PMCS_IOMB_CAT_SHIFT)); 129110696SDavid.Hollister@Sun.COM mdb_printf("OPCODE=%s", 129210696SDavid.Hollister@Sun.COM outbound_iomb_opcode(word0 & PMCS_IOMB_OPCODE_MASK)); 129310696SDavid.Hollister@Sun.COM mdb_printf(")\n"); 129410696SDavid.Hollister@Sun.COM 129510696SDavid.Hollister@Sun.COM mdb_printf("Remaining Payload:\n"); 129610696SDavid.Hollister@Sun.COM 129710696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 129810696SDavid.Hollister@Sun.COM for (qeidx = 1; qeidx < (PMCS_QENTRY_SIZE / 4); qeidx++) { 129910696SDavid.Hollister@Sun.COM mdb_printf("%08x ", LE_32(*(qentryp + qeidx))); 130010696SDavid.Hollister@Sun.COM } 130110696SDavid.Hollister@Sun.COM mdb_printf("\n"); 130210696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 130310696SDavid.Hollister@Sun.COM } 130410696SDavid.Hollister@Sun.COM 130510696SDavid.Hollister@Sun.COM static void 130610696SDavid.Hollister@Sun.COM display_outbound_queues(struct pmcs_hw ss, uint_t verbose) 130710696SDavid.Hollister@Sun.COM { 130810696SDavid.Hollister@Sun.COM int idx, qidx; 130910696SDavid.Hollister@Sun.COM uintptr_t obqp; 131010696SDavid.Hollister@Sun.COM uint32_t *cip; 131110696SDavid.Hollister@Sun.COM uint32_t *qentryp = mdb_alloc(PMCS_QENTRY_SIZE, UM_SLEEP); 131210696SDavid.Hollister@Sun.COM uint32_t last_consumed, oqpi; 131310696SDavid.Hollister@Sun.COM 131410696SDavid.Hollister@Sun.COM mdb_printf("\n"); 131510696SDavid.Hollister@Sun.COM mdb_printf("Outbound Queues\n"); 131610696SDavid.Hollister@Sun.COM mdb_printf("---------------\n"); 131710696SDavid.Hollister@Sun.COM 131810696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 131910696SDavid.Hollister@Sun.COM 132010696SDavid.Hollister@Sun.COM for (qidx = 0; qidx < PMCS_NOQ; qidx++) { 132110696SDavid.Hollister@Sun.COM obqp = (uintptr_t)ss.oqp[qidx]; 132210696SDavid.Hollister@Sun.COM 132310696SDavid.Hollister@Sun.COM if (obqp == NULL) { 132410696SDavid.Hollister@Sun.COM mdb_printf("No outbound queue ptr for queue #%d\n", 132510696SDavid.Hollister@Sun.COM qidx); 132610696SDavid.Hollister@Sun.COM continue; 132710696SDavid.Hollister@Sun.COM } 132810696SDavid.Hollister@Sun.COM 132910696SDavid.Hollister@Sun.COM mdb_printf("Outbound Queue #%d (Queue Type = %s)\n", qidx, 133010696SDavid.Hollister@Sun.COM obq_type(qidx)); 133110696SDavid.Hollister@Sun.COM /* 133210696SDavid.Hollister@Sun.COM * Chip is the producer, so read the actual producer index 133310696SDavid.Hollister@Sun.COM * and not the driver's version 133410696SDavid.Hollister@Sun.COM */ 133510696SDavid.Hollister@Sun.COM cip = (uint32_t *)((void *)ss.cip); 133610696SDavid.Hollister@Sun.COM if (MDB_RD(&oqpi, 4, cip + OQPI_BASE_OFFSET + 133710696SDavid.Hollister@Sun.COM (qidx * 4)) == -1) { 133810696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read oqpi\n"); 133910696SDavid.Hollister@Sun.COM break; 134010696SDavid.Hollister@Sun.COM } 134110696SDavid.Hollister@Sun.COM 134210696SDavid.Hollister@Sun.COM mdb_printf("Producer index: %d Consumer index: %d\n\n", 134310696SDavid.Hollister@Sun.COM LE_32(oqpi), ss.oqci[qidx]); 134410696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 134510696SDavid.Hollister@Sun.COM 134610696SDavid.Hollister@Sun.COM if (ss.oqci[qidx] == 0) { 134710696SDavid.Hollister@Sun.COM last_consumed = ss.ioq_depth - 1; 134810696SDavid.Hollister@Sun.COM } else { 134910696SDavid.Hollister@Sun.COM last_consumed = ss.oqci[qidx] - 1; 135010696SDavid.Hollister@Sun.COM } 135110696SDavid.Hollister@Sun.COM 135210696SDavid.Hollister@Sun.COM 135310696SDavid.Hollister@Sun.COM if (!verbose) { 135410696SDavid.Hollister@Sun.COM mdb_printf("Last processed entry:\n"); 135510696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 135610696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * last_consumed))) 135710696SDavid.Hollister@Sun.COM == -1) { 135810696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 135910696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * 136010696SDavid.Hollister@Sun.COM last_consumed))); 136110696SDavid.Hollister@Sun.COM break; 136210696SDavid.Hollister@Sun.COM } 136310696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(qentryp, last_consumed); 136410696SDavid.Hollister@Sun.COM mdb_printf("\n"); 136510696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 136610696SDavid.Hollister@Sun.COM continue; 136710696SDavid.Hollister@Sun.COM } 136810696SDavid.Hollister@Sun.COM 136910696SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.ioq_depth; idx++) { 137010696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 137110696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * idx))) == -1) { 137210696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 137310696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * idx))); 137410696SDavid.Hollister@Sun.COM break; 137510696SDavid.Hollister@Sun.COM } 137610696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(qentryp, idx); 137710696SDavid.Hollister@Sun.COM } 137810696SDavid.Hollister@Sun.COM 137910696SDavid.Hollister@Sun.COM mdb_printf("\n"); 138010696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 138110696SDavid.Hollister@Sun.COM } 138210696SDavid.Hollister@Sun.COM 138310696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 138410696SDavid.Hollister@Sun.COM mdb_free(qentryp, PMCS_QENTRY_SIZE); 138510696SDavid.Hollister@Sun.COM } 138610696SDavid.Hollister@Sun.COM 138710696SDavid.Hollister@Sun.COM static void 138810696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(uint32_t *qentryp, int idx) 138910696SDavid.Hollister@Sun.COM { 139010696SDavid.Hollister@Sun.COM int qeidx; 139110696SDavid.Hollister@Sun.COM uint32_t word0 = LE_32(*qentryp); 139210696SDavid.Hollister@Sun.COM 139310696SDavid.Hollister@Sun.COM mdb_printf("Entry #%02d\n", idx); 139410696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 139510696SDavid.Hollister@Sun.COM 139610696SDavid.Hollister@Sun.COM mdb_printf("Header: 0x%08x (", word0); 139710696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_VALID) { 139810696SDavid.Hollister@Sun.COM mdb_printf("VALID, "); 139910696SDavid.Hollister@Sun.COM } 140010696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_HIPRI) { 140110696SDavid.Hollister@Sun.COM mdb_printf("HIPRI, "); 140210696SDavid.Hollister@Sun.COM } 140310696SDavid.Hollister@Sun.COM mdb_printf("OBID=%d, ", 140410696SDavid.Hollister@Sun.COM (word0 & PMCS_IOMB_OBID_MASK) >> PMCS_IOMB_OBID_SHIFT); 140510696SDavid.Hollister@Sun.COM mdb_printf("CAT=%s, ", 140610696SDavid.Hollister@Sun.COM iomb_cat((word0 & PMCS_IOMB_CAT_MASK) >> PMCS_IOMB_CAT_SHIFT)); 140710696SDavid.Hollister@Sun.COM mdb_printf("OPCODE=%s", 140810696SDavid.Hollister@Sun.COM inbound_iomb_opcode(word0 & PMCS_IOMB_OPCODE_MASK)); 140910696SDavid.Hollister@Sun.COM mdb_printf(")\n"); 141010696SDavid.Hollister@Sun.COM 141110696SDavid.Hollister@Sun.COM mdb_printf("HTAG: 0x%08x\n", LE_32(*(qentryp + 1))); 141210696SDavid.Hollister@Sun.COM mdb_printf("Remaining Payload:\n"); 141310696SDavid.Hollister@Sun.COM 141410696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 141510696SDavid.Hollister@Sun.COM for (qeidx = 2; qeidx < (PMCS_QENTRY_SIZE / 4); qeidx++) { 141610696SDavid.Hollister@Sun.COM mdb_printf("%08x ", LE_32(*(qentryp + qeidx))); 141710696SDavid.Hollister@Sun.COM } 141810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 141910696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 142010696SDavid.Hollister@Sun.COM } 142110696SDavid.Hollister@Sun.COM 142210696SDavid.Hollister@Sun.COM static void 142310696SDavid.Hollister@Sun.COM display_inbound_queues(struct pmcs_hw ss, uint_t verbose) 142410696SDavid.Hollister@Sun.COM { 142510696SDavid.Hollister@Sun.COM int idx, qidx, iqci, last_consumed; 142610696SDavid.Hollister@Sun.COM uintptr_t ibqp; 142710696SDavid.Hollister@Sun.COM uint32_t *qentryp = mdb_alloc(PMCS_QENTRY_SIZE, UM_SLEEP); 142810696SDavid.Hollister@Sun.COM uint32_t *cip; 142910696SDavid.Hollister@Sun.COM 143010696SDavid.Hollister@Sun.COM mdb_printf("\n"); 143110696SDavid.Hollister@Sun.COM mdb_printf("Inbound Queues\n"); 143210696SDavid.Hollister@Sun.COM mdb_printf("--------------\n"); 143310696SDavid.Hollister@Sun.COM 143410696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 143510696SDavid.Hollister@Sun.COM 143610696SDavid.Hollister@Sun.COM for (qidx = 0; qidx < PMCS_NIQ; qidx++) { 143710696SDavid.Hollister@Sun.COM ibqp = (uintptr_t)ss.iqp[qidx]; 143810696SDavid.Hollister@Sun.COM 143910696SDavid.Hollister@Sun.COM if (ibqp == NULL) { 144010696SDavid.Hollister@Sun.COM mdb_printf("No inbound queue ptr for queue #%d\n", 144110696SDavid.Hollister@Sun.COM qidx); 144210696SDavid.Hollister@Sun.COM continue; 144310696SDavid.Hollister@Sun.COM } 144410696SDavid.Hollister@Sun.COM 144510696SDavid.Hollister@Sun.COM mdb_printf("Inbound Queue #%d (Queue Type = %s)\n", qidx, 144610696SDavid.Hollister@Sun.COM ibq_type(qidx)); 144710696SDavid.Hollister@Sun.COM 144810696SDavid.Hollister@Sun.COM cip = (uint32_t *)((void *)ss.cip); 144910696SDavid.Hollister@Sun.COM if (MDB_RD(&iqci, 4, cip + (qidx * 4)) == -1) { 145010696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read iqci\n"); 145110696SDavid.Hollister@Sun.COM break; 145210696SDavid.Hollister@Sun.COM } 145310696SDavid.Hollister@Sun.COM iqci = LE_32(iqci); 145410696SDavid.Hollister@Sun.COM 145510696SDavid.Hollister@Sun.COM mdb_printf("Producer index: %d Consumer index: %d\n\n", 145610696SDavid.Hollister@Sun.COM ss.shadow_iqpi[qidx], iqci); 145710696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 145810696SDavid.Hollister@Sun.COM 145910696SDavid.Hollister@Sun.COM if (iqci == 0) { 146010696SDavid.Hollister@Sun.COM last_consumed = ss.ioq_depth - 1; 146110696SDavid.Hollister@Sun.COM } else { 146210696SDavid.Hollister@Sun.COM last_consumed = iqci - 1; 146310696SDavid.Hollister@Sun.COM } 146410696SDavid.Hollister@Sun.COM 146510696SDavid.Hollister@Sun.COM if (!verbose) { 146610696SDavid.Hollister@Sun.COM mdb_printf("Last processed entry:\n"); 146710696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 146810696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * last_consumed))) 146910696SDavid.Hollister@Sun.COM == -1) { 147010696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 147110696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * 147210696SDavid.Hollister@Sun.COM last_consumed))); 147310696SDavid.Hollister@Sun.COM break; 147410696SDavid.Hollister@Sun.COM } 147510696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(qentryp, last_consumed); 147610696SDavid.Hollister@Sun.COM mdb_printf("\n"); 147710696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 147810696SDavid.Hollister@Sun.COM continue; 147910696SDavid.Hollister@Sun.COM } 148010696SDavid.Hollister@Sun.COM 148110696SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.ioq_depth; idx++) { 148210696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 148310696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * idx))) == -1) { 148410696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 148510696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * idx))); 148610696SDavid.Hollister@Sun.COM break; 148710696SDavid.Hollister@Sun.COM } 148810696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(qentryp, idx); 148910696SDavid.Hollister@Sun.COM } 149010696SDavid.Hollister@Sun.COM 149110696SDavid.Hollister@Sun.COM mdb_printf("\n"); 149210696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 149310696SDavid.Hollister@Sun.COM } 149410696SDavid.Hollister@Sun.COM 149510696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 149610696SDavid.Hollister@Sun.COM mdb_free(qentryp, PMCS_QENTRY_SIZE); 149710696SDavid.Hollister@Sun.COM } 149810696SDavid.Hollister@Sun.COM 149910696SDavid.Hollister@Sun.COM static void 150010696SDavid.Hollister@Sun.COM display_phy(struct pmcs_phy phy, int verbose, int totals_only) 150110696SDavid.Hollister@Sun.COM { 150210696SDavid.Hollister@Sun.COM char *dtype, *speed; 150310696SDavid.Hollister@Sun.COM char *yes = "Yes"; 150410696SDavid.Hollister@Sun.COM char *no = "No"; 150510696SDavid.Hollister@Sun.COM char *cfgd = no; 150610696SDavid.Hollister@Sun.COM char *apend = no; 150710696SDavid.Hollister@Sun.COM char *asent = no; 150810696SDavid.Hollister@Sun.COM char *dead = no; 150910696SDavid.Hollister@Sun.COM char *changed = no; 151010696SDavid.Hollister@Sun.COM 151110696SDavid.Hollister@Sun.COM switch (phy.dtype) { 151210696SDavid.Hollister@Sun.COM case NOTHING: 151310696SDavid.Hollister@Sun.COM dtype = "None"; 151410696SDavid.Hollister@Sun.COM break; 151510696SDavid.Hollister@Sun.COM case SATA: 151610696SDavid.Hollister@Sun.COM dtype = "SATA"; 151710696SDavid.Hollister@Sun.COM if (phy.configured) { 151810696SDavid.Hollister@Sun.COM ++sata_phys; 151910696SDavid.Hollister@Sun.COM } 152010696SDavid.Hollister@Sun.COM break; 152110696SDavid.Hollister@Sun.COM case SAS: 152210696SDavid.Hollister@Sun.COM dtype = "SAS"; 152310696SDavid.Hollister@Sun.COM if (phy.configured) { 152410696SDavid.Hollister@Sun.COM ++sas_phys; 152510696SDavid.Hollister@Sun.COM } 152610696SDavid.Hollister@Sun.COM break; 152710696SDavid.Hollister@Sun.COM case EXPANDER: 152810696SDavid.Hollister@Sun.COM dtype = "EXP"; 152910696SDavid.Hollister@Sun.COM if (phy.configured) { 153010696SDavid.Hollister@Sun.COM ++exp_phys; 153110696SDavid.Hollister@Sun.COM } 153210696SDavid.Hollister@Sun.COM break; 153310696SDavid.Hollister@Sun.COM } 153410696SDavid.Hollister@Sun.COM 153510696SDavid.Hollister@Sun.COM if (phy.dtype == NOTHING) { 153610696SDavid.Hollister@Sun.COM empty_phys++; 153710696SDavid.Hollister@Sun.COM } else if ((phy.dtype == EXPANDER) && phy.configured) { 153810696SDavid.Hollister@Sun.COM num_expanders++; 153910696SDavid.Hollister@Sun.COM } 154010696SDavid.Hollister@Sun.COM 154110696SDavid.Hollister@Sun.COM if (totals_only) { 154210696SDavid.Hollister@Sun.COM return; 154310696SDavid.Hollister@Sun.COM } 154410696SDavid.Hollister@Sun.COM 154510696SDavid.Hollister@Sun.COM switch (phy.link_rate) { 154610696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_1_5GBIT: 154710696SDavid.Hollister@Sun.COM speed = "1.5Gb/s"; 154810696SDavid.Hollister@Sun.COM break; 154910696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_3GBIT: 155010696SDavid.Hollister@Sun.COM speed = "3 Gb/s"; 155110696SDavid.Hollister@Sun.COM break; 155210696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_6GBIT: 155310696SDavid.Hollister@Sun.COM speed = "6 Gb/s"; 155410696SDavid.Hollister@Sun.COM break; 155510696SDavid.Hollister@Sun.COM default: 155610696SDavid.Hollister@Sun.COM speed = "N/A"; 155710696SDavid.Hollister@Sun.COM break; 155810696SDavid.Hollister@Sun.COM } 155910696SDavid.Hollister@Sun.COM 156010696SDavid.Hollister@Sun.COM if ((phy.dtype != NOTHING) || verbose) { 156110696SDavid.Hollister@Sun.COM print_sas_address(&phy); 156210696SDavid.Hollister@Sun.COM 156310696SDavid.Hollister@Sun.COM if (phy.device_id != PMCS_INVALID_DEVICE_ID) { 156410696SDavid.Hollister@Sun.COM mdb_printf(" %3d %4d %6s %4s ", 156510696SDavid.Hollister@Sun.COM phy.device_id, phy.phynum, speed, dtype); 156610696SDavid.Hollister@Sun.COM } else { 156710696SDavid.Hollister@Sun.COM mdb_printf(" N/A %4d %6s %4s ", 156810696SDavid.Hollister@Sun.COM phy.phynum, speed, dtype); 156910696SDavid.Hollister@Sun.COM } 157010696SDavid.Hollister@Sun.COM 157110696SDavid.Hollister@Sun.COM if (verbose) { 157210696SDavid.Hollister@Sun.COM if (phy.abort_sent) { 157310696SDavid.Hollister@Sun.COM asent = yes; 157410696SDavid.Hollister@Sun.COM } 157510696SDavid.Hollister@Sun.COM if (phy.abort_pending) { 157610696SDavid.Hollister@Sun.COM apend = yes; 157710696SDavid.Hollister@Sun.COM } 157810696SDavid.Hollister@Sun.COM if (phy.configured) { 157910696SDavid.Hollister@Sun.COM cfgd = yes; 158010696SDavid.Hollister@Sun.COM } 158110696SDavid.Hollister@Sun.COM if (phy.dead) { 158210696SDavid.Hollister@Sun.COM dead = yes; 158310696SDavid.Hollister@Sun.COM } 158410696SDavid.Hollister@Sun.COM if (phy.changed) { 158510696SDavid.Hollister@Sun.COM changed = yes; 158610696SDavid.Hollister@Sun.COM } 158710696SDavid.Hollister@Sun.COM 158810696SDavid.Hollister@Sun.COM mdb_printf("%-4s %-4s %-4s %-4s %-4s %3d " 158910696SDavid.Hollister@Sun.COM "0x%p ", cfgd, apend, asent, 159010696SDavid.Hollister@Sun.COM changed, dead, phy.ref_count, phy.phy_lock); 159110696SDavid.Hollister@Sun.COM } 159210696SDavid.Hollister@Sun.COM 159310696SDavid.Hollister@Sun.COM mdb_printf("Path: %s\n", phy.path); 159410696SDavid.Hollister@Sun.COM } 159510696SDavid.Hollister@Sun.COM } 159610696SDavid.Hollister@Sun.COM 159710696SDavid.Hollister@Sun.COM static void 159810696SDavid.Hollister@Sun.COM display_phys(struct pmcs_hw ss, int verbose, struct pmcs_phy *parent, int level, 159910696SDavid.Hollister@Sun.COM int totals_only) 160010696SDavid.Hollister@Sun.COM { 160110696SDavid.Hollister@Sun.COM pmcs_phy_t phy; 160210696SDavid.Hollister@Sun.COM pmcs_phy_t *pphy = parent; 160310696SDavid.Hollister@Sun.COM 160410696SDavid.Hollister@Sun.COM mdb_inc_indent(3); 160510696SDavid.Hollister@Sun.COM 160610696SDavid.Hollister@Sun.COM if (parent == NULL) { 160710696SDavid.Hollister@Sun.COM pphy = (pmcs_phy_t *)ss.root_phys; 160810696SDavid.Hollister@Sun.COM } else { 160910696SDavid.Hollister@Sun.COM pphy = (pmcs_phy_t *)parent; 161010696SDavid.Hollister@Sun.COM } 161110696SDavid.Hollister@Sun.COM 161210696SDavid.Hollister@Sun.COM if (level == 0) { 161310696SDavid.Hollister@Sun.COM sas_phys = 0; 161410696SDavid.Hollister@Sun.COM sata_phys = 0; 161510696SDavid.Hollister@Sun.COM exp_phys = 0; 161610696SDavid.Hollister@Sun.COM num_expanders = 0; 161710696SDavid.Hollister@Sun.COM empty_phys = 0; 161810696SDavid.Hollister@Sun.COM } 161910696SDavid.Hollister@Sun.COM 162010696SDavid.Hollister@Sun.COM if (!totals_only) { 162110696SDavid.Hollister@Sun.COM if (level == 0) { 162210696SDavid.Hollister@Sun.COM mdb_printf("PHY information\n"); 162310696SDavid.Hollister@Sun.COM } 162410696SDavid.Hollister@Sun.COM mdb_printf("--------\n"); 162510696SDavid.Hollister@Sun.COM mdb_printf("Level %2d\n", level); 162610696SDavid.Hollister@Sun.COM mdb_printf("--------\n"); 162710696SDavid.Hollister@Sun.COM mdb_printf("SAS Address Hdl Phy# Speed Type "); 162810696SDavid.Hollister@Sun.COM 162910696SDavid.Hollister@Sun.COM if (verbose) { 163010696SDavid.Hollister@Sun.COM mdb_printf("Cfgd AbtP AbtS Chgd Dead Ref Lock\n"); 163110696SDavid.Hollister@Sun.COM } else { 163210696SDavid.Hollister@Sun.COM mdb_printf("\n"); 163310696SDavid.Hollister@Sun.COM } 163410696SDavid.Hollister@Sun.COM } 163510696SDavid.Hollister@Sun.COM 163610696SDavid.Hollister@Sun.COM while (pphy) { 163710696SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), (uintptr_t)pphy) == -1) { 163810696SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, phy); 163910696SDavid.Hollister@Sun.COM break; 164010696SDavid.Hollister@Sun.COM } 164110696SDavid.Hollister@Sun.COM 164210696SDavid.Hollister@Sun.COM display_phy(phy, verbose, totals_only); 164310696SDavid.Hollister@Sun.COM 164410696SDavid.Hollister@Sun.COM if (phy.children) { 164510696SDavid.Hollister@Sun.COM display_phys(ss, verbose, phy.children, level + 1, 164610696SDavid.Hollister@Sun.COM totals_only); 164710696SDavid.Hollister@Sun.COM if (!totals_only) { 164810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 164910696SDavid.Hollister@Sun.COM } 165010696SDavid.Hollister@Sun.COM } 165110696SDavid.Hollister@Sun.COM 165210696SDavid.Hollister@Sun.COM pphy = phy.sibling; 165310696SDavid.Hollister@Sun.COM } 165410696SDavid.Hollister@Sun.COM 165510696SDavid.Hollister@Sun.COM mdb_dec_indent(3); 165610696SDavid.Hollister@Sun.COM 165710696SDavid.Hollister@Sun.COM if (level == 0) { 165810696SDavid.Hollister@Sun.COM if (verbose) { 165910696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP) " 166010696SDavid.Hollister@Sun.COM "(+%d subsidiary + %d empty)\n", "Occupied PHYs:", 166110696SDavid.Hollister@Sun.COM (sas_phys + sata_phys + num_expanders), 166210696SDavid.Hollister@Sun.COM sas_phys, sata_phys, num_expanders, 166310696SDavid.Hollister@Sun.COM (exp_phys - num_expanders), empty_phys); 166410696SDavid.Hollister@Sun.COM } else { 166510696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP)\n", 166610696SDavid.Hollister@Sun.COM "Occupied PHYs:", 166710696SDavid.Hollister@Sun.COM (sas_phys + sata_phys + num_expanders), 166810696SDavid.Hollister@Sun.COM sas_phys, sata_phys, num_expanders); 166910696SDavid.Hollister@Sun.COM } 167010696SDavid.Hollister@Sun.COM } 167110696SDavid.Hollister@Sun.COM } 167210696SDavid.Hollister@Sun.COM 167310696SDavid.Hollister@Sun.COM /* 167411048SDavid.Hollister@Sun.COM * filter is used to indicate whether we are filtering log messages based 167511048SDavid.Hollister@Sun.COM * on "instance". The other filtering (based on options) depends on the 167611048SDavid.Hollister@Sun.COM * values that are passed in for "sas_addr" and "phy_path". 167711048SDavid.Hollister@Sun.COM * 167810696SDavid.Hollister@Sun.COM * MAX_INST_STRLEN is the largest string size from which we will attempt 167910696SDavid.Hollister@Sun.COM * to convert to an instance number. The string will be formed up as 168010696SDavid.Hollister@Sun.COM * "0t<inst>\0" so that mdb_strtoull can parse it properly. 168110696SDavid.Hollister@Sun.COM */ 168210696SDavid.Hollister@Sun.COM #define MAX_INST_STRLEN 8 168310696SDavid.Hollister@Sun.COM 168410696SDavid.Hollister@Sun.COM static int 168511048SDavid.Hollister@Sun.COM pmcs_dump_tracelog(boolean_t filter, int instance, const char *phy_path, 168611048SDavid.Hollister@Sun.COM uint64_t sas_address) 168710696SDavid.Hollister@Sun.COM { 168810696SDavid.Hollister@Sun.COM pmcs_tbuf_t *tbuf_addr; 168910696SDavid.Hollister@Sun.COM uint_t tbuf_idx; 169010696SDavid.Hollister@Sun.COM pmcs_tbuf_t tbuf; 169110696SDavid.Hollister@Sun.COM boolean_t wrap, elem_filtered; 169210696SDavid.Hollister@Sun.COM uint_t start_idx, elems_to_print, idx, tbuf_num_elems; 169310696SDavid.Hollister@Sun.COM char *bufp; 169410696SDavid.Hollister@Sun.COM char elem_inst[MAX_INST_STRLEN], ei_idx; 169511048SDavid.Hollister@Sun.COM uint64_t sas_addr; 169611048SDavid.Hollister@Sun.COM uint8_t *sas_addressp; 169710696SDavid.Hollister@Sun.COM 169810696SDavid.Hollister@Sun.COM /* Get the address of the first element */ 169910696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_addr, "pmcs_tbuf") == -1) { 170010696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf"); 170110696SDavid.Hollister@Sun.COM return (DCMD_ERR); 170210696SDavid.Hollister@Sun.COM } 170310696SDavid.Hollister@Sun.COM 170410696SDavid.Hollister@Sun.COM /* Get the total number */ 170510696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_num_elems, "pmcs_tbuf_num_elems") == -1) { 170610696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_num_elems"); 170710696SDavid.Hollister@Sun.COM return (DCMD_ERR); 170810696SDavid.Hollister@Sun.COM } 170910696SDavid.Hollister@Sun.COM 171010696SDavid.Hollister@Sun.COM /* Get the current index */ 171110696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_idx, "pmcs_tbuf_idx") == -1) { 171210696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_idx"); 171310696SDavid.Hollister@Sun.COM return (DCMD_ERR); 171410696SDavid.Hollister@Sun.COM } 171510696SDavid.Hollister@Sun.COM 171610696SDavid.Hollister@Sun.COM /* Indicator as to whether the buffer has wrapped */ 171710696SDavid.Hollister@Sun.COM if (mdb_readvar(&wrap, "pmcs_tbuf_wrap") == -1) { 171810696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_wrap"); 171910696SDavid.Hollister@Sun.COM return (DCMD_ERR); 172010696SDavid.Hollister@Sun.COM } 172110696SDavid.Hollister@Sun.COM 172211048SDavid.Hollister@Sun.COM /* 172311048SDavid.Hollister@Sun.COM * On little-endian systems, the SAS address passed in will be 172411048SDavid.Hollister@Sun.COM * byte swapped. Take care of that here. 172511048SDavid.Hollister@Sun.COM */ 172611048SDavid.Hollister@Sun.COM #if defined(_LITTLE_ENDIAN) 172711048SDavid.Hollister@Sun.COM sas_addr = ((sas_address << 56) | 172811048SDavid.Hollister@Sun.COM ((sas_address << 40) & 0xff000000000000ULL) | 172911048SDavid.Hollister@Sun.COM ((sas_address << 24) & 0xff0000000000ULL) | 173011048SDavid.Hollister@Sun.COM ((sas_address << 8) & 0xff00000000ULL) | 173111048SDavid.Hollister@Sun.COM ((sas_address >> 8) & 0xff000000ULL) | 173211048SDavid.Hollister@Sun.COM ((sas_address >> 24) & 0xff0000ULL) | 173311048SDavid.Hollister@Sun.COM ((sas_address >> 40) & 0xff00ULL) | 173411048SDavid.Hollister@Sun.COM (sas_address >> 56)); 173511048SDavid.Hollister@Sun.COM #else 173611048SDavid.Hollister@Sun.COM sas_addr = sas_address; 173711048SDavid.Hollister@Sun.COM #endif 173811048SDavid.Hollister@Sun.COM sas_addressp = (uint8_t *)&sas_addr; 173911048SDavid.Hollister@Sun.COM 174010696SDavid.Hollister@Sun.COM /* Figure out where we start and stop */ 174110696SDavid.Hollister@Sun.COM if (wrap) { 174210696SDavid.Hollister@Sun.COM start_idx = tbuf_idx; 174310696SDavid.Hollister@Sun.COM elems_to_print = tbuf_num_elems; 174410696SDavid.Hollister@Sun.COM } else { 174510696SDavid.Hollister@Sun.COM start_idx = 0; 174610696SDavid.Hollister@Sun.COM elems_to_print = tbuf_idx; 174710696SDavid.Hollister@Sun.COM } 174810696SDavid.Hollister@Sun.COM 174910696SDavid.Hollister@Sun.COM idx = start_idx; 175010696SDavid.Hollister@Sun.COM 175110696SDavid.Hollister@Sun.COM /* Dump the buffer contents */ 175210696SDavid.Hollister@Sun.COM while (elems_to_print != 0) { 175310696SDavid.Hollister@Sun.COM if (MDB_RD(&tbuf, sizeof (pmcs_tbuf_t), (tbuf_addr + idx)) 175410696SDavid.Hollister@Sun.COM == -1) { 175510696SDavid.Hollister@Sun.COM NOREAD(tbuf, (tbuf_addr + idx)); 175610696SDavid.Hollister@Sun.COM return (DCMD_ERR); 175710696SDavid.Hollister@Sun.COM } 175810696SDavid.Hollister@Sun.COM 175911048SDavid.Hollister@Sun.COM /* 176011048SDavid.Hollister@Sun.COM * Check for filtering on HBA instance 176111048SDavid.Hollister@Sun.COM */ 176210696SDavid.Hollister@Sun.COM elem_filtered = B_FALSE; 176310696SDavid.Hollister@Sun.COM 176410696SDavid.Hollister@Sun.COM if (filter) { 176510696SDavid.Hollister@Sun.COM bufp = tbuf.buf; 176610696SDavid.Hollister@Sun.COM /* Skip the driver name */ 176710696SDavid.Hollister@Sun.COM while (*bufp < '0' || *bufp > '9') { 176810696SDavid.Hollister@Sun.COM bufp++; 176910696SDavid.Hollister@Sun.COM } 177010696SDavid.Hollister@Sun.COM 177110696SDavid.Hollister@Sun.COM ei_idx = 0; 177210696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = '0'; 177310696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = 't'; 177410696SDavid.Hollister@Sun.COM while (*bufp != ':' && ei_idx < (MAX_INST_STRLEN - 1)) { 177510696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = *bufp; 177610696SDavid.Hollister@Sun.COM bufp++; 177710696SDavid.Hollister@Sun.COM } 177810696SDavid.Hollister@Sun.COM elem_inst[ei_idx] = 0; 177910696SDavid.Hollister@Sun.COM 178010696SDavid.Hollister@Sun.COM /* Get the instance */ 178110696SDavid.Hollister@Sun.COM if ((int)mdb_strtoull(elem_inst) != instance) { 178210696SDavid.Hollister@Sun.COM elem_filtered = B_TRUE; 178310696SDavid.Hollister@Sun.COM } 178410696SDavid.Hollister@Sun.COM } 178510696SDavid.Hollister@Sun.COM 178611048SDavid.Hollister@Sun.COM if (!elem_filtered && (phy_path || sas_address)) { 178711048SDavid.Hollister@Sun.COM /* 178811048SDavid.Hollister@Sun.COM * This message is not being filtered by HBA instance. 178911048SDavid.Hollister@Sun.COM * Now check to see if we're filtering based on 179011048SDavid.Hollister@Sun.COM * PHY path or SAS address. 179111048SDavid.Hollister@Sun.COM * Filtering is an "OR" operation. So, if any of the 179211048SDavid.Hollister@Sun.COM * criteria matches, this message will be printed. 179311048SDavid.Hollister@Sun.COM */ 179411048SDavid.Hollister@Sun.COM elem_filtered = B_TRUE; 179511048SDavid.Hollister@Sun.COM 179611048SDavid.Hollister@Sun.COM if (phy_path != NULL) { 179711048SDavid.Hollister@Sun.COM if (strncmp(phy_path, tbuf.phy_path, 179811048SDavid.Hollister@Sun.COM PMCS_TBUF_UA_MAX_SIZE) == 0) { 179911048SDavid.Hollister@Sun.COM elem_filtered = B_FALSE; 180011048SDavid.Hollister@Sun.COM } 180111048SDavid.Hollister@Sun.COM } 180211048SDavid.Hollister@Sun.COM if (sas_address != 0) { 180311048SDavid.Hollister@Sun.COM if (memcmp(sas_addressp, tbuf.phy_sas_address, 180411048SDavid.Hollister@Sun.COM 8) == 0) { 180511048SDavid.Hollister@Sun.COM elem_filtered = B_FALSE; 180611048SDavid.Hollister@Sun.COM } 180711048SDavid.Hollister@Sun.COM } 180811048SDavid.Hollister@Sun.COM } 180911048SDavid.Hollister@Sun.COM 181010696SDavid.Hollister@Sun.COM if (!elem_filtered) { 181110696SDavid.Hollister@Sun.COM mdb_printf("%Y.%09ld %s\n", tbuf.timestamp, tbuf.buf); 181210696SDavid.Hollister@Sun.COM } 181310696SDavid.Hollister@Sun.COM 181410696SDavid.Hollister@Sun.COM --elems_to_print; 181510696SDavid.Hollister@Sun.COM if (++idx == tbuf_num_elems) { 181610696SDavid.Hollister@Sun.COM idx = 0; 181710696SDavid.Hollister@Sun.COM } 181810696SDavid.Hollister@Sun.COM } 181910696SDavid.Hollister@Sun.COM 182010696SDavid.Hollister@Sun.COM return (DCMD_OK); 182110696SDavid.Hollister@Sun.COM } 182210696SDavid.Hollister@Sun.COM 182310696SDavid.Hollister@Sun.COM /* 182410696SDavid.Hollister@Sun.COM * Walkers 182510696SDavid.Hollister@Sun.COM */ 182610696SDavid.Hollister@Sun.COM static int 182710696SDavid.Hollister@Sun.COM targets_walk_i(mdb_walk_state_t *wsp) 182810696SDavid.Hollister@Sun.COM { 182910696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 183010696SDavid.Hollister@Sun.COM mdb_warn("Can not perform global walk\n"); 183110696SDavid.Hollister@Sun.COM return (WALK_ERR); 183210696SDavid.Hollister@Sun.COM } 183310696SDavid.Hollister@Sun.COM 183410696SDavid.Hollister@Sun.COM /* 183510696SDavid.Hollister@Sun.COM * Address provided belongs to HBA softstate. Get the targets pointer 183610696SDavid.Hollister@Sun.COM * to begin the walk. 183710696SDavid.Hollister@Sun.COM */ 183810696SDavid.Hollister@Sun.COM if (mdb_vread(&ss, sizeof (pmcs_hw_t), wsp->walk_addr) != 183910696SDavid.Hollister@Sun.COM sizeof (pmcs_hw_t)) { 184010696SDavid.Hollister@Sun.COM mdb_warn("Unable to read HBA softstate\n"); 184110696SDavid.Hollister@Sun.COM return (WALK_ERR); 184210696SDavid.Hollister@Sun.COM } 184310696SDavid.Hollister@Sun.COM 184410696SDavid.Hollister@Sun.COM if (targets == NULL) { 184510696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * ss.max_dev, UM_SLEEP); 184610696SDavid.Hollister@Sun.COM } 184710696SDavid.Hollister@Sun.COM 184810696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * ss.max_dev, ss.targets) == -1) { 184910696SDavid.Hollister@Sun.COM NOREAD(targets, ss.targets); 185010696SDavid.Hollister@Sun.COM return (WALK_ERR); 185110696SDavid.Hollister@Sun.COM } 185210696SDavid.Hollister@Sun.COM 185310696SDavid.Hollister@Sun.COM target_idx = 0; 185410696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(targets[0]); 185510696SDavid.Hollister@Sun.COM wsp->walk_data = mdb_alloc(sizeof (pmcs_xscsi_t), UM_SLEEP); 185610696SDavid.Hollister@Sun.COM 185710696SDavid.Hollister@Sun.COM return (WALK_NEXT); 185810696SDavid.Hollister@Sun.COM } 185910696SDavid.Hollister@Sun.COM 186010696SDavid.Hollister@Sun.COM static int 186110696SDavid.Hollister@Sun.COM targets_walk_s(mdb_walk_state_t *wsp) 186210696SDavid.Hollister@Sun.COM { 186310696SDavid.Hollister@Sun.COM int status; 186410696SDavid.Hollister@Sun.COM 186510696SDavid.Hollister@Sun.COM if (target_idx == ss.max_dev) { 186610696SDavid.Hollister@Sun.COM return (WALK_DONE); 186710696SDavid.Hollister@Sun.COM } 186810696SDavid.Hollister@Sun.COM 186910696SDavid.Hollister@Sun.COM if (mdb_vread(wsp->walk_data, sizeof (pmcs_xscsi_t), 187010696SDavid.Hollister@Sun.COM wsp->walk_addr) == -1) { 187110696SDavid.Hollister@Sun.COM mdb_warn("Failed to read target at %p", (void *)wsp->walk_addr); 187210696SDavid.Hollister@Sun.COM return (WALK_DONE); 187310696SDavid.Hollister@Sun.COM } 187410696SDavid.Hollister@Sun.COM 187510696SDavid.Hollister@Sun.COM status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 187610696SDavid.Hollister@Sun.COM wsp->walk_cbdata); 187710696SDavid.Hollister@Sun.COM 187810696SDavid.Hollister@Sun.COM do { 187910696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(targets[++target_idx]); 188010696SDavid.Hollister@Sun.COM } while ((wsp->walk_addr == NULL) && (target_idx < ss.max_dev)); 188110696SDavid.Hollister@Sun.COM 188210696SDavid.Hollister@Sun.COM if (target_idx == ss.max_dev) { 188310696SDavid.Hollister@Sun.COM return (WALK_DONE); 188410696SDavid.Hollister@Sun.COM } 188510696SDavid.Hollister@Sun.COM 188610696SDavid.Hollister@Sun.COM return (status); 188710696SDavid.Hollister@Sun.COM } 188810696SDavid.Hollister@Sun.COM 188910696SDavid.Hollister@Sun.COM static void 189010696SDavid.Hollister@Sun.COM targets_walk_f(mdb_walk_state_t *wsp) 189110696SDavid.Hollister@Sun.COM { 189210696SDavid.Hollister@Sun.COM mdb_free(wsp->walk_data, sizeof (pmcs_xscsi_t)); 189310696SDavid.Hollister@Sun.COM } 189410696SDavid.Hollister@Sun.COM 189510696SDavid.Hollister@Sun.COM 189610696SDavid.Hollister@Sun.COM static pmcs_phy_t * 189710696SDavid.Hollister@Sun.COM pmcs_next_sibling(pmcs_phy_t *phyp) 189810696SDavid.Hollister@Sun.COM { 189910696SDavid.Hollister@Sun.COM pmcs_phy_t parent; 190010696SDavid.Hollister@Sun.COM 190110696SDavid.Hollister@Sun.COM /* 190210696SDavid.Hollister@Sun.COM * First, if this is a root PHY, there are no more siblings 190310696SDavid.Hollister@Sun.COM */ 190410696SDavid.Hollister@Sun.COM if (phyp->level == 0) { 190510696SDavid.Hollister@Sun.COM return (NULL); 190610696SDavid.Hollister@Sun.COM } 190710696SDavid.Hollister@Sun.COM 190810696SDavid.Hollister@Sun.COM /* 190910696SDavid.Hollister@Sun.COM * Otherwise, next sibling is the parent's sibling 191010696SDavid.Hollister@Sun.COM */ 191110696SDavid.Hollister@Sun.COM while (phyp->level > 0) { 191210696SDavid.Hollister@Sun.COM if (mdb_vread(&parent, sizeof (pmcs_phy_t), 191310696SDavid.Hollister@Sun.COM (uintptr_t)phyp->parent) == -1) { 191410696SDavid.Hollister@Sun.COM mdb_warn("pmcs_next_sibling: Failed to read PHY at %p", 191510696SDavid.Hollister@Sun.COM (void *)phyp->parent); 191610696SDavid.Hollister@Sun.COM return (NULL); 191710696SDavid.Hollister@Sun.COM } 191810696SDavid.Hollister@Sun.COM 191910696SDavid.Hollister@Sun.COM if (parent.sibling != NULL) { 192010696SDavid.Hollister@Sun.COM break; 192110696SDavid.Hollister@Sun.COM } 192210696SDavid.Hollister@Sun.COM 192310696SDavid.Hollister@Sun.COM phyp = phyp->parent; 192410696SDavid.Hollister@Sun.COM } 192510696SDavid.Hollister@Sun.COM 192610696SDavid.Hollister@Sun.COM return (parent.sibling); 192710696SDavid.Hollister@Sun.COM } 192810696SDavid.Hollister@Sun.COM 192910696SDavid.Hollister@Sun.COM static int 193010696SDavid.Hollister@Sun.COM phy_walk_i(mdb_walk_state_t *wsp) 193110696SDavid.Hollister@Sun.COM { 193210696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 193310696SDavid.Hollister@Sun.COM mdb_warn("Can not perform global walk\n"); 193410696SDavid.Hollister@Sun.COM return (WALK_ERR); 193510696SDavid.Hollister@Sun.COM } 193610696SDavid.Hollister@Sun.COM 193710696SDavid.Hollister@Sun.COM /* 193810696SDavid.Hollister@Sun.COM * Address provided belongs to HBA softstate. Get the targets pointer 193910696SDavid.Hollister@Sun.COM * to begin the walk. 194010696SDavid.Hollister@Sun.COM */ 194110696SDavid.Hollister@Sun.COM if (mdb_vread(&ss, sizeof (pmcs_hw_t), wsp->walk_addr) != 194210696SDavid.Hollister@Sun.COM sizeof (pmcs_hw_t)) { 194310696SDavid.Hollister@Sun.COM mdb_warn("Unable to read HBA softstate\n"); 194410696SDavid.Hollister@Sun.COM return (WALK_ERR); 194510696SDavid.Hollister@Sun.COM } 194610696SDavid.Hollister@Sun.COM 194710696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(ss.root_phys); 194810696SDavid.Hollister@Sun.COM wsp->walk_data = mdb_alloc(sizeof (pmcs_phy_t), UM_SLEEP); 194910696SDavid.Hollister@Sun.COM 195010696SDavid.Hollister@Sun.COM return (WALK_NEXT); 195110696SDavid.Hollister@Sun.COM } 195210696SDavid.Hollister@Sun.COM 195310696SDavid.Hollister@Sun.COM static int 195410696SDavid.Hollister@Sun.COM phy_walk_s(mdb_walk_state_t *wsp) 195510696SDavid.Hollister@Sun.COM { 195610696SDavid.Hollister@Sun.COM pmcs_phy_t *phyp, *nphyp; 195710696SDavid.Hollister@Sun.COM int status; 195810696SDavid.Hollister@Sun.COM 195910696SDavid.Hollister@Sun.COM if (mdb_vread(wsp->walk_data, sizeof (pmcs_phy_t), 196010696SDavid.Hollister@Sun.COM wsp->walk_addr) == -1) { 196110696SDavid.Hollister@Sun.COM mdb_warn("phy_walk_s: Failed to read PHY at %p", 196210696SDavid.Hollister@Sun.COM (void *)wsp->walk_addr); 196310696SDavid.Hollister@Sun.COM return (WALK_DONE); 196410696SDavid.Hollister@Sun.COM } 196510696SDavid.Hollister@Sun.COM 196610696SDavid.Hollister@Sun.COM status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 196710696SDavid.Hollister@Sun.COM wsp->walk_cbdata); 196810696SDavid.Hollister@Sun.COM 196910696SDavid.Hollister@Sun.COM phyp = (pmcs_phy_t *)wsp->walk_data; 197010696SDavid.Hollister@Sun.COM if (phyp->children) { 197110696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(phyp->children); 197210696SDavid.Hollister@Sun.COM } else { 197310696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(phyp->sibling); 197410696SDavid.Hollister@Sun.COM } 197510696SDavid.Hollister@Sun.COM 197610696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 197710696SDavid.Hollister@Sun.COM /* 197810696SDavid.Hollister@Sun.COM * We reached the end of this sibling list. Trudge back up 197910696SDavid.Hollister@Sun.COM * to the parent and find the next sibling after the expander 198010696SDavid.Hollister@Sun.COM * we just finished traversing, if there is one. 198110696SDavid.Hollister@Sun.COM */ 198210696SDavid.Hollister@Sun.COM nphyp = pmcs_next_sibling(phyp); 198310696SDavid.Hollister@Sun.COM 198410696SDavid.Hollister@Sun.COM if (nphyp == NULL) { 198510696SDavid.Hollister@Sun.COM return (WALK_DONE); 198610696SDavid.Hollister@Sun.COM } 198710696SDavid.Hollister@Sun.COM 198810696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)nphyp; 198910696SDavid.Hollister@Sun.COM } 199010696SDavid.Hollister@Sun.COM 199110696SDavid.Hollister@Sun.COM return (status); 199210696SDavid.Hollister@Sun.COM } 199310696SDavid.Hollister@Sun.COM 199410696SDavid.Hollister@Sun.COM static void 199510696SDavid.Hollister@Sun.COM phy_walk_f(mdb_walk_state_t *wsp) 199610696SDavid.Hollister@Sun.COM { 199710696SDavid.Hollister@Sun.COM mdb_free(wsp->walk_data, sizeof (pmcs_phy_t)); 199810696SDavid.Hollister@Sun.COM } 199910696SDavid.Hollister@Sun.COM 200010743SDavid.Hollister@Sun.COM static void 200110743SDavid.Hollister@Sun.COM display_matching_work(struct pmcs_hw ss, uintmax_t index, uintmax_t snum, 200210743SDavid.Hollister@Sun.COM uintmax_t tag_type) 200310743SDavid.Hollister@Sun.COM { 200410743SDavid.Hollister@Sun.COM int idx; 200510743SDavid.Hollister@Sun.COM pmcwork_t work, *wp = &work; 200610743SDavid.Hollister@Sun.COM uintptr_t _wp; 200710743SDavid.Hollister@Sun.COM boolean_t printed_header = B_FALSE; 200810743SDavid.Hollister@Sun.COM uint32_t mask, mask_val, match_val; 200910743SDavid.Hollister@Sun.COM char *match_type; 201010743SDavid.Hollister@Sun.COM 201110743SDavid.Hollister@Sun.COM if (index != UINT_MAX) { 201210743SDavid.Hollister@Sun.COM match_type = "index"; 201310743SDavid.Hollister@Sun.COM mask = PMCS_TAG_INDEX_MASK; 201410743SDavid.Hollister@Sun.COM mask_val = index << PMCS_TAG_INDEX_SHIFT; 201510743SDavid.Hollister@Sun.COM match_val = index; 201610743SDavid.Hollister@Sun.COM } else if (snum != UINT_MAX) { 201710743SDavid.Hollister@Sun.COM match_type = "serial number"; 201810743SDavid.Hollister@Sun.COM mask = PMCS_TAG_SERNO_MASK; 201910743SDavid.Hollister@Sun.COM mask_val = snum << PMCS_TAG_SERNO_SHIFT; 202010743SDavid.Hollister@Sun.COM match_val = snum; 202110743SDavid.Hollister@Sun.COM } else { 202210743SDavid.Hollister@Sun.COM switch (tag_type) { 202310743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_NONE: 202410743SDavid.Hollister@Sun.COM match_type = "tag type NONE"; 202510743SDavid.Hollister@Sun.COM break; 202610743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_CBACK: 202710743SDavid.Hollister@Sun.COM match_type = "tag type CBACK"; 202810743SDavid.Hollister@Sun.COM break; 202910743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_WAIT: 203010743SDavid.Hollister@Sun.COM match_type = "tag type WAIT"; 203110743SDavid.Hollister@Sun.COM break; 203210743SDavid.Hollister@Sun.COM } 203310743SDavid.Hollister@Sun.COM mask = PMCS_TAG_TYPE_MASK; 203410743SDavid.Hollister@Sun.COM mask_val = tag_type << PMCS_TAG_TYPE_SHIFT; 203510743SDavid.Hollister@Sun.COM match_val = tag_type; 203610743SDavid.Hollister@Sun.COM } 203710743SDavid.Hollister@Sun.COM 203810743SDavid.Hollister@Sun.COM _wp = (uintptr_t)ss.work; 203910743SDavid.Hollister@Sun.COM 204010743SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.max_cmd; idx++, _wp += sizeof (pmcwork_t)) { 204110743SDavid.Hollister@Sun.COM if (MDB_RD(&work, sizeof (pmcwork_t), _wp) == -1) { 204210743SDavid.Hollister@Sun.COM NOREAD(pmcwork_t, _wp); 204310743SDavid.Hollister@Sun.COM continue; 204410743SDavid.Hollister@Sun.COM } 204510743SDavid.Hollister@Sun.COM 204610743SDavid.Hollister@Sun.COM if ((work.htag & mask) != mask_val) { 204710743SDavid.Hollister@Sun.COM continue; 204810743SDavid.Hollister@Sun.COM } 204910743SDavid.Hollister@Sun.COM 205010743SDavid.Hollister@Sun.COM if (printed_header == B_FALSE) { 205110743SDavid.Hollister@Sun.COM if (tag_type) { 205210743SDavid.Hollister@Sun.COM mdb_printf("\nWork structures matching %s\n\n", 205310743SDavid.Hollister@Sun.COM match_type, match_val); 205410743SDavid.Hollister@Sun.COM } else { 205510743SDavid.Hollister@Sun.COM mdb_printf("\nWork structures matching %s of " 205610743SDavid.Hollister@Sun.COM "0x%x\n\n", match_type, match_val); 205710743SDavid.Hollister@Sun.COM } 205810743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D\n", 205910743SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 206010743SDavid.Hollister@Sun.COM printed_header = B_TRUE; 206110743SDavid.Hollister@Sun.COM } 206210743SDavid.Hollister@Sun.COM 206310743SDavid.Hollister@Sun.COM display_one_work(wp, 0, 0); 206410743SDavid.Hollister@Sun.COM } 206510743SDavid.Hollister@Sun.COM 206610743SDavid.Hollister@Sun.COM if (!printed_header) { 206710743SDavid.Hollister@Sun.COM mdb_printf("No work structure matches found\n"); 206810743SDavid.Hollister@Sun.COM } 206910743SDavid.Hollister@Sun.COM } 207010743SDavid.Hollister@Sun.COM 207110743SDavid.Hollister@Sun.COM static int 207210743SDavid.Hollister@Sun.COM pmcs_tag(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 207310743SDavid.Hollister@Sun.COM { 207410743SDavid.Hollister@Sun.COM struct pmcs_hw ss; 207510743SDavid.Hollister@Sun.COM uintmax_t tag_type = UINT_MAX; 207610743SDavid.Hollister@Sun.COM uintmax_t snum = UINT_MAX; 207710743SDavid.Hollister@Sun.COM uintmax_t index = UINT_MAX; 207810743SDavid.Hollister@Sun.COM int args = 0; 207910743SDavid.Hollister@Sun.COM void *pmcs_state; 208010743SDavid.Hollister@Sun.COM char *state_str; 208110743SDavid.Hollister@Sun.COM struct dev_info dip; 208210743SDavid.Hollister@Sun.COM 208310743SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 208410743SDavid.Hollister@Sun.COM pmcs_state = NULL; 208510743SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 208610743SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 208710743SDavid.Hollister@Sun.COM return (DCMD_ERR); 208810743SDavid.Hollister@Sun.COM } 208910743SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_tag", argc, 209010743SDavid.Hollister@Sun.COM argv, (uintptr_t)pmcs_state) == -1) { 209110743SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed"); 209210743SDavid.Hollister@Sun.COM return (DCMD_ERR); 209310743SDavid.Hollister@Sun.COM } 209410743SDavid.Hollister@Sun.COM return (DCMD_OK); 209510743SDavid.Hollister@Sun.COM } 209610743SDavid.Hollister@Sun.COM 209710743SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 209810743SDavid.Hollister@Sun.COM 'i', MDB_OPT_UINT64, &index, 209910743SDavid.Hollister@Sun.COM 's', MDB_OPT_UINT64, &snum, 210010743SDavid.Hollister@Sun.COM 't', MDB_OPT_UINT64, &tag_type) != argc) 210110743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 210210743SDavid.Hollister@Sun.COM 210310743SDavid.Hollister@Sun.COM /* 210410743SDavid.Hollister@Sun.COM * Count the number of supplied options and make sure they are 210510743SDavid.Hollister@Sun.COM * within appropriate ranges. If they're set to UINT_MAX, that means 210610743SDavid.Hollister@Sun.COM * they were not supplied, in which case reset them to 0. 210710743SDavid.Hollister@Sun.COM */ 210810743SDavid.Hollister@Sun.COM if (index != UINT_MAX) { 210910743SDavid.Hollister@Sun.COM args++; 211010743SDavid.Hollister@Sun.COM if (index > PMCS_TAG_INDEX_MASK) { 211110743SDavid.Hollister@Sun.COM mdb_warn("Index is out of range\n"); 211210743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 211310743SDavid.Hollister@Sun.COM } 211410743SDavid.Hollister@Sun.COM } 211510743SDavid.Hollister@Sun.COM 211610743SDavid.Hollister@Sun.COM if (tag_type != UINT_MAX) { 211710743SDavid.Hollister@Sun.COM args++; 211810743SDavid.Hollister@Sun.COM switch (tag_type) { 211910743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_NONE: 212010743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_CBACK: 212110743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_WAIT: 212210743SDavid.Hollister@Sun.COM break; 212310743SDavid.Hollister@Sun.COM default: 212410743SDavid.Hollister@Sun.COM mdb_warn("Invalid tag type\n"); 212510743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 212610743SDavid.Hollister@Sun.COM } 212710743SDavid.Hollister@Sun.COM } 212810743SDavid.Hollister@Sun.COM 212910743SDavid.Hollister@Sun.COM if (snum != UINT_MAX) { 213010743SDavid.Hollister@Sun.COM args++; 213110743SDavid.Hollister@Sun.COM if (snum > (PMCS_TAG_SERNO_MASK >> PMCS_TAG_SERNO_SHIFT)) { 213210743SDavid.Hollister@Sun.COM mdb_warn("Serial number is out of range\n"); 213310743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 213410743SDavid.Hollister@Sun.COM } 213510743SDavid.Hollister@Sun.COM } 213610743SDavid.Hollister@Sun.COM 213710743SDavid.Hollister@Sun.COM /* 213810743SDavid.Hollister@Sun.COM * Make sure 1 and only 1 option is specified 213910743SDavid.Hollister@Sun.COM */ 214010743SDavid.Hollister@Sun.COM if ((args == 0) || (args > 1)) { 214110743SDavid.Hollister@Sun.COM mdb_warn("Exactly one of -i, -s and -t must be specified\n"); 214210743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 214310743SDavid.Hollister@Sun.COM } 214410743SDavid.Hollister@Sun.COM 214510743SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 214610743SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 214710743SDavid.Hollister@Sun.COM return (DCMD_ERR); 214810743SDavid.Hollister@Sun.COM } 214910743SDavid.Hollister@Sun.COM 215010743SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 215110743SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 215210743SDavid.Hollister@Sun.COM return (DCMD_ERR); 215310743SDavid.Hollister@Sun.COM } 215410743SDavid.Hollister@Sun.COM 215510743SDavid.Hollister@Sun.COM /* processing completed */ 215610743SDavid.Hollister@Sun.COM 215710743SDavid.Hollister@Sun.COM if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) || 215810743SDavid.Hollister@Sun.COM (flags & DCMD_LOOPFIRST)) { 215910743SDavid.Hollister@Sun.COM if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST)) 216010743SDavid.Hollister@Sun.COM mdb_printf("\n"); 216110743SDavid.Hollister@Sun.COM mdb_printf("%16s %9s %4s B C WorkFlags wserno DbgMsk %16s\n", 216210743SDavid.Hollister@Sun.COM "Address", "State", "Inst", "DIP"); 216310743SDavid.Hollister@Sun.COM mdb_printf("=================================" 216410743SDavid.Hollister@Sun.COM "============================================\n"); 216510743SDavid.Hollister@Sun.COM } 216610743SDavid.Hollister@Sun.COM 216710743SDavid.Hollister@Sun.COM switch (ss.state) { 216810743SDavid.Hollister@Sun.COM case STATE_NIL: 216910743SDavid.Hollister@Sun.COM state_str = "Invalid"; 217010743SDavid.Hollister@Sun.COM break; 217110743SDavid.Hollister@Sun.COM case STATE_PROBING: 217210743SDavid.Hollister@Sun.COM state_str = "Probing"; 217310743SDavid.Hollister@Sun.COM break; 217410743SDavid.Hollister@Sun.COM case STATE_RUNNING: 217510743SDavid.Hollister@Sun.COM state_str = "Running"; 217610743SDavid.Hollister@Sun.COM break; 217710743SDavid.Hollister@Sun.COM case STATE_UNPROBING: 217810743SDavid.Hollister@Sun.COM state_str = "Unprobing"; 217910743SDavid.Hollister@Sun.COM break; 218010743SDavid.Hollister@Sun.COM case STATE_DEAD: 218110743SDavid.Hollister@Sun.COM state_str = "Dead"; 218210743SDavid.Hollister@Sun.COM break; 218310743SDavid.Hollister@Sun.COM } 218410743SDavid.Hollister@Sun.COM 218510743SDavid.Hollister@Sun.COM mdb_printf("%16p %9s %4d %1d %1d 0x%08x 0x%04x 0x%04x %16p\n", addr, 218610743SDavid.Hollister@Sun.COM state_str, dip.devi_instance, ss.blocked, ss.configuring, 218710743SDavid.Hollister@Sun.COM ss.work_flags, ss.wserno, ss.debug_mask, ss.dip); 218810743SDavid.Hollister@Sun.COM mdb_printf("\n"); 218910743SDavid.Hollister@Sun.COM 219010743SDavid.Hollister@Sun.COM mdb_inc_indent(4); 219110743SDavid.Hollister@Sun.COM display_matching_work(ss, index, snum, tag_type); 219210743SDavid.Hollister@Sun.COM mdb_dec_indent(4); 219310743SDavid.Hollister@Sun.COM mdb_printf("\n"); 219410743SDavid.Hollister@Sun.COM 219510743SDavid.Hollister@Sun.COM return (DCMD_OK); 219610743SDavid.Hollister@Sun.COM } 219710743SDavid.Hollister@Sun.COM 219810696SDavid.Hollister@Sun.COM static int 219911048SDavid.Hollister@Sun.COM pmcs_log(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 220011048SDavid.Hollister@Sun.COM { 220111048SDavid.Hollister@Sun.COM void *pmcs_state; 220211048SDavid.Hollister@Sun.COM struct pmcs_hw ss; 220311048SDavid.Hollister@Sun.COM struct dev_info dip; 220411048SDavid.Hollister@Sun.COM const char *match_phy_path = NULL; 220511048SDavid.Hollister@Sun.COM uint64_t match_sas_address = 0; 220611048SDavid.Hollister@Sun.COM 220711048SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 220811048SDavid.Hollister@Sun.COM pmcs_state = NULL; 220911048SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 221011048SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 221111048SDavid.Hollister@Sun.COM return (DCMD_ERR); 221211048SDavid.Hollister@Sun.COM } 221311048SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_log", argc, 221411048SDavid.Hollister@Sun.COM argv, (uintptr_t)pmcs_state) == -1) { 221511048SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed for pmcs_log"); 221611048SDavid.Hollister@Sun.COM return (DCMD_ERR); 221711048SDavid.Hollister@Sun.COM } 221811048SDavid.Hollister@Sun.COM return (DCMD_OK); 221911048SDavid.Hollister@Sun.COM } 222011048SDavid.Hollister@Sun.COM 222111048SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 222211048SDavid.Hollister@Sun.COM 'p', MDB_OPT_STR, &match_phy_path, 222311048SDavid.Hollister@Sun.COM 's', MDB_OPT_UINT64, &match_sas_address, 222411048SDavid.Hollister@Sun.COM NULL) != argc) { 222511048SDavid.Hollister@Sun.COM return (DCMD_USAGE); 222611048SDavid.Hollister@Sun.COM } 222711048SDavid.Hollister@Sun.COM 222811048SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 222911048SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 223011048SDavid.Hollister@Sun.COM return (DCMD_ERR); 223111048SDavid.Hollister@Sun.COM } 223211048SDavid.Hollister@Sun.COM 223311048SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 223411048SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 223511048SDavid.Hollister@Sun.COM return (DCMD_ERR); 223611048SDavid.Hollister@Sun.COM } 223711048SDavid.Hollister@Sun.COM 223811048SDavid.Hollister@Sun.COM if (!(flags & DCMD_LOOP)) { 223911048SDavid.Hollister@Sun.COM return (pmcs_dump_tracelog(B_TRUE, dip.devi_instance, 224011048SDavid.Hollister@Sun.COM match_phy_path, match_sas_address)); 224111048SDavid.Hollister@Sun.COM } else if (flags & DCMD_LOOPFIRST) { 224211048SDavid.Hollister@Sun.COM return (pmcs_dump_tracelog(B_FALSE, 0, match_phy_path, 224311048SDavid.Hollister@Sun.COM match_sas_address)); 224411048SDavid.Hollister@Sun.COM } else { 224511048SDavid.Hollister@Sun.COM return (DCMD_OK); 224611048SDavid.Hollister@Sun.COM } 224711048SDavid.Hollister@Sun.COM } 224811048SDavid.Hollister@Sun.COM 224911048SDavid.Hollister@Sun.COM static int 225010696SDavid.Hollister@Sun.COM pmcs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 225110696SDavid.Hollister@Sun.COM { 225211048SDavid.Hollister@Sun.COM struct pmcs_hw ss; 225310696SDavid.Hollister@Sun.COM uint_t verbose = FALSE; 225410696SDavid.Hollister@Sun.COM uint_t phy_info = FALSE; 225510696SDavid.Hollister@Sun.COM uint_t hw_info = FALSE; 225610696SDavid.Hollister@Sun.COM uint_t target_info = FALSE; 225710696SDavid.Hollister@Sun.COM uint_t work_info = FALSE; 225810696SDavid.Hollister@Sun.COM uint_t ic_info = FALSE; 225910696SDavid.Hollister@Sun.COM uint_t iport_info = FALSE; 226010696SDavid.Hollister@Sun.COM uint_t waitqs_info = FALSE; 226110696SDavid.Hollister@Sun.COM uint_t ibq = FALSE; 226210696SDavid.Hollister@Sun.COM uint_t obq = FALSE; 226310696SDavid.Hollister@Sun.COM uint_t tgt_phy_count = FALSE; 226410743SDavid.Hollister@Sun.COM uint_t compq = FALSE; 226511048SDavid.Hollister@Sun.COM uint_t unconfigured = FALSE; 2266*11334SReed.Liu@Sun.COM uint_t damap_info = FALSE; 2267*11334SReed.Liu@Sun.COM uint_t dtc_info = FALSE; 226810696SDavid.Hollister@Sun.COM int rv = DCMD_OK; 226910696SDavid.Hollister@Sun.COM void *pmcs_state; 227010696SDavid.Hollister@Sun.COM char *state_str; 227110696SDavid.Hollister@Sun.COM struct dev_info dip; 2272*11334SReed.Liu@Sun.COM per_iport_setting_t pis; 227310696SDavid.Hollister@Sun.COM 227410696SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 227510696SDavid.Hollister@Sun.COM pmcs_state = NULL; 227610696SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 227710696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 227810696SDavid.Hollister@Sun.COM return (DCMD_ERR); 227910696SDavid.Hollister@Sun.COM } 228010696SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs", argc, argv, 228110696SDavid.Hollister@Sun.COM (uintptr_t)pmcs_state) == -1) { 228210696SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed"); 228310696SDavid.Hollister@Sun.COM return (DCMD_ERR); 228410696SDavid.Hollister@Sun.COM } 228510696SDavid.Hollister@Sun.COM return (DCMD_OK); 228610696SDavid.Hollister@Sun.COM } 228710696SDavid.Hollister@Sun.COM 228810696SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 228910743SDavid.Hollister@Sun.COM 'c', MDB_OPT_SETBITS, TRUE, &compq, 2290*11334SReed.Liu@Sun.COM 'd', MDB_OPT_SETBITS, TRUE, &dtc_info, 229110696SDavid.Hollister@Sun.COM 'h', MDB_OPT_SETBITS, TRUE, &hw_info, 229210696SDavid.Hollister@Sun.COM 'i', MDB_OPT_SETBITS, TRUE, &ic_info, 229310696SDavid.Hollister@Sun.COM 'I', MDB_OPT_SETBITS, TRUE, &iport_info, 2294*11334SReed.Liu@Sun.COM 'm', MDB_OPT_SETBITS, TRUE, &damap_info, 229510696SDavid.Hollister@Sun.COM 'p', MDB_OPT_SETBITS, TRUE, &phy_info, 229610696SDavid.Hollister@Sun.COM 'q', MDB_OPT_SETBITS, TRUE, &ibq, 229710696SDavid.Hollister@Sun.COM 'Q', MDB_OPT_SETBITS, TRUE, &obq, 229810696SDavid.Hollister@Sun.COM 't', MDB_OPT_SETBITS, TRUE, &target_info, 229910696SDavid.Hollister@Sun.COM 'T', MDB_OPT_SETBITS, TRUE, &tgt_phy_count, 230011048SDavid.Hollister@Sun.COM 'u', MDB_OPT_SETBITS, TRUE, &unconfigured, 230110696SDavid.Hollister@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose, 230210696SDavid.Hollister@Sun.COM 'w', MDB_OPT_SETBITS, TRUE, &work_info, 230310696SDavid.Hollister@Sun.COM 'W', MDB_OPT_SETBITS, TRUE, &waitqs_info, 230410696SDavid.Hollister@Sun.COM NULL) != argc) 230510696SDavid.Hollister@Sun.COM return (DCMD_USAGE); 230610696SDavid.Hollister@Sun.COM 2307*11334SReed.Liu@Sun.COM /* 2308*11334SReed.Liu@Sun.COM * The 'd' and 'm' options implicitly enable the 'I' option 2309*11334SReed.Liu@Sun.COM */ 2310*11334SReed.Liu@Sun.COM pis.pis_damap_info = damap_info; 2311*11334SReed.Liu@Sun.COM pis.pis_dtc_info = dtc_info; 2312*11334SReed.Liu@Sun.COM if (damap_info || dtc_info) { 2313*11334SReed.Liu@Sun.COM iport_info = TRUE; 2314*11334SReed.Liu@Sun.COM } 2315*11334SReed.Liu@Sun.COM 231610696SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 231710696SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 231810696SDavid.Hollister@Sun.COM return (DCMD_ERR); 231910696SDavid.Hollister@Sun.COM } 232010696SDavid.Hollister@Sun.COM 232110696SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 232210696SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 232310696SDavid.Hollister@Sun.COM return (DCMD_ERR); 232410696SDavid.Hollister@Sun.COM } 232510696SDavid.Hollister@Sun.COM 232610696SDavid.Hollister@Sun.COM /* processing completed */ 232710696SDavid.Hollister@Sun.COM 232810696SDavid.Hollister@Sun.COM if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) || 232910696SDavid.Hollister@Sun.COM (flags & DCMD_LOOPFIRST) || phy_info || target_info || hw_info || 233011048SDavid.Hollister@Sun.COM work_info || waitqs_info || ibq || obq || tgt_phy_count || compq || 233111048SDavid.Hollister@Sun.COM unconfigured) { 233210696SDavid.Hollister@Sun.COM if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST)) 233310696SDavid.Hollister@Sun.COM mdb_printf("\n"); 233410696SDavid.Hollister@Sun.COM mdb_printf("%16s %9s %4s B C WorkFlags wserno DbgMsk %16s\n", 233510696SDavid.Hollister@Sun.COM "Address", "State", "Inst", "DIP"); 233610696SDavid.Hollister@Sun.COM mdb_printf("=================================" 233710696SDavid.Hollister@Sun.COM "============================================\n"); 233810696SDavid.Hollister@Sun.COM } 233910696SDavid.Hollister@Sun.COM 234010696SDavid.Hollister@Sun.COM switch (ss.state) { 234110696SDavid.Hollister@Sun.COM case STATE_NIL: 234210696SDavid.Hollister@Sun.COM state_str = "Invalid"; 234310696SDavid.Hollister@Sun.COM break; 234410696SDavid.Hollister@Sun.COM case STATE_PROBING: 234510696SDavid.Hollister@Sun.COM state_str = "Probing"; 234610696SDavid.Hollister@Sun.COM break; 234710696SDavid.Hollister@Sun.COM case STATE_RUNNING: 234810696SDavid.Hollister@Sun.COM state_str = "Running"; 234910696SDavid.Hollister@Sun.COM break; 235010696SDavid.Hollister@Sun.COM case STATE_UNPROBING: 235110696SDavid.Hollister@Sun.COM state_str = "Unprobing"; 235210696SDavid.Hollister@Sun.COM break; 235310696SDavid.Hollister@Sun.COM case STATE_DEAD: 235410696SDavid.Hollister@Sun.COM state_str = "Dead"; 235510696SDavid.Hollister@Sun.COM break; 235610696SDavid.Hollister@Sun.COM } 235710696SDavid.Hollister@Sun.COM 235810696SDavid.Hollister@Sun.COM mdb_printf("%16p %9s %4d %1d %1d 0x%08x 0x%04x 0x%04x %16p\n", addr, 235910696SDavid.Hollister@Sun.COM state_str, dip.devi_instance, ss.blocked, ss.configuring, 236010696SDavid.Hollister@Sun.COM ss.work_flags, ss.wserno, ss.debug_mask, ss.dip); 236110696SDavid.Hollister@Sun.COM mdb_printf("\n"); 236210696SDavid.Hollister@Sun.COM 236310696SDavid.Hollister@Sun.COM mdb_inc_indent(4); 236410696SDavid.Hollister@Sun.COM 236510696SDavid.Hollister@Sun.COM if (waitqs_info) 236610696SDavid.Hollister@Sun.COM display_waitqs(ss, verbose); 236710696SDavid.Hollister@Sun.COM 236810696SDavid.Hollister@Sun.COM if (hw_info) 236910696SDavid.Hollister@Sun.COM display_hwinfo(ss, verbose); 237010696SDavid.Hollister@Sun.COM 237110696SDavid.Hollister@Sun.COM if (phy_info || tgt_phy_count) 237210696SDavid.Hollister@Sun.COM display_phys(ss, verbose, NULL, 0, tgt_phy_count); 237310696SDavid.Hollister@Sun.COM 237410696SDavid.Hollister@Sun.COM if (target_info || tgt_phy_count) 237510696SDavid.Hollister@Sun.COM display_targets(ss, verbose, tgt_phy_count); 237610696SDavid.Hollister@Sun.COM 237710696SDavid.Hollister@Sun.COM if (work_info) 237810696SDavid.Hollister@Sun.COM display_work(ss, verbose); 237910696SDavid.Hollister@Sun.COM 238010696SDavid.Hollister@Sun.COM if (ic_info) 238110696SDavid.Hollister@Sun.COM display_ic(ss, verbose); 238210696SDavid.Hollister@Sun.COM 238310696SDavid.Hollister@Sun.COM if (ibq) 238410696SDavid.Hollister@Sun.COM display_inbound_queues(ss, verbose); 238510696SDavid.Hollister@Sun.COM 238610696SDavid.Hollister@Sun.COM if (obq) 238710696SDavid.Hollister@Sun.COM display_outbound_queues(ss, verbose); 238810696SDavid.Hollister@Sun.COM 238910696SDavid.Hollister@Sun.COM if (iport_info) 2390*11334SReed.Liu@Sun.COM display_iport(ss, addr, verbose, &pis); 239110696SDavid.Hollister@Sun.COM 239210743SDavid.Hollister@Sun.COM if (compq) 239310743SDavid.Hollister@Sun.COM display_completion_queue(ss); 239410743SDavid.Hollister@Sun.COM 239511048SDavid.Hollister@Sun.COM if (unconfigured) 239611048SDavid.Hollister@Sun.COM display_unconfigured_targets(addr); 239711048SDavid.Hollister@Sun.COM 239810696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 239910696SDavid.Hollister@Sun.COM 240010696SDavid.Hollister@Sun.COM return (rv); 240110696SDavid.Hollister@Sun.COM } 240210696SDavid.Hollister@Sun.COM 240310696SDavid.Hollister@Sun.COM void 240410696SDavid.Hollister@Sun.COM pmcs_help() 240510696SDavid.Hollister@Sun.COM { 240610696SDavid.Hollister@Sun.COM mdb_printf("Prints summary information about each pmcs instance.\n" 240710743SDavid.Hollister@Sun.COM " -c: Dump the completion queue\n" 2408*11334SReed.Liu@Sun.COM " -d: Print per-iport information about device tree children\n" 240910696SDavid.Hollister@Sun.COM " -h: Print more detailed hardware information\n" 241010696SDavid.Hollister@Sun.COM " -i: Print interrupt coalescing information\n" 241110696SDavid.Hollister@Sun.COM " -I: Print information about each iport\n" 2412*11334SReed.Liu@Sun.COM " -m: Print per-iport information about DAM/damap state\n" 241310696SDavid.Hollister@Sun.COM " -p: Print information about each attached PHY\n" 241410696SDavid.Hollister@Sun.COM " -q: Dump inbound queues\n" 241510696SDavid.Hollister@Sun.COM " -Q: Dump outbound queues\n" 241611048SDavid.Hollister@Sun.COM " -t: Print information about each configured target\n" 241710696SDavid.Hollister@Sun.COM " -T: Print target and PHY count summary\n" 241811048SDavid.Hollister@Sun.COM " -u: Show SAS address of all unconfigured targets\n" 241910696SDavid.Hollister@Sun.COM " -w: Dump work structures\n" 242010696SDavid.Hollister@Sun.COM " -W: List pmcs cmds waiting on various queues\n" 242110696SDavid.Hollister@Sun.COM " -v: Add verbosity to the above options\n"); 242210696SDavid.Hollister@Sun.COM } 242310696SDavid.Hollister@Sun.COM 242410743SDavid.Hollister@Sun.COM void 242511048SDavid.Hollister@Sun.COM pmcs_log_help() 242611048SDavid.Hollister@Sun.COM { 242711048SDavid.Hollister@Sun.COM mdb_printf("Dump the pmcs log buffer, possibly with filtering.\n" 242811048SDavid.Hollister@Sun.COM " -p PHY_PATH: Dump messages matching PHY_PATH\n" 242911048SDavid.Hollister@Sun.COM " -s SAS_ADDRESS: Dump messages matching SAS_ADDRESS\n\n" 243011048SDavid.Hollister@Sun.COM "Where: PHY_PATH can be found with ::pmcs -p (e.g. pp04.18.18.01)\n" 243111048SDavid.Hollister@Sun.COM " SAS_ADDRESS can be found with ::pmcs -t " 243211048SDavid.Hollister@Sun.COM "(e.g. 5000c5000358c221)\n"); 243311048SDavid.Hollister@Sun.COM } 243411048SDavid.Hollister@Sun.COM void 243510743SDavid.Hollister@Sun.COM pmcs_tag_help() 243610743SDavid.Hollister@Sun.COM { 243710743SDavid.Hollister@Sun.COM mdb_printf("Print all work structures by matching the tag.\n" 243810743SDavid.Hollister@Sun.COM " -i index: Match tag index (0x000 - 0xfff)\n" 243910743SDavid.Hollister@Sun.COM " -s serialnumber: Match serial number (0x0000 - 0xffff)\n" 244010743SDavid.Hollister@Sun.COM " -t tagtype: Match tag type [NONE(1), CBACK(2), " 244110743SDavid.Hollister@Sun.COM "WAIT(3)]\n"); 244210743SDavid.Hollister@Sun.COM } 244310743SDavid.Hollister@Sun.COM 244410696SDavid.Hollister@Sun.COM static const mdb_dcmd_t dcmds[] = { 2445*11334SReed.Liu@Sun.COM { "pmcs", "?[-cdhiImpQqtTuwWv]", "print pmcs information", 244610696SDavid.Hollister@Sun.COM pmcs_dcmd, pmcs_help 244710696SDavid.Hollister@Sun.COM }, 244811048SDavid.Hollister@Sun.COM { "pmcs_log", 244911048SDavid.Hollister@Sun.COM "?[-p PHY_PATH | -s SAS_ADDRESS]", 245011048SDavid.Hollister@Sun.COM "dump pmcs log file", pmcs_log, pmcs_log_help 245111048SDavid.Hollister@Sun.COM }, 245210743SDavid.Hollister@Sun.COM { "pmcs_tag", "?[-t tagtype|-s serialnum|-i index]", 245310743SDavid.Hollister@Sun.COM "Find work structures by tag type, serial number or index", 245410743SDavid.Hollister@Sun.COM pmcs_tag, pmcs_tag_help 245510743SDavid.Hollister@Sun.COM }, 245610696SDavid.Hollister@Sun.COM { NULL } 245710696SDavid.Hollister@Sun.COM }; 245810696SDavid.Hollister@Sun.COM 245910696SDavid.Hollister@Sun.COM static const mdb_walker_t walkers[] = { 246010696SDavid.Hollister@Sun.COM { "pmcs_targets", "walk target structures", 246110696SDavid.Hollister@Sun.COM targets_walk_i, targets_walk_s, targets_walk_f }, 246210696SDavid.Hollister@Sun.COM { "pmcs_phys", "walk PHY structures", 246310696SDavid.Hollister@Sun.COM phy_walk_i, phy_walk_s, phy_walk_f }, 246410696SDavid.Hollister@Sun.COM { NULL } 246510696SDavid.Hollister@Sun.COM }; 246610696SDavid.Hollister@Sun.COM 246710696SDavid.Hollister@Sun.COM static const mdb_modinfo_t modinfo = { 246810696SDavid.Hollister@Sun.COM MDB_API_VERSION, dcmds, walkers 246910696SDavid.Hollister@Sun.COM }; 247010696SDavid.Hollister@Sun.COM 247110696SDavid.Hollister@Sun.COM const mdb_modinfo_t * 247210696SDavid.Hollister@Sun.COM _mdb_init(void) 247310696SDavid.Hollister@Sun.COM { 247410696SDavid.Hollister@Sun.COM return (&modinfo); 247510696SDavid.Hollister@Sun.COM } 2476