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> 2810696SDavid.Hollister@Sun.COM #include <sys/sysinfo.h> 2910696SDavid.Hollister@Sun.COM #include <sys/scsi/scsi.h> 3010696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs.h> 3110696SDavid.Hollister@Sun.COM 3210696SDavid.Hollister@Sun.COM #define MDB_RD(a, b, c) mdb_vread(a, b, (uintptr_t)c) 3310696SDavid.Hollister@Sun.COM #define NOREAD(a, b) mdb_warn("could not read " #a " at 0x%p", b) 3410696SDavid.Hollister@Sun.COM 3510696SDavid.Hollister@Sun.COM static pmcs_hw_t ss; 3610696SDavid.Hollister@Sun.COM static pmcs_xscsi_t **targets = NULL; 3710696SDavid.Hollister@Sun.COM static int target_idx; 3810696SDavid.Hollister@Sun.COM 3910696SDavid.Hollister@Sun.COM static uint32_t sas_phys, sata_phys, exp_phys, num_expanders, empty_phys; 4010696SDavid.Hollister@Sun.COM 4110696SDavid.Hollister@Sun.COM static pmcs_phy_t *pmcs_next_sibling(pmcs_phy_t *phyp); 42*10743SDavid.Hollister@Sun.COM static void display_one_work(pmcwork_t *wp, int verbose, int idx); 4310696SDavid.Hollister@Sun.COM 4410696SDavid.Hollister@Sun.COM static void 4510696SDavid.Hollister@Sun.COM print_sas_address(pmcs_phy_t *phy) 4610696SDavid.Hollister@Sun.COM { 4710696SDavid.Hollister@Sun.COM int idx; 4810696SDavid.Hollister@Sun.COM 4910696SDavid.Hollister@Sun.COM for (idx = 0; idx < 8; idx++) { 5010696SDavid.Hollister@Sun.COM mdb_printf("%02x", phy->sas_address[idx]); 5110696SDavid.Hollister@Sun.COM } 5210696SDavid.Hollister@Sun.COM } 5310696SDavid.Hollister@Sun.COM 5410696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 5510696SDavid.Hollister@Sun.COM static void 5610696SDavid.Hollister@Sun.COM display_ic(struct pmcs_hw m, int verbose) 5710696SDavid.Hollister@Sun.COM { 5810696SDavid.Hollister@Sun.COM int msec_per_tick; 5910696SDavid.Hollister@Sun.COM 6010696SDavid.Hollister@Sun.COM if (mdb_readvar(&msec_per_tick, "msec_per_tick") == -1) { 6110696SDavid.Hollister@Sun.COM mdb_warn("can't read msec_per_tick"); 6210696SDavid.Hollister@Sun.COM msec_per_tick = 0; 6310696SDavid.Hollister@Sun.COM } 6410696SDavid.Hollister@Sun.COM 6510696SDavid.Hollister@Sun.COM mdb_printf("\n"); 6610696SDavid.Hollister@Sun.COM mdb_printf("Interrupt coalescing timer info\n"); 6710696SDavid.Hollister@Sun.COM mdb_printf("-------------------------------\n"); 6810696SDavid.Hollister@Sun.COM if (msec_per_tick == 0) { 6910696SDavid.Hollister@Sun.COM mdb_printf("Quantum : ?? ms\n"); 7010696SDavid.Hollister@Sun.COM } else { 7110696SDavid.Hollister@Sun.COM mdb_printf("Quantum : %d ms\n", 7210696SDavid.Hollister@Sun.COM m.io_intr_coal.quantum * msec_per_tick); 7310696SDavid.Hollister@Sun.COM } 7410696SDavid.Hollister@Sun.COM mdb_printf("Timer enabled : "); 7510696SDavid.Hollister@Sun.COM if (m.io_intr_coal.timer_on) { 7610696SDavid.Hollister@Sun.COM mdb_printf("Yes\n"); 7710696SDavid.Hollister@Sun.COM mdb_printf("Coalescing timer value : %d us\n", 7810696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_coal_timer); 7910696SDavid.Hollister@Sun.COM } else { 8010696SDavid.Hollister@Sun.COM mdb_printf("No\n"); 8110696SDavid.Hollister@Sun.COM } 8210696SDavid.Hollister@Sun.COM mdb_printf("Total nsecs between interrupts: %ld\n", 8310696SDavid.Hollister@Sun.COM m.io_intr_coal.nsecs_between_intrs); 8410696SDavid.Hollister@Sun.COM mdb_printf("Time of last I/O interrupt : %ld\n", 8510696SDavid.Hollister@Sun.COM m.io_intr_coal.last_io_comp); 8610696SDavid.Hollister@Sun.COM mdb_printf("Number of I/O interrupts : %d\n", 8710696SDavid.Hollister@Sun.COM m.io_intr_coal.num_intrs); 8810696SDavid.Hollister@Sun.COM mdb_printf("Number of I/O completions : %d\n", 8910696SDavid.Hollister@Sun.COM m.io_intr_coal.num_io_completions); 9010696SDavid.Hollister@Sun.COM mdb_printf("Max I/O completion interrupts : %d\n", 9110696SDavid.Hollister@Sun.COM m.io_intr_coal.max_io_completions); 9210696SDavid.Hollister@Sun.COM mdb_printf("Measured ECHO int latency : %d ns\n", 9310696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_latency); 9410696SDavid.Hollister@Sun.COM mdb_printf("Interrupt threshold : %d\n", 9510696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_threshold); 9610696SDavid.Hollister@Sun.COM } 9710696SDavid.Hollister@Sun.COM 9810696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 9910696SDavid.Hollister@Sun.COM static int 10010696SDavid.Hollister@Sun.COM pmcs_iport_phy_walk_cb(uintptr_t addr, const void *wdata, void *priv) 10110696SDavid.Hollister@Sun.COM { 10210696SDavid.Hollister@Sun.COM struct pmcs_phy phy; 10310696SDavid.Hollister@Sun.COM 10410696SDavid.Hollister@Sun.COM if (mdb_vread(&phy, sizeof (struct pmcs_phy), addr) != 10510696SDavid.Hollister@Sun.COM sizeof (struct pmcs_phy)) { 10610696SDavid.Hollister@Sun.COM return (DCMD_ERR); 10710696SDavid.Hollister@Sun.COM } 10810696SDavid.Hollister@Sun.COM 10910696SDavid.Hollister@Sun.COM mdb_printf("%16p %2d\n", addr, phy.phynum); 11010696SDavid.Hollister@Sun.COM 11110696SDavid.Hollister@Sun.COM return (0); 11210696SDavid.Hollister@Sun.COM } 11310696SDavid.Hollister@Sun.COM 11410696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 11510696SDavid.Hollister@Sun.COM static int 11610696SDavid.Hollister@Sun.COM pmcs_iport_walk_cb(uintptr_t addr, const void *wdata, void *priv) 11710696SDavid.Hollister@Sun.COM { 11810696SDavid.Hollister@Sun.COM struct pmcs_iport iport; 11910696SDavid.Hollister@Sun.COM uintptr_t list_addr; 12010696SDavid.Hollister@Sun.COM char *ua_state; 12110696SDavid.Hollister@Sun.COM char portid[4]; 12210696SDavid.Hollister@Sun.COM char unit_address[34]; 12310696SDavid.Hollister@Sun.COM 12410696SDavid.Hollister@Sun.COM if (mdb_vread(&iport, sizeof (struct pmcs_iport), addr) != 12510696SDavid.Hollister@Sun.COM sizeof (struct pmcs_iport)) { 12610696SDavid.Hollister@Sun.COM return (DCMD_ERR); 12710696SDavid.Hollister@Sun.COM } 12810696SDavid.Hollister@Sun.COM 12910696SDavid.Hollister@Sun.COM if (mdb_readstr(unit_address, sizeof (unit_address), 13010696SDavid.Hollister@Sun.COM (uintptr_t)(iport.ua)) == -1) { 13110696SDavid.Hollister@Sun.COM strncpy(unit_address, "Unset", sizeof (unit_address)); 13210696SDavid.Hollister@Sun.COM } 13310696SDavid.Hollister@Sun.COM 13410696SDavid.Hollister@Sun.COM if (iport.portid == 0xffff) { 13510696SDavid.Hollister@Sun.COM mdb_snprintf(portid, sizeof (portid), "%s", "-"); 13610696SDavid.Hollister@Sun.COM } else { 13710696SDavid.Hollister@Sun.COM mdb_snprintf(portid, sizeof (portid), "%d", iport.portid); 13810696SDavid.Hollister@Sun.COM } 13910696SDavid.Hollister@Sun.COM 14010696SDavid.Hollister@Sun.COM switch (iport.ua_state) { 14110696SDavid.Hollister@Sun.COM case UA_INACTIVE: 14210696SDavid.Hollister@Sun.COM ua_state = "Inactive"; 14310696SDavid.Hollister@Sun.COM break; 14410696SDavid.Hollister@Sun.COM case UA_PEND_ACTIVATE: 14510696SDavid.Hollister@Sun.COM ua_state = "PendActivate"; 14610696SDavid.Hollister@Sun.COM break; 14710696SDavid.Hollister@Sun.COM case UA_ACTIVE: 14810696SDavid.Hollister@Sun.COM ua_state = "Active"; 14910696SDavid.Hollister@Sun.COM break; 15010696SDavid.Hollister@Sun.COM case UA_PEND_DEACTIVATE: 15110696SDavid.Hollister@Sun.COM ua_state = "PendDeactivate"; 15210696SDavid.Hollister@Sun.COM break; 15310696SDavid.Hollister@Sun.COM default: 15410696SDavid.Hollister@Sun.COM ua_state = "Unknown"; 15510696SDavid.Hollister@Sun.COM } 15610696SDavid.Hollister@Sun.COM 15710696SDavid.Hollister@Sun.COM if (strlen(unit_address) < 3) { 15810696SDavid.Hollister@Sun.COM /* Standard iport unit address */ 15910696SDavid.Hollister@Sun.COM mdb_printf("UA %-16s %16s %8s %8s %16s", "Iport", "UA State", 16010696SDavid.Hollister@Sun.COM "PortID", "NumPhys", "DIP\n"); 16110696SDavid.Hollister@Sun.COM mdb_printf("%2s %16p %16s %8s %8d %16p\n", unit_address, addr, 16210696SDavid.Hollister@Sun.COM ua_state, portid, iport.nphy, iport.dip); 16310696SDavid.Hollister@Sun.COM } else { 16410696SDavid.Hollister@Sun.COM /* Temporary iport unit address */ 16510696SDavid.Hollister@Sun.COM mdb_printf("%-32s %16s %20s %8s %8s %16s", "UA", "Iport", 16610696SDavid.Hollister@Sun.COM "UA State", "PortID", "NumPhys", "DIP\n"); 16710696SDavid.Hollister@Sun.COM mdb_printf("%32s %16p %20s %8s %8d %16p\n", unit_address, addr, 16810696SDavid.Hollister@Sun.COM ua_state, portid, iport.nphy, iport.dip); 16910696SDavid.Hollister@Sun.COM } 17010696SDavid.Hollister@Sun.COM 17110696SDavid.Hollister@Sun.COM if (iport.nphy > 0) { 17210696SDavid.Hollister@Sun.COM mdb_inc_indent(4); 17310696SDavid.Hollister@Sun.COM mdb_printf("%-18s %8s", "Phy", "PhyNum\n"); 17410696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 17510696SDavid.Hollister@Sun.COM list_addr = 17610696SDavid.Hollister@Sun.COM (uintptr_t)(addr + offsetof(struct pmcs_iport, phys)); 17710696SDavid.Hollister@Sun.COM if (mdb_pwalk("list", pmcs_iport_phy_walk_cb, NULL, 17810696SDavid.Hollister@Sun.COM list_addr) == -1) { 17910696SDavid.Hollister@Sun.COM mdb_warn("pmcs iport walk failed"); 18010696SDavid.Hollister@Sun.COM } 18110696SDavid.Hollister@Sun.COM mdb_dec_indent(6); 18210696SDavid.Hollister@Sun.COM mdb_printf("\n"); 18310696SDavid.Hollister@Sun.COM } 18410696SDavid.Hollister@Sun.COM 18510696SDavid.Hollister@Sun.COM return (0); 18610696SDavid.Hollister@Sun.COM } 18710696SDavid.Hollister@Sun.COM 18810696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 18910696SDavid.Hollister@Sun.COM static void 19010696SDavid.Hollister@Sun.COM display_iport(struct pmcs_hw m, uintptr_t addr, int verbose) 19110696SDavid.Hollister@Sun.COM { 19210696SDavid.Hollister@Sun.COM uintptr_t list_addr; 19310696SDavid.Hollister@Sun.COM 19410696SDavid.Hollister@Sun.COM if (m.iports_attached) { 19510696SDavid.Hollister@Sun.COM mdb_printf("Iport information:\n"); 19610696SDavid.Hollister@Sun.COM mdb_printf("-----------------\n"); 19710696SDavid.Hollister@Sun.COM } else { 19810696SDavid.Hollister@Sun.COM mdb_printf("No Iports found.\n\n"); 19910696SDavid.Hollister@Sun.COM return; 20010696SDavid.Hollister@Sun.COM } 20110696SDavid.Hollister@Sun.COM 20210696SDavid.Hollister@Sun.COM list_addr = (uintptr_t)(addr + offsetof(struct pmcs_hw, iports)); 20310696SDavid.Hollister@Sun.COM 20410696SDavid.Hollister@Sun.COM if (mdb_pwalk("list", pmcs_iport_walk_cb, NULL, list_addr) == -1) { 20510696SDavid.Hollister@Sun.COM mdb_warn("pmcs iport walk failed"); 20610696SDavid.Hollister@Sun.COM } 20710696SDavid.Hollister@Sun.COM 20810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 20910696SDavid.Hollister@Sun.COM } 21010696SDavid.Hollister@Sun.COM 211*10743SDavid.Hollister@Sun.COM static void 212*10743SDavid.Hollister@Sun.COM display_completion_queue(struct pmcs_hw ss) 213*10743SDavid.Hollister@Sun.COM { 214*10743SDavid.Hollister@Sun.COM pmcs_iocomp_cb_t ccb, *ccbp; 215*10743SDavid.Hollister@Sun.COM pmcwork_t work; 216*10743SDavid.Hollister@Sun.COM 217*10743SDavid.Hollister@Sun.COM if (ss.iocomp_cb_head == NULL) { 218*10743SDavid.Hollister@Sun.COM mdb_printf("Completion queue is empty.\n"); 219*10743SDavid.Hollister@Sun.COM return; 220*10743SDavid.Hollister@Sun.COM } 221*10743SDavid.Hollister@Sun.COM 222*10743SDavid.Hollister@Sun.COM ccbp = ss.iocomp_cb_head; 223*10743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D\n", 224*10743SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 225*10743SDavid.Hollister@Sun.COM 226*10743SDavid.Hollister@Sun.COM while (ccbp) { 227*10743SDavid.Hollister@Sun.COM if (mdb_vread(&ccb, sizeof (pmcs_iocomp_cb_t), 228*10743SDavid.Hollister@Sun.COM (uintptr_t)ccbp) != sizeof (pmcs_iocomp_cb_t)) { 229*10743SDavid.Hollister@Sun.COM mdb_warn("Unable to read completion queue entry\n"); 230*10743SDavid.Hollister@Sun.COM return; 231*10743SDavid.Hollister@Sun.COM } 232*10743SDavid.Hollister@Sun.COM 233*10743SDavid.Hollister@Sun.COM if (mdb_vread(&work, sizeof (pmcwork_t), (uintptr_t)ccb.pwrk) 234*10743SDavid.Hollister@Sun.COM != sizeof (pmcwork_t)) { 235*10743SDavid.Hollister@Sun.COM mdb_warn("Unable to read work structure\n"); 236*10743SDavid.Hollister@Sun.COM return; 237*10743SDavid.Hollister@Sun.COM } 238*10743SDavid.Hollister@Sun.COM 239*10743SDavid.Hollister@Sun.COM /* 240*10743SDavid.Hollister@Sun.COM * Only print the work structure if it's still active. If 241*10743SDavid.Hollister@Sun.COM * it's not, it's been completed since we started looking at 242*10743SDavid.Hollister@Sun.COM * it. 243*10743SDavid.Hollister@Sun.COM */ 244*10743SDavid.Hollister@Sun.COM if (work.state != PMCS_WORK_STATE_NIL) { 245*10743SDavid.Hollister@Sun.COM display_one_work(&work, 0, 0); 246*10743SDavid.Hollister@Sun.COM } 247*10743SDavid.Hollister@Sun.COM ccbp = ccb.next; 248*10743SDavid.Hollister@Sun.COM } 249*10743SDavid.Hollister@Sun.COM } 250*10743SDavid.Hollister@Sun.COM 25110696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 25210696SDavid.Hollister@Sun.COM static void 25310696SDavid.Hollister@Sun.COM display_hwinfo(struct pmcs_hw m, int verbose) 25410696SDavid.Hollister@Sun.COM { 25510696SDavid.Hollister@Sun.COM struct pmcs_hw *mp = &m; 25610696SDavid.Hollister@Sun.COM char *fwsupport; 25710696SDavid.Hollister@Sun.COM 25810696SDavid.Hollister@Sun.COM switch (PMCS_FW_TYPE(mp)) { 25910696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_RELEASED: 26010696SDavid.Hollister@Sun.COM fwsupport = "Released"; 26110696SDavid.Hollister@Sun.COM break; 26210696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_DEVELOPMENT: 26310696SDavid.Hollister@Sun.COM fwsupport = "Development"; 26410696SDavid.Hollister@Sun.COM break; 26510696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_ALPHA: 26610696SDavid.Hollister@Sun.COM fwsupport = "Alpha"; 26710696SDavid.Hollister@Sun.COM break; 26810696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_BETA: 26910696SDavid.Hollister@Sun.COM fwsupport = "Beta"; 27010696SDavid.Hollister@Sun.COM break; 27110696SDavid.Hollister@Sun.COM default: 27210696SDavid.Hollister@Sun.COM fwsupport = "Special"; 27310696SDavid.Hollister@Sun.COM break; 27410696SDavid.Hollister@Sun.COM } 27510696SDavid.Hollister@Sun.COM 27610696SDavid.Hollister@Sun.COM mdb_printf("\nHardware information:\n"); 27710696SDavid.Hollister@Sun.COM mdb_printf("---------------------\n"); 27810696SDavid.Hollister@Sun.COM 27910696SDavid.Hollister@Sun.COM mdb_printf("Chip revision: %c\n", 'A' + m.chiprev); 28010696SDavid.Hollister@Sun.COM mdb_printf("SAS WWID: %"PRIx64"\n", m.sas_wwns[0]); 28110696SDavid.Hollister@Sun.COM mdb_printf("Firmware version: %x.%x.%x (%s)\n", 28210696SDavid.Hollister@Sun.COM PMCS_FW_MAJOR(mp), PMCS_FW_MINOR(mp), PMCS_FW_MICRO(mp), 28310696SDavid.Hollister@Sun.COM fwsupport); 28410696SDavid.Hollister@Sun.COM 28510696SDavid.Hollister@Sun.COM mdb_printf("Number of PHYs: %d\n", m.nphy); 28610696SDavid.Hollister@Sun.COM mdb_printf("Maximum commands: %d\n", m.max_cmd); 28710696SDavid.Hollister@Sun.COM mdb_printf("Maximum devices: %d\n", m.max_dev); 28810696SDavid.Hollister@Sun.COM mdb_printf("I/O queue depth: %d\n", m.ioq_depth); 28910696SDavid.Hollister@Sun.COM if (m.fwlog == 0) { 29010696SDavid.Hollister@Sun.COM mdb_printf("Firmware logging: Disabled\n"); 29110696SDavid.Hollister@Sun.COM } else { 29210696SDavid.Hollister@Sun.COM mdb_printf("Firmware logging: Enabled (%d)\n", m.fwlog); 29310696SDavid.Hollister@Sun.COM } 29410696SDavid.Hollister@Sun.COM } 29510696SDavid.Hollister@Sun.COM 29610696SDavid.Hollister@Sun.COM static void 29710696SDavid.Hollister@Sun.COM display_targets(struct pmcs_hw m, int verbose, int totals_only) 29810696SDavid.Hollister@Sun.COM { 29910696SDavid.Hollister@Sun.COM char *dtype; 30010696SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 30110696SDavid.Hollister@Sun.COM pmcs_phy_t phy; 30210696SDavid.Hollister@Sun.COM uint16_t max_dev, idx; 30310696SDavid.Hollister@Sun.COM uint32_t sas_targets = 0, smp_targets = 0, sata_targets = 0; 30410696SDavid.Hollister@Sun.COM 30510696SDavid.Hollister@Sun.COM max_dev = m.max_dev; 30610696SDavid.Hollister@Sun.COM 30710696SDavid.Hollister@Sun.COM if (targets == NULL) { 30810696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * max_dev, UM_SLEEP); 30910696SDavid.Hollister@Sun.COM } 31010696SDavid.Hollister@Sun.COM 31110696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * max_dev, m.targets) == -1) { 31210696SDavid.Hollister@Sun.COM NOREAD(targets, m.targets); 31310696SDavid.Hollister@Sun.COM return; 31410696SDavid.Hollister@Sun.COM } 31510696SDavid.Hollister@Sun.COM 31610696SDavid.Hollister@Sun.COM if (!totals_only) { 31710696SDavid.Hollister@Sun.COM mdb_printf("\nTarget information:\n"); 31810696SDavid.Hollister@Sun.COM mdb_printf("---------------------------------------\n"); 31910696SDavid.Hollister@Sun.COM mdb_printf("VTGT %-16s %-16s %-5s %8s %s", "SAS Address", 32010696SDavid.Hollister@Sun.COM "PHY Address", "DType", "Active", "DS"); 32110696SDavid.Hollister@Sun.COM mdb_printf("\n"); 32210696SDavid.Hollister@Sun.COM } 32310696SDavid.Hollister@Sun.COM 32410696SDavid.Hollister@Sun.COM for (idx = 0; idx < max_dev; idx++) { 32510696SDavid.Hollister@Sun.COM if (targets[idx] == NULL) { 32610696SDavid.Hollister@Sun.COM continue; 32710696SDavid.Hollister@Sun.COM } 32810696SDavid.Hollister@Sun.COM 32910696SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), targets[idx]) == -1) { 33010696SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, targets[idx]); 33110696SDavid.Hollister@Sun.COM continue; 33210696SDavid.Hollister@Sun.COM } 33310696SDavid.Hollister@Sun.COM 33410696SDavid.Hollister@Sun.COM /* 33510696SDavid.Hollister@Sun.COM * It has to be one of new, assigned or dying to be of interest. 33610696SDavid.Hollister@Sun.COM */ 33710696SDavid.Hollister@Sun.COM if (xs.new == 0 && xs.assigned == 0 && xs.dying == 0) { 33810696SDavid.Hollister@Sun.COM continue; 33910696SDavid.Hollister@Sun.COM } 34010696SDavid.Hollister@Sun.COM 34110696SDavid.Hollister@Sun.COM switch (xs.dtype) { 34210696SDavid.Hollister@Sun.COM case NOTHING: 34310696SDavid.Hollister@Sun.COM dtype = "None"; 34410696SDavid.Hollister@Sun.COM break; 34510696SDavid.Hollister@Sun.COM case SATA: 34610696SDavid.Hollister@Sun.COM dtype = "SATA"; 34710696SDavid.Hollister@Sun.COM sata_targets++; 34810696SDavid.Hollister@Sun.COM break; 34910696SDavid.Hollister@Sun.COM case SAS: 35010696SDavid.Hollister@Sun.COM dtype = "SAS"; 35110696SDavid.Hollister@Sun.COM sas_targets++; 35210696SDavid.Hollister@Sun.COM break; 35310696SDavid.Hollister@Sun.COM case EXPANDER: 35410696SDavid.Hollister@Sun.COM dtype = "SMP"; 35510696SDavid.Hollister@Sun.COM smp_targets++; 35610696SDavid.Hollister@Sun.COM break; 35710696SDavid.Hollister@Sun.COM } 35810696SDavid.Hollister@Sun.COM 35910696SDavid.Hollister@Sun.COM if (totals_only) { 36010696SDavid.Hollister@Sun.COM continue; 36110696SDavid.Hollister@Sun.COM } 36210696SDavid.Hollister@Sun.COM 36310696SDavid.Hollister@Sun.COM if (xs.phy) { 36410696SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), xs.phy) == -1) { 36510696SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, xs.phy); 36610696SDavid.Hollister@Sun.COM continue; 36710696SDavid.Hollister@Sun.COM } 36810696SDavid.Hollister@Sun.COM mdb_printf("%4d ", idx); 36910696SDavid.Hollister@Sun.COM print_sas_address(&phy); 37010696SDavid.Hollister@Sun.COM mdb_printf(" %16p", xs.phy); 37110696SDavid.Hollister@Sun.COM } else { 37210696SDavid.Hollister@Sun.COM mdb_printf("%4d %16s", idx, "<no phy avail>"); 37310696SDavid.Hollister@Sun.COM } 37410696SDavid.Hollister@Sun.COM mdb_printf(" %5s", dtype); 37510696SDavid.Hollister@Sun.COM mdb_printf(" %8d", xs.actv_cnt); 37610696SDavid.Hollister@Sun.COM mdb_printf(" %2d", xs.dev_state); 37710696SDavid.Hollister@Sun.COM 37810696SDavid.Hollister@Sun.COM if (verbose) { 37910696SDavid.Hollister@Sun.COM if (xs.new) { 38010696SDavid.Hollister@Sun.COM mdb_printf(" new"); 38110696SDavid.Hollister@Sun.COM } else if (xs.dying) { 38210696SDavid.Hollister@Sun.COM mdb_printf(" dying"); 38310696SDavid.Hollister@Sun.COM } else if (xs.assigned) { 38410696SDavid.Hollister@Sun.COM mdb_printf(" assigned"); 38510696SDavid.Hollister@Sun.COM } 38610696SDavid.Hollister@Sun.COM if (xs.draining) { 38710696SDavid.Hollister@Sun.COM mdb_printf(" draining"); 38810696SDavid.Hollister@Sun.COM } 38910696SDavid.Hollister@Sun.COM if (xs.reset_wait) { 39010696SDavid.Hollister@Sun.COM mdb_printf(" reset_wait"); 39110696SDavid.Hollister@Sun.COM } 39210696SDavid.Hollister@Sun.COM if (xs.resetting) { 39310696SDavid.Hollister@Sun.COM mdb_printf(" resetting"); 39410696SDavid.Hollister@Sun.COM } 39510696SDavid.Hollister@Sun.COM if (xs.recover_wait) { 39610696SDavid.Hollister@Sun.COM mdb_printf(" recover_wait"); 39710696SDavid.Hollister@Sun.COM } 39810696SDavid.Hollister@Sun.COM if (xs.recovering) { 39910696SDavid.Hollister@Sun.COM mdb_printf(" recovering"); 40010696SDavid.Hollister@Sun.COM } 40110696SDavid.Hollister@Sun.COM if (xs.event_recovery) { 40210696SDavid.Hollister@Sun.COM mdb_printf(" event recovery"); 40310696SDavid.Hollister@Sun.COM } 40410696SDavid.Hollister@Sun.COM if (xs.special_running) { 40510696SDavid.Hollister@Sun.COM mdb_printf(" special_active"); 40610696SDavid.Hollister@Sun.COM } 40710696SDavid.Hollister@Sun.COM if (xs.ncq) { 40810696SDavid.Hollister@Sun.COM mdb_printf(" ncq_tagmap=0x%x qdepth=%d", 40910696SDavid.Hollister@Sun.COM xs.tagmap, xs.qdepth); 41010696SDavid.Hollister@Sun.COM } else if (xs.pio) { 41110696SDavid.Hollister@Sun.COM mdb_printf(" pio"); 41210696SDavid.Hollister@Sun.COM } 41310696SDavid.Hollister@Sun.COM } 41410696SDavid.Hollister@Sun.COM 41510696SDavid.Hollister@Sun.COM mdb_printf("\n"); 41610696SDavid.Hollister@Sun.COM } 41710696SDavid.Hollister@Sun.COM 41810696SDavid.Hollister@Sun.COM if (!totals_only) { 41910696SDavid.Hollister@Sun.COM mdb_printf("\n"); 42010696SDavid.Hollister@Sun.COM } 42110696SDavid.Hollister@Sun.COM 42210696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP)\n", 42310696SDavid.Hollister@Sun.COM "Configured targets:", (sas_targets + sata_targets + smp_targets), 42410696SDavid.Hollister@Sun.COM sas_targets, sata_targets, smp_targets); 42510696SDavid.Hollister@Sun.COM } 42610696SDavid.Hollister@Sun.COM 427*10743SDavid.Hollister@Sun.COM static char * 428*10743SDavid.Hollister@Sun.COM work_state_to_string(uint32_t state) 429*10743SDavid.Hollister@Sun.COM { 430*10743SDavid.Hollister@Sun.COM char *state_string; 431*10743SDavid.Hollister@Sun.COM 432*10743SDavid.Hollister@Sun.COM switch (state) { 433*10743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_NIL: 434*10743SDavid.Hollister@Sun.COM state_string = "Free"; 435*10743SDavid.Hollister@Sun.COM break; 436*10743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_READY: 437*10743SDavid.Hollister@Sun.COM state_string = "Ready"; 438*10743SDavid.Hollister@Sun.COM break; 439*10743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_ONCHIP: 440*10743SDavid.Hollister@Sun.COM state_string = "On Chip"; 441*10743SDavid.Hollister@Sun.COM break; 442*10743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_INTR: 443*10743SDavid.Hollister@Sun.COM state_string = "In Intr"; 444*10743SDavid.Hollister@Sun.COM break; 445*10743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_IOCOMPQ: 446*10743SDavid.Hollister@Sun.COM state_string = "I/O Comp"; 447*10743SDavid.Hollister@Sun.COM break; 448*10743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_ABORTED: 449*10743SDavid.Hollister@Sun.COM state_string = "I/O Aborted"; 450*10743SDavid.Hollister@Sun.COM break; 451*10743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_TIMED_OUT: 452*10743SDavid.Hollister@Sun.COM state_string = "I/O Timed Out"; 453*10743SDavid.Hollister@Sun.COM break; 454*10743SDavid.Hollister@Sun.COM default: 455*10743SDavid.Hollister@Sun.COM state_string = "INVALID"; 456*10743SDavid.Hollister@Sun.COM break; 457*10743SDavid.Hollister@Sun.COM } 458*10743SDavid.Hollister@Sun.COM 459*10743SDavid.Hollister@Sun.COM return (state_string); 460*10743SDavid.Hollister@Sun.COM } 461*10743SDavid.Hollister@Sun.COM 462*10743SDavid.Hollister@Sun.COM static void 463*10743SDavid.Hollister@Sun.COM display_one_work(pmcwork_t *wp, int verbose, int idx) 464*10743SDavid.Hollister@Sun.COM { 465*10743SDavid.Hollister@Sun.COM char *state, *last_state; 466*10743SDavid.Hollister@Sun.COM char *path; 467*10743SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 468*10743SDavid.Hollister@Sun.COM pmcs_phy_t phy; 469*10743SDavid.Hollister@Sun.COM int tgt; 470*10743SDavid.Hollister@Sun.COM 471*10743SDavid.Hollister@Sun.COM state = work_state_to_string(wp->state); 472*10743SDavid.Hollister@Sun.COM last_state = work_state_to_string(wp->last_state); 473*10743SDavid.Hollister@Sun.COM 474*10743SDavid.Hollister@Sun.COM if (wp->ssp_event && wp->ssp_event != 0xffffffff) { 475*10743SDavid.Hollister@Sun.COM mdb_printf("SSP event 0x%x", wp->ssp_event); 476*10743SDavid.Hollister@Sun.COM } 477*10743SDavid.Hollister@Sun.COM 478*10743SDavid.Hollister@Sun.COM tgt = -1; 479*10743SDavid.Hollister@Sun.COM if (wp->xp) { 480*10743SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), wp->xp) == -1) { 481*10743SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, wp->xp); 482*10743SDavid.Hollister@Sun.COM } else { 483*10743SDavid.Hollister@Sun.COM tgt = xs.target_num; 484*10743SDavid.Hollister@Sun.COM } 485*10743SDavid.Hollister@Sun.COM } 486*10743SDavid.Hollister@Sun.COM if (wp->phy) { 487*10743SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), wp->phy) == -1) { 488*10743SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, wp->phy); 489*10743SDavid.Hollister@Sun.COM } 490*10743SDavid.Hollister@Sun.COM path = phy.path; 491*10743SDavid.Hollister@Sun.COM } else { 492*10743SDavid.Hollister@Sun.COM path = "N/A"; 493*10743SDavid.Hollister@Sun.COM } 494*10743SDavid.Hollister@Sun.COM 495*10743SDavid.Hollister@Sun.COM if (verbose) { 496*10743SDavid.Hollister@Sun.COM mdb_printf("%4d ", idx); 497*10743SDavid.Hollister@Sun.COM } 498*10743SDavid.Hollister@Sun.COM if (tgt == -1) { 499*10743SDavid.Hollister@Sun.COM mdb_printf("%08x %10s %20s N/A %8u %1d %1d ", 500*10743SDavid.Hollister@Sun.COM wp->htag, state, path, wp->timer, 501*10743SDavid.Hollister@Sun.COM wp->onwire, wp->dead); 502*10743SDavid.Hollister@Sun.COM } else { 503*10743SDavid.Hollister@Sun.COM mdb_printf("%08x %10s %20s %8d %8u %1d %1d ", 504*10743SDavid.Hollister@Sun.COM wp->htag, state, path, tgt, wp->timer, 505*10743SDavid.Hollister@Sun.COM wp->onwire, wp->dead); 506*10743SDavid.Hollister@Sun.COM } 507*10743SDavid.Hollister@Sun.COM if (verbose) { 508*10743SDavid.Hollister@Sun.COM mdb_printf("%08x %10s 0x%016p 0x%016p\n", 509*10743SDavid.Hollister@Sun.COM wp->last_htag, last_state, wp->last_phy, wp->last_xp); 510*10743SDavid.Hollister@Sun.COM } else { 511*10743SDavid.Hollister@Sun.COM mdb_printf("\n"); 512*10743SDavid.Hollister@Sun.COM } 513*10743SDavid.Hollister@Sun.COM } 514*10743SDavid.Hollister@Sun.COM 51510696SDavid.Hollister@Sun.COM static void 51610696SDavid.Hollister@Sun.COM display_work(struct pmcs_hw m, int verbose) 51710696SDavid.Hollister@Sun.COM { 51810696SDavid.Hollister@Sun.COM int idx; 519*10743SDavid.Hollister@Sun.COM boolean_t header_printed = B_FALSE; 52010696SDavid.Hollister@Sun.COM pmcwork_t work, *wp = &work; 52110696SDavid.Hollister@Sun.COM uintptr_t _wp; 52210696SDavid.Hollister@Sun.COM 52310696SDavid.Hollister@Sun.COM mdb_printf("\nActive Work structure information:\n"); 52410696SDavid.Hollister@Sun.COM mdb_printf("----------------------------------\n"); 52510696SDavid.Hollister@Sun.COM 52610696SDavid.Hollister@Sun.COM _wp = (uintptr_t)m.work; 52710696SDavid.Hollister@Sun.COM 52810696SDavid.Hollister@Sun.COM for (idx = 0; idx < m.max_cmd; idx++, _wp += sizeof (pmcwork_t)) { 52910696SDavid.Hollister@Sun.COM if (MDB_RD(&work, sizeof (pmcwork_t), _wp) == -1) { 53010696SDavid.Hollister@Sun.COM NOREAD(pmcwork_t, _wp); 53110696SDavid.Hollister@Sun.COM continue; 53210696SDavid.Hollister@Sun.COM } 533*10743SDavid.Hollister@Sun.COM 534*10743SDavid.Hollister@Sun.COM if (!verbose && (wp->htag == PMCS_TAG_TYPE_FREE)) { 53510696SDavid.Hollister@Sun.COM continue; 53610696SDavid.Hollister@Sun.COM } 537*10743SDavid.Hollister@Sun.COM 538*10743SDavid.Hollister@Sun.COM if (header_printed == B_FALSE) { 539*10743SDavid.Hollister@Sun.COM if (verbose) { 540*10743SDavid.Hollister@Sun.COM mdb_printf("%4s ", "Idx"); 541*10743SDavid.Hollister@Sun.COM } 542*10743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D ", 54310696SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 544*10743SDavid.Hollister@Sun.COM if (verbose) { 545*10743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %18s %18s\n", "LastHTAG", 546*10743SDavid.Hollister@Sun.COM "LastState", "LastPHY", "LastTgt"); 547*10743SDavid.Hollister@Sun.COM } else { 548*10743SDavid.Hollister@Sun.COM mdb_printf("\n"); 549*10743SDavid.Hollister@Sun.COM } 550*10743SDavid.Hollister@Sun.COM header_printed = B_TRUE; 55110696SDavid.Hollister@Sun.COM } 552*10743SDavid.Hollister@Sun.COM 553*10743SDavid.Hollister@Sun.COM display_one_work(wp, verbose, idx); 55410696SDavid.Hollister@Sun.COM } 55510696SDavid.Hollister@Sun.COM } 55610696SDavid.Hollister@Sun.COM 55710696SDavid.Hollister@Sun.COM static void 558*10743SDavid.Hollister@Sun.COM print_spcmd(pmcs_cmd_t *sp, void *kaddr, int printhdr, int verbose) 55910696SDavid.Hollister@Sun.COM { 560*10743SDavid.Hollister@Sun.COM int cdb_size, idx; 561*10743SDavid.Hollister@Sun.COM struct scsi_pkt pkt; 562*10743SDavid.Hollister@Sun.COM uchar_t cdb[256]; 563*10743SDavid.Hollister@Sun.COM 56410696SDavid.Hollister@Sun.COM if (printhdr) { 565*10743SDavid.Hollister@Sun.COM if (verbose) { 566*10743SDavid.Hollister@Sun.COM mdb_printf("%16s %16s %16s %8s %s CDB\n", "Command", 567*10743SDavid.Hollister@Sun.COM "SCSA pkt", "DMA Chunks", "HTAG", "SATL Tag"); 568*10743SDavid.Hollister@Sun.COM } else { 569*10743SDavid.Hollister@Sun.COM mdb_printf("%16s %16s %16s %8s %s\n", "Command", 570*10743SDavid.Hollister@Sun.COM "SCSA pkt", "DMA Chunks", "HTAG", "SATL Tag"); 571*10743SDavid.Hollister@Sun.COM } 57210696SDavid.Hollister@Sun.COM } 573*10743SDavid.Hollister@Sun.COM 574*10743SDavid.Hollister@Sun.COM mdb_printf("%16p %16p %16p %08x %08x ", 57510696SDavid.Hollister@Sun.COM kaddr, sp->cmd_pkt, sp->cmd_clist, sp->cmd_tag, sp->cmd_satltag); 576*10743SDavid.Hollister@Sun.COM 577*10743SDavid.Hollister@Sun.COM /* 578*10743SDavid.Hollister@Sun.COM * If we're printing verbose, dump the CDB as well. 579*10743SDavid.Hollister@Sun.COM */ 580*10743SDavid.Hollister@Sun.COM if (verbose) { 581*10743SDavid.Hollister@Sun.COM if (sp->cmd_pkt) { 582*10743SDavid.Hollister@Sun.COM if (mdb_vread(&pkt, sizeof (struct scsi_pkt), 583*10743SDavid.Hollister@Sun.COM (uintptr_t)sp->cmd_pkt) != 584*10743SDavid.Hollister@Sun.COM sizeof (struct scsi_pkt)) { 585*10743SDavid.Hollister@Sun.COM mdb_warn("Unable to read SCSI pkt\n"); 586*10743SDavid.Hollister@Sun.COM return; 587*10743SDavid.Hollister@Sun.COM } 588*10743SDavid.Hollister@Sun.COM cdb_size = pkt.pkt_cdblen; 589*10743SDavid.Hollister@Sun.COM if (mdb_vread(&cdb[0], cdb_size, 590*10743SDavid.Hollister@Sun.COM (uintptr_t)pkt.pkt_cdbp) != cdb_size) { 591*10743SDavid.Hollister@Sun.COM mdb_warn("Unable to read CDB\n"); 592*10743SDavid.Hollister@Sun.COM return; 593*10743SDavid.Hollister@Sun.COM } 594*10743SDavid.Hollister@Sun.COM 595*10743SDavid.Hollister@Sun.COM for (idx = 0; idx < cdb_size; idx++) { 596*10743SDavid.Hollister@Sun.COM mdb_printf("%02x ", cdb[idx]); 597*10743SDavid.Hollister@Sun.COM } 598*10743SDavid.Hollister@Sun.COM } else { 599*10743SDavid.Hollister@Sun.COM mdb_printf("N/A"); 600*10743SDavid.Hollister@Sun.COM } 601*10743SDavid.Hollister@Sun.COM 602*10743SDavid.Hollister@Sun.COM mdb_printf("\n"); 603*10743SDavid.Hollister@Sun.COM } else { 604*10743SDavid.Hollister@Sun.COM mdb_printf("\n"); 605*10743SDavid.Hollister@Sun.COM } 60610696SDavid.Hollister@Sun.COM } 60710696SDavid.Hollister@Sun.COM 60810696SDavid.Hollister@Sun.COM /*ARGSUSED1*/ 60910696SDavid.Hollister@Sun.COM static void 61010696SDavid.Hollister@Sun.COM display_waitqs(struct pmcs_hw m, int verbose) 61110696SDavid.Hollister@Sun.COM { 61210696SDavid.Hollister@Sun.COM pmcs_cmd_t *sp, s; 61310696SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 61410696SDavid.Hollister@Sun.COM int first, i; 61510696SDavid.Hollister@Sun.COM int max_dev = m.max_dev; 61610696SDavid.Hollister@Sun.COM 61710696SDavid.Hollister@Sun.COM sp = m.dq.stqh_first; 61810696SDavid.Hollister@Sun.COM first = 1; 61910696SDavid.Hollister@Sun.COM while (sp) { 62010696SDavid.Hollister@Sun.COM if (first) { 62110696SDavid.Hollister@Sun.COM mdb_printf("\nDead Command Queue:\n"); 62210696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 62310696SDavid.Hollister@Sun.COM } 62410696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 62510696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 62610696SDavid.Hollister@Sun.COM break; 62710696SDavid.Hollister@Sun.COM } 628*10743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 62910696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 63010696SDavid.Hollister@Sun.COM first = 0; 63110696SDavid.Hollister@Sun.COM } 63210696SDavid.Hollister@Sun.COM 63310696SDavid.Hollister@Sun.COM sp = m.cq.stqh_first; 63410696SDavid.Hollister@Sun.COM first = 1; 63510696SDavid.Hollister@Sun.COM while (sp) { 63610696SDavid.Hollister@Sun.COM if (first) { 63710696SDavid.Hollister@Sun.COM mdb_printf("\nCompletion Command Queue:\n"); 63810696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 63910696SDavid.Hollister@Sun.COM } 64010696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 64110696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 64210696SDavid.Hollister@Sun.COM break; 64310696SDavid.Hollister@Sun.COM } 644*10743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 64510696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 64610696SDavid.Hollister@Sun.COM first = 0; 64710696SDavid.Hollister@Sun.COM } 64810696SDavid.Hollister@Sun.COM 64910696SDavid.Hollister@Sun.COM 65010696SDavid.Hollister@Sun.COM if (targets == NULL) { 65110696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * max_dev, UM_SLEEP); 65210696SDavid.Hollister@Sun.COM } 65310696SDavid.Hollister@Sun.COM 65410696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * max_dev, m.targets) == -1) { 65510696SDavid.Hollister@Sun.COM NOREAD(targets, m.targets); 65610696SDavid.Hollister@Sun.COM return; 65710696SDavid.Hollister@Sun.COM } 65810696SDavid.Hollister@Sun.COM 65910696SDavid.Hollister@Sun.COM for (i = 0; i < max_dev; i++) { 66010696SDavid.Hollister@Sun.COM if (targets[i] == NULL) { 66110696SDavid.Hollister@Sun.COM continue; 66210696SDavid.Hollister@Sun.COM } 66310696SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), targets[i]) == -1) { 66410696SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, targets[i]); 66510696SDavid.Hollister@Sun.COM continue; 66610696SDavid.Hollister@Sun.COM } 66710696SDavid.Hollister@Sun.COM sp = xs.wq.stqh_first; 66810696SDavid.Hollister@Sun.COM first = 1; 66910696SDavid.Hollister@Sun.COM while (sp) { 67010696SDavid.Hollister@Sun.COM if (first) { 67110696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Wait Queue:\n", 67210696SDavid.Hollister@Sun.COM xs.target_num); 67310696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 67410696SDavid.Hollister@Sun.COM } 67510696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 67610696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 67710696SDavid.Hollister@Sun.COM break; 67810696SDavid.Hollister@Sun.COM } 679*10743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 68010696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 68110696SDavid.Hollister@Sun.COM first = 0; 68210696SDavid.Hollister@Sun.COM } 68310696SDavid.Hollister@Sun.COM sp = xs.aq.stqh_first; 68410696SDavid.Hollister@Sun.COM first = 1; 68510696SDavid.Hollister@Sun.COM while (sp) { 68610696SDavid.Hollister@Sun.COM if (first) { 68710696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Active Queue:\n", 68810696SDavid.Hollister@Sun.COM xs.target_num); 68910696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 69010696SDavid.Hollister@Sun.COM } 69110696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 69210696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 69310696SDavid.Hollister@Sun.COM break; 69410696SDavid.Hollister@Sun.COM } 695*10743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 69610696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 69710696SDavid.Hollister@Sun.COM first = 0; 69810696SDavid.Hollister@Sun.COM } 69910696SDavid.Hollister@Sun.COM sp = xs.sq.stqh_first; 70010696SDavid.Hollister@Sun.COM first = 1; 70110696SDavid.Hollister@Sun.COM while (sp) { 70210696SDavid.Hollister@Sun.COM if (first) { 70310696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Special Queue:\n", 70410696SDavid.Hollister@Sun.COM xs.target_num); 70510696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 70610696SDavid.Hollister@Sun.COM } 70710696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 70810696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 70910696SDavid.Hollister@Sun.COM break; 71010696SDavid.Hollister@Sun.COM } 711*10743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 71210696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 71310696SDavid.Hollister@Sun.COM first = 0; 71410696SDavid.Hollister@Sun.COM } 71510696SDavid.Hollister@Sun.COM } 71610696SDavid.Hollister@Sun.COM } 71710696SDavid.Hollister@Sun.COM 71810696SDavid.Hollister@Sun.COM static char * 71910696SDavid.Hollister@Sun.COM ibq_type(int qnum) 72010696SDavid.Hollister@Sun.COM { 72110696SDavid.Hollister@Sun.COM if (qnum < 0 || qnum >= PMCS_NIQ) { 72210696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 72310696SDavid.Hollister@Sun.COM } 72410696SDavid.Hollister@Sun.COM 72510696SDavid.Hollister@Sun.COM if (qnum < PMCS_IQ_OTHER) { 72610696SDavid.Hollister@Sun.COM return ("I/O"); 72710696SDavid.Hollister@Sun.COM } 72810696SDavid.Hollister@Sun.COM 72910696SDavid.Hollister@Sun.COM return ("Other"); 73010696SDavid.Hollister@Sun.COM } 73110696SDavid.Hollister@Sun.COM 73210696SDavid.Hollister@Sun.COM static char * 73310696SDavid.Hollister@Sun.COM obq_type(int qnum) 73410696SDavid.Hollister@Sun.COM { 73510696SDavid.Hollister@Sun.COM switch (qnum) { 73610696SDavid.Hollister@Sun.COM case PMCS_OQ_IODONE: 73710696SDavid.Hollister@Sun.COM return ("I/O"); 73810696SDavid.Hollister@Sun.COM break; 73910696SDavid.Hollister@Sun.COM case PMCS_OQ_GENERAL: 74010696SDavid.Hollister@Sun.COM return ("General"); 74110696SDavid.Hollister@Sun.COM break; 74210696SDavid.Hollister@Sun.COM case PMCS_OQ_EVENTS: 74310696SDavid.Hollister@Sun.COM return ("Events"); 74410696SDavid.Hollister@Sun.COM break; 74510696SDavid.Hollister@Sun.COM default: 74610696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 74710696SDavid.Hollister@Sun.COM } 74810696SDavid.Hollister@Sun.COM } 74910696SDavid.Hollister@Sun.COM 75010696SDavid.Hollister@Sun.COM static char * 75110696SDavid.Hollister@Sun.COM iomb_cat(uint32_t cat) 75210696SDavid.Hollister@Sun.COM { 75310696SDavid.Hollister@Sun.COM switch (cat) { 75410696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_NET: 75510696SDavid.Hollister@Sun.COM return ("NET"); 75610696SDavid.Hollister@Sun.COM break; 75710696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_FC: 75810696SDavid.Hollister@Sun.COM return ("FC"); 75910696SDavid.Hollister@Sun.COM break; 76010696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_SAS: 76110696SDavid.Hollister@Sun.COM return ("SAS"); 76210696SDavid.Hollister@Sun.COM break; 76310696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_SCSI: 76410696SDavid.Hollister@Sun.COM return ("SCSI"); 76510696SDavid.Hollister@Sun.COM break; 76610696SDavid.Hollister@Sun.COM default: 76710696SDavid.Hollister@Sun.COM return ("???"); 76810696SDavid.Hollister@Sun.COM } 76910696SDavid.Hollister@Sun.COM } 77010696SDavid.Hollister@Sun.COM 77110696SDavid.Hollister@Sun.COM static char * 77210696SDavid.Hollister@Sun.COM inbound_iomb_opcode(uint32_t opcode) 77310696SDavid.Hollister@Sun.COM { 77410696SDavid.Hollister@Sun.COM switch (opcode) { 77510696SDavid.Hollister@Sun.COM case PMCIN_ECHO: 77610696SDavid.Hollister@Sun.COM return ("ECHO"); 77710696SDavid.Hollister@Sun.COM break; 77810696SDavid.Hollister@Sun.COM case PMCIN_GET_INFO: 77910696SDavid.Hollister@Sun.COM return ("GET_INFO"); 78010696SDavid.Hollister@Sun.COM break; 78110696SDavid.Hollister@Sun.COM case PMCIN_GET_VPD: 78210696SDavid.Hollister@Sun.COM return ("GET_VPD"); 78310696SDavid.Hollister@Sun.COM break; 78410696SDavid.Hollister@Sun.COM case PMCIN_PHY_START: 78510696SDavid.Hollister@Sun.COM return ("PHY_START"); 78610696SDavid.Hollister@Sun.COM break; 78710696SDavid.Hollister@Sun.COM case PMCIN_PHY_STOP: 78810696SDavid.Hollister@Sun.COM return ("PHY_STOP"); 78910696SDavid.Hollister@Sun.COM break; 79010696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_IO_START: 79110696SDavid.Hollister@Sun.COM return ("INI_IO_START"); 79210696SDavid.Hollister@Sun.COM break; 79310696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_TM_START: 79410696SDavid.Hollister@Sun.COM return ("INI_TM_START"); 79510696SDavid.Hollister@Sun.COM break; 79610696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EXT_IO_START: 79710696SDavid.Hollister@Sun.COM return ("INI_EXT_IO_START"); 79810696SDavid.Hollister@Sun.COM break; 79910696SDavid.Hollister@Sun.COM case PMCIN_DEVICE_HANDLE_ACCEPT: 80010696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_ACCEPT"); 80110696SDavid.Hollister@Sun.COM break; 80210696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_IO_START: 80310696SDavid.Hollister@Sun.COM return ("TGT_IO_START"); 80410696SDavid.Hollister@Sun.COM break; 80510696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_RESPONSE_START: 80610696SDavid.Hollister@Sun.COM return ("TGT_RESPONSE_START"); 80710696SDavid.Hollister@Sun.COM break; 80810696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EDC_EXT_IO_START: 80910696SDavid.Hollister@Sun.COM return ("INI_EDC_EXT_IO_START"); 81010696SDavid.Hollister@Sun.COM break; 81110696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EDC_EXT_IO_START1: 81210696SDavid.Hollister@Sun.COM return ("INI_EDC_EXT_IO_START1"); 81310696SDavid.Hollister@Sun.COM break; 81410696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_EDC_IO_START: 81510696SDavid.Hollister@Sun.COM return ("TGT_EDC_IO_START"); 81610696SDavid.Hollister@Sun.COM break; 81710696SDavid.Hollister@Sun.COM case PMCIN_SSP_ABORT: 81810696SDavid.Hollister@Sun.COM return ("SSP_ABORT"); 81910696SDavid.Hollister@Sun.COM break; 82010696SDavid.Hollister@Sun.COM case PMCIN_DEREGISTER_DEVICE_HANDLE: 82110696SDavid.Hollister@Sun.COM return ("DEREGISTER_DEVICE_HANDLE"); 82210696SDavid.Hollister@Sun.COM break; 82310696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_HANDLE: 82410696SDavid.Hollister@Sun.COM return ("GET_DEVICE_HANDLE"); 82510696SDavid.Hollister@Sun.COM break; 82610696SDavid.Hollister@Sun.COM case PMCIN_SMP_REQUEST: 82710696SDavid.Hollister@Sun.COM return ("SMP_REQUEST"); 82810696SDavid.Hollister@Sun.COM break; 82910696SDavid.Hollister@Sun.COM case PMCIN_SMP_RESPONSE: 83010696SDavid.Hollister@Sun.COM return ("SMP_RESPONSE"); 83110696SDavid.Hollister@Sun.COM break; 83210696SDavid.Hollister@Sun.COM case PMCIN_SMP_ABORT: 83310696SDavid.Hollister@Sun.COM return ("SMP_ABORT"); 83410696SDavid.Hollister@Sun.COM break; 83510696SDavid.Hollister@Sun.COM case PMCIN_ASSISTED_DISCOVERY: 83610696SDavid.Hollister@Sun.COM return ("ASSISTED_DISCOVERY"); 83710696SDavid.Hollister@Sun.COM break; 83810696SDavid.Hollister@Sun.COM case PMCIN_REGISTER_DEVICE: 83910696SDavid.Hollister@Sun.COM return ("REGISTER_DEVICE"); 84010696SDavid.Hollister@Sun.COM break; 84110696SDavid.Hollister@Sun.COM case PMCIN_SATA_HOST_IO_START: 84210696SDavid.Hollister@Sun.COM return ("SATA_HOST_IO_START"); 84310696SDavid.Hollister@Sun.COM break; 84410696SDavid.Hollister@Sun.COM case PMCIN_SATA_ABORT: 84510696SDavid.Hollister@Sun.COM return ("SATA_ABORT"); 84610696SDavid.Hollister@Sun.COM break; 84710696SDavid.Hollister@Sun.COM case PMCIN_LOCAL_PHY_CONTROL: 84810696SDavid.Hollister@Sun.COM return ("LOCAL_PHY_CONTROL"); 84910696SDavid.Hollister@Sun.COM break; 85010696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_INFO: 85110696SDavid.Hollister@Sun.COM return ("GET_DEVICE_INFO"); 85210696SDavid.Hollister@Sun.COM break; 85310696SDavid.Hollister@Sun.COM case PMCIN_TWI: 85410696SDavid.Hollister@Sun.COM return ("TWI"); 85510696SDavid.Hollister@Sun.COM break; 85610696SDavid.Hollister@Sun.COM case PMCIN_FW_FLASH_UPDATE: 85710696SDavid.Hollister@Sun.COM return ("FW_FLASH_UPDATE"); 85810696SDavid.Hollister@Sun.COM break; 85910696SDavid.Hollister@Sun.COM case PMCIN_SET_VPD: 86010696SDavid.Hollister@Sun.COM return ("SET_VPD"); 86110696SDavid.Hollister@Sun.COM break; 86210696SDavid.Hollister@Sun.COM case PMCIN_GPIO: 86310696SDavid.Hollister@Sun.COM return ("GPIO"); 86410696SDavid.Hollister@Sun.COM break; 86510696SDavid.Hollister@Sun.COM case PMCIN_SAS_DIAG_MODE_START_END: 86610696SDavid.Hollister@Sun.COM return ("SAS_DIAG_MODE_START_END"); 86710696SDavid.Hollister@Sun.COM break; 86810696SDavid.Hollister@Sun.COM case PMCIN_SAS_DIAG_EXECUTE: 86910696SDavid.Hollister@Sun.COM return ("SAS_DIAG_EXECUTE"); 87010696SDavid.Hollister@Sun.COM break; 87110696SDavid.Hollister@Sun.COM case PMCIN_SAW_HW_EVENT_ACK: 87210696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT_ACK"); 87310696SDavid.Hollister@Sun.COM break; 87410696SDavid.Hollister@Sun.COM case PMCIN_GET_TIME_STAMP: 87510696SDavid.Hollister@Sun.COM return ("GET_TIME_STAMP"); 87610696SDavid.Hollister@Sun.COM break; 87710696SDavid.Hollister@Sun.COM case PMCIN_PORT_CONTROL: 87810696SDavid.Hollister@Sun.COM return ("PORT_CONTROL"); 87910696SDavid.Hollister@Sun.COM break; 88010696SDavid.Hollister@Sun.COM case PMCIN_GET_NVMD_DATA: 88110696SDavid.Hollister@Sun.COM return ("GET_NVMD_DATA"); 88210696SDavid.Hollister@Sun.COM break; 88310696SDavid.Hollister@Sun.COM case PMCIN_SET_NVMD_DATA: 88410696SDavid.Hollister@Sun.COM return ("SET_NVMD_DATA"); 88510696SDavid.Hollister@Sun.COM break; 88610696SDavid.Hollister@Sun.COM case PMCIN_SET_DEVICE_STATE: 88710696SDavid.Hollister@Sun.COM return ("SET_DEVICE_STATE"); 88810696SDavid.Hollister@Sun.COM break; 88910696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_STATE: 89010696SDavid.Hollister@Sun.COM return ("GET_DEVICE_STATE"); 89110696SDavid.Hollister@Sun.COM break; 89210696SDavid.Hollister@Sun.COM default: 89310696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 89410696SDavid.Hollister@Sun.COM break; 89510696SDavid.Hollister@Sun.COM } 89610696SDavid.Hollister@Sun.COM } 89710696SDavid.Hollister@Sun.COM 89810696SDavid.Hollister@Sun.COM static char * 89910696SDavid.Hollister@Sun.COM outbound_iomb_opcode(uint32_t opcode) 90010696SDavid.Hollister@Sun.COM { 90110696SDavid.Hollister@Sun.COM switch (opcode) { 90210696SDavid.Hollister@Sun.COM case PMCOUT_ECHO: 90310696SDavid.Hollister@Sun.COM return ("ECHO"); 90410696SDavid.Hollister@Sun.COM break; 90510696SDavid.Hollister@Sun.COM case PMCOUT_GET_INFO: 90610696SDavid.Hollister@Sun.COM return ("GET_INFO"); 90710696SDavid.Hollister@Sun.COM break; 90810696SDavid.Hollister@Sun.COM case PMCOUT_GET_VPD: 90910696SDavid.Hollister@Sun.COM return ("GET_VPD"); 91010696SDavid.Hollister@Sun.COM break; 91110696SDavid.Hollister@Sun.COM case PMCOUT_SAS_HW_EVENT: 91210696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT"); 91310696SDavid.Hollister@Sun.COM break; 91410696SDavid.Hollister@Sun.COM case PMCOUT_SSP_COMPLETION: 91510696SDavid.Hollister@Sun.COM return ("SSP_COMPLETION"); 91610696SDavid.Hollister@Sun.COM break; 91710696SDavid.Hollister@Sun.COM case PMCOUT_SMP_COMPLETION: 91810696SDavid.Hollister@Sun.COM return ("SMP_COMPLETION"); 91910696SDavid.Hollister@Sun.COM break; 92010696SDavid.Hollister@Sun.COM case PMCOUT_LOCAL_PHY_CONTROL: 92110696SDavid.Hollister@Sun.COM return ("LOCAL_PHY_CONTROL"); 92210696SDavid.Hollister@Sun.COM break; 92310696SDavid.Hollister@Sun.COM case PMCOUT_SAS_ASSISTED_DISCOVERY_EVENT: 92410696SDavid.Hollister@Sun.COM return ("SAS_ASSISTED_DISCOVERY_SENT"); 92510696SDavid.Hollister@Sun.COM break; 92610696SDavid.Hollister@Sun.COM case PMCOUT_SATA_ASSISTED_DISCOVERY_EVENT: 92710696SDavid.Hollister@Sun.COM return ("SATA_ASSISTED_DISCOVERY_SENT"); 92810696SDavid.Hollister@Sun.COM break; 92910696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_REGISTRATION: 93010696SDavid.Hollister@Sun.COM return ("DEVICE_REGISTRATION"); 93110696SDavid.Hollister@Sun.COM break; 93210696SDavid.Hollister@Sun.COM case PMCOUT_DEREGISTER_DEVICE_HANDLE: 93310696SDavid.Hollister@Sun.COM return ("DEREGISTER_DEVICE_HANDLE"); 93410696SDavid.Hollister@Sun.COM break; 93510696SDavid.Hollister@Sun.COM case PMCOUT_GET_DEVICE_HANDLE: 93610696SDavid.Hollister@Sun.COM return ("GET_DEVICE_HANDLE"); 93710696SDavid.Hollister@Sun.COM break; 93810696SDavid.Hollister@Sun.COM case PMCOUT_SATA_COMPLETION: 93910696SDavid.Hollister@Sun.COM return ("SATA_COMPLETION"); 94010696SDavid.Hollister@Sun.COM break; 94110696SDavid.Hollister@Sun.COM case PMCOUT_SATA_EVENT: 94210696SDavid.Hollister@Sun.COM return ("SATA_EVENT"); 94310696SDavid.Hollister@Sun.COM break; 94410696SDavid.Hollister@Sun.COM case PMCOUT_SSP_EVENT: 94510696SDavid.Hollister@Sun.COM return ("SSP_EVENT"); 94610696SDavid.Hollister@Sun.COM break; 94710696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_HANDLE_ARRIVED: 94810696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_ARRIVED"); 94910696SDavid.Hollister@Sun.COM break; 95010696SDavid.Hollister@Sun.COM case PMCOUT_SMP_REQUEST_RECEIVED: 95110696SDavid.Hollister@Sun.COM return ("SMP_REQUEST_RECEIVED"); 95210696SDavid.Hollister@Sun.COM break; 95310696SDavid.Hollister@Sun.COM case PMCOUT_SSP_REQUEST_RECEIVED: 95410696SDavid.Hollister@Sun.COM return ("SSP_REQUEST_RECEIVED"); 95510696SDavid.Hollister@Sun.COM break; 95610696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_INFO: 95710696SDavid.Hollister@Sun.COM return ("DEVICE_INFO"); 95810696SDavid.Hollister@Sun.COM break; 95910696SDavid.Hollister@Sun.COM case PMCOUT_FW_FLASH_UPDATE: 96010696SDavid.Hollister@Sun.COM return ("FW_FLASH_UPDATE"); 96110696SDavid.Hollister@Sun.COM break; 96210696SDavid.Hollister@Sun.COM case PMCOUT_SET_VPD: 96310696SDavid.Hollister@Sun.COM return ("SET_VPD"); 96410696SDavid.Hollister@Sun.COM break; 96510696SDavid.Hollister@Sun.COM case PMCOUT_GPIO: 96610696SDavid.Hollister@Sun.COM return ("GPIO"); 96710696SDavid.Hollister@Sun.COM break; 96810696SDavid.Hollister@Sun.COM case PMCOUT_GPIO_EVENT: 96910696SDavid.Hollister@Sun.COM return ("GPIO_EVENT"); 97010696SDavid.Hollister@Sun.COM break; 97110696SDavid.Hollister@Sun.COM case PMCOUT_GENERAL_EVENT: 97210696SDavid.Hollister@Sun.COM return ("GENERAL_EVENT"); 97310696SDavid.Hollister@Sun.COM break; 97410696SDavid.Hollister@Sun.COM case PMCOUT_TWI: 97510696SDavid.Hollister@Sun.COM return ("TWI"); 97610696SDavid.Hollister@Sun.COM break; 97710696SDavid.Hollister@Sun.COM case PMCOUT_SSP_ABORT: 97810696SDavid.Hollister@Sun.COM return ("SSP_ABORT"); 97910696SDavid.Hollister@Sun.COM break; 98010696SDavid.Hollister@Sun.COM case PMCOUT_SATA_ABORT: 98110696SDavid.Hollister@Sun.COM return ("SATA_ABORT"); 98210696SDavid.Hollister@Sun.COM break; 98310696SDavid.Hollister@Sun.COM case PMCOUT_SAS_DIAG_MODE_START_END: 98410696SDavid.Hollister@Sun.COM return ("SAS_DIAG_MODE_START_END"); 98510696SDavid.Hollister@Sun.COM break; 98610696SDavid.Hollister@Sun.COM case PMCOUT_SAS_DIAG_EXECUTE: 98710696SDavid.Hollister@Sun.COM return ("SAS_DIAG_EXECUTE"); 98810696SDavid.Hollister@Sun.COM break; 98910696SDavid.Hollister@Sun.COM case PMCOUT_GET_TIME_STAMP: 99010696SDavid.Hollister@Sun.COM return ("GET_TIME_STAMP"); 99110696SDavid.Hollister@Sun.COM break; 99210696SDavid.Hollister@Sun.COM case PMCOUT_SAS_HW_EVENT_ACK_ACK: 99310696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT_ACK_ACK"); 99410696SDavid.Hollister@Sun.COM break; 99510696SDavid.Hollister@Sun.COM case PMCOUT_PORT_CONTROL: 99610696SDavid.Hollister@Sun.COM return ("PORT_CONTROL"); 99710696SDavid.Hollister@Sun.COM break; 99810696SDavid.Hollister@Sun.COM case PMCOUT_SKIP_ENTRIES: 99910696SDavid.Hollister@Sun.COM return ("SKIP_ENTRIES"); 100010696SDavid.Hollister@Sun.COM break; 100110696SDavid.Hollister@Sun.COM case PMCOUT_SMP_ABORT: 100210696SDavid.Hollister@Sun.COM return ("SMP_ABORT"); 100310696SDavid.Hollister@Sun.COM break; 100410696SDavid.Hollister@Sun.COM case PMCOUT_GET_NVMD_DATA: 100510696SDavid.Hollister@Sun.COM return ("GET_NVMD_DATA"); 100610696SDavid.Hollister@Sun.COM break; 100710696SDavid.Hollister@Sun.COM case PMCOUT_SET_NVMD_DATA: 100810696SDavid.Hollister@Sun.COM return ("SET_NVMD_DATA"); 100910696SDavid.Hollister@Sun.COM break; 101010696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_HANDLE_REMOVED: 101110696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_REMOVED"); 101210696SDavid.Hollister@Sun.COM break; 101310696SDavid.Hollister@Sun.COM case PMCOUT_SET_DEVICE_STATE: 101410696SDavid.Hollister@Sun.COM return ("SET_DEVICE_STATE"); 101510696SDavid.Hollister@Sun.COM break; 101610696SDavid.Hollister@Sun.COM case PMCOUT_GET_DEVICE_STATE: 101710696SDavid.Hollister@Sun.COM return ("GET_DEVICE_STATE"); 101810696SDavid.Hollister@Sun.COM break; 101910696SDavid.Hollister@Sun.COM case PMCOUT_SET_DEVICE_INFO: 102010696SDavid.Hollister@Sun.COM return ("SET_DEVICE_INFO"); 102110696SDavid.Hollister@Sun.COM break; 102210696SDavid.Hollister@Sun.COM default: 102310696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 102410696SDavid.Hollister@Sun.COM break; 102510696SDavid.Hollister@Sun.COM } 102610696SDavid.Hollister@Sun.COM } 102710696SDavid.Hollister@Sun.COM 102810696SDavid.Hollister@Sun.COM static void 102910696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(uint32_t *qentryp, int idx) 103010696SDavid.Hollister@Sun.COM { 103110696SDavid.Hollister@Sun.COM int qeidx; 103210696SDavid.Hollister@Sun.COM uint32_t word0 = LE_32(*qentryp); 103310696SDavid.Hollister@Sun.COM 103410696SDavid.Hollister@Sun.COM mdb_printf("Entry #%02d\n", idx); 103510696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 103610696SDavid.Hollister@Sun.COM 103710696SDavid.Hollister@Sun.COM mdb_printf("Header: 0x%08x (", word0); 103810696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_VALID) { 103910696SDavid.Hollister@Sun.COM mdb_printf("VALID, "); 104010696SDavid.Hollister@Sun.COM } 104110696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_HIPRI) { 104210696SDavid.Hollister@Sun.COM mdb_printf("HIPRI, "); 104310696SDavid.Hollister@Sun.COM } 104410696SDavid.Hollister@Sun.COM mdb_printf("OBID=%d, ", 104510696SDavid.Hollister@Sun.COM (word0 & PMCS_IOMB_OBID_MASK) >> PMCS_IOMB_OBID_SHIFT); 104610696SDavid.Hollister@Sun.COM mdb_printf("CAT=%s, ", 104710696SDavid.Hollister@Sun.COM iomb_cat((word0 & PMCS_IOMB_CAT_MASK) >> PMCS_IOMB_CAT_SHIFT)); 104810696SDavid.Hollister@Sun.COM mdb_printf("OPCODE=%s", 104910696SDavid.Hollister@Sun.COM outbound_iomb_opcode(word0 & PMCS_IOMB_OPCODE_MASK)); 105010696SDavid.Hollister@Sun.COM mdb_printf(")\n"); 105110696SDavid.Hollister@Sun.COM 105210696SDavid.Hollister@Sun.COM mdb_printf("Remaining Payload:\n"); 105310696SDavid.Hollister@Sun.COM 105410696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 105510696SDavid.Hollister@Sun.COM for (qeidx = 1; qeidx < (PMCS_QENTRY_SIZE / 4); qeidx++) { 105610696SDavid.Hollister@Sun.COM mdb_printf("%08x ", LE_32(*(qentryp + qeidx))); 105710696SDavid.Hollister@Sun.COM } 105810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 105910696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 106010696SDavid.Hollister@Sun.COM } 106110696SDavid.Hollister@Sun.COM 106210696SDavid.Hollister@Sun.COM static void 106310696SDavid.Hollister@Sun.COM display_outbound_queues(struct pmcs_hw ss, uint_t verbose) 106410696SDavid.Hollister@Sun.COM { 106510696SDavid.Hollister@Sun.COM int idx, qidx; 106610696SDavid.Hollister@Sun.COM uintptr_t obqp; 106710696SDavid.Hollister@Sun.COM uint32_t *cip; 106810696SDavid.Hollister@Sun.COM uint32_t *qentryp = mdb_alloc(PMCS_QENTRY_SIZE, UM_SLEEP); 106910696SDavid.Hollister@Sun.COM uint32_t last_consumed, oqpi; 107010696SDavid.Hollister@Sun.COM 107110696SDavid.Hollister@Sun.COM mdb_printf("\n"); 107210696SDavid.Hollister@Sun.COM mdb_printf("Outbound Queues\n"); 107310696SDavid.Hollister@Sun.COM mdb_printf("---------------\n"); 107410696SDavid.Hollister@Sun.COM 107510696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 107610696SDavid.Hollister@Sun.COM 107710696SDavid.Hollister@Sun.COM for (qidx = 0; qidx < PMCS_NOQ; qidx++) { 107810696SDavid.Hollister@Sun.COM obqp = (uintptr_t)ss.oqp[qidx]; 107910696SDavid.Hollister@Sun.COM 108010696SDavid.Hollister@Sun.COM if (obqp == NULL) { 108110696SDavid.Hollister@Sun.COM mdb_printf("No outbound queue ptr for queue #%d\n", 108210696SDavid.Hollister@Sun.COM qidx); 108310696SDavid.Hollister@Sun.COM continue; 108410696SDavid.Hollister@Sun.COM } 108510696SDavid.Hollister@Sun.COM 108610696SDavid.Hollister@Sun.COM mdb_printf("Outbound Queue #%d (Queue Type = %s)\n", qidx, 108710696SDavid.Hollister@Sun.COM obq_type(qidx)); 108810696SDavid.Hollister@Sun.COM /* 108910696SDavid.Hollister@Sun.COM * Chip is the producer, so read the actual producer index 109010696SDavid.Hollister@Sun.COM * and not the driver's version 109110696SDavid.Hollister@Sun.COM */ 109210696SDavid.Hollister@Sun.COM cip = (uint32_t *)((void *)ss.cip); 109310696SDavid.Hollister@Sun.COM if (MDB_RD(&oqpi, 4, cip + OQPI_BASE_OFFSET + 109410696SDavid.Hollister@Sun.COM (qidx * 4)) == -1) { 109510696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read oqpi\n"); 109610696SDavid.Hollister@Sun.COM break; 109710696SDavid.Hollister@Sun.COM } 109810696SDavid.Hollister@Sun.COM 109910696SDavid.Hollister@Sun.COM mdb_printf("Producer index: %d Consumer index: %d\n\n", 110010696SDavid.Hollister@Sun.COM LE_32(oqpi), ss.oqci[qidx]); 110110696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 110210696SDavid.Hollister@Sun.COM 110310696SDavid.Hollister@Sun.COM if (ss.oqci[qidx] == 0) { 110410696SDavid.Hollister@Sun.COM last_consumed = ss.ioq_depth - 1; 110510696SDavid.Hollister@Sun.COM } else { 110610696SDavid.Hollister@Sun.COM last_consumed = ss.oqci[qidx] - 1; 110710696SDavid.Hollister@Sun.COM } 110810696SDavid.Hollister@Sun.COM 110910696SDavid.Hollister@Sun.COM 111010696SDavid.Hollister@Sun.COM if (!verbose) { 111110696SDavid.Hollister@Sun.COM mdb_printf("Last processed entry:\n"); 111210696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 111310696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * last_consumed))) 111410696SDavid.Hollister@Sun.COM == -1) { 111510696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 111610696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * 111710696SDavid.Hollister@Sun.COM last_consumed))); 111810696SDavid.Hollister@Sun.COM break; 111910696SDavid.Hollister@Sun.COM } 112010696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(qentryp, last_consumed); 112110696SDavid.Hollister@Sun.COM mdb_printf("\n"); 112210696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 112310696SDavid.Hollister@Sun.COM continue; 112410696SDavid.Hollister@Sun.COM } 112510696SDavid.Hollister@Sun.COM 112610696SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.ioq_depth; idx++) { 112710696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 112810696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * idx))) == -1) { 112910696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 113010696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * idx))); 113110696SDavid.Hollister@Sun.COM break; 113210696SDavid.Hollister@Sun.COM } 113310696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(qentryp, idx); 113410696SDavid.Hollister@Sun.COM } 113510696SDavid.Hollister@Sun.COM 113610696SDavid.Hollister@Sun.COM mdb_printf("\n"); 113710696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 113810696SDavid.Hollister@Sun.COM } 113910696SDavid.Hollister@Sun.COM 114010696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 114110696SDavid.Hollister@Sun.COM mdb_free(qentryp, PMCS_QENTRY_SIZE); 114210696SDavid.Hollister@Sun.COM } 114310696SDavid.Hollister@Sun.COM 114410696SDavid.Hollister@Sun.COM static void 114510696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(uint32_t *qentryp, int idx) 114610696SDavid.Hollister@Sun.COM { 114710696SDavid.Hollister@Sun.COM int qeidx; 114810696SDavid.Hollister@Sun.COM uint32_t word0 = LE_32(*qentryp); 114910696SDavid.Hollister@Sun.COM 115010696SDavid.Hollister@Sun.COM mdb_printf("Entry #%02d\n", idx); 115110696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 115210696SDavid.Hollister@Sun.COM 115310696SDavid.Hollister@Sun.COM mdb_printf("Header: 0x%08x (", word0); 115410696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_VALID) { 115510696SDavid.Hollister@Sun.COM mdb_printf("VALID, "); 115610696SDavid.Hollister@Sun.COM } 115710696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_HIPRI) { 115810696SDavid.Hollister@Sun.COM mdb_printf("HIPRI, "); 115910696SDavid.Hollister@Sun.COM } 116010696SDavid.Hollister@Sun.COM mdb_printf("OBID=%d, ", 116110696SDavid.Hollister@Sun.COM (word0 & PMCS_IOMB_OBID_MASK) >> PMCS_IOMB_OBID_SHIFT); 116210696SDavid.Hollister@Sun.COM mdb_printf("CAT=%s, ", 116310696SDavid.Hollister@Sun.COM iomb_cat((word0 & PMCS_IOMB_CAT_MASK) >> PMCS_IOMB_CAT_SHIFT)); 116410696SDavid.Hollister@Sun.COM mdb_printf("OPCODE=%s", 116510696SDavid.Hollister@Sun.COM inbound_iomb_opcode(word0 & PMCS_IOMB_OPCODE_MASK)); 116610696SDavid.Hollister@Sun.COM mdb_printf(")\n"); 116710696SDavid.Hollister@Sun.COM 116810696SDavid.Hollister@Sun.COM mdb_printf("HTAG: 0x%08x\n", LE_32(*(qentryp + 1))); 116910696SDavid.Hollister@Sun.COM mdb_printf("Remaining Payload:\n"); 117010696SDavid.Hollister@Sun.COM 117110696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 117210696SDavid.Hollister@Sun.COM for (qeidx = 2; qeidx < (PMCS_QENTRY_SIZE / 4); qeidx++) { 117310696SDavid.Hollister@Sun.COM mdb_printf("%08x ", LE_32(*(qentryp + qeidx))); 117410696SDavid.Hollister@Sun.COM } 117510696SDavid.Hollister@Sun.COM mdb_printf("\n"); 117610696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 117710696SDavid.Hollister@Sun.COM } 117810696SDavid.Hollister@Sun.COM 117910696SDavid.Hollister@Sun.COM static void 118010696SDavid.Hollister@Sun.COM display_inbound_queues(struct pmcs_hw ss, uint_t verbose) 118110696SDavid.Hollister@Sun.COM { 118210696SDavid.Hollister@Sun.COM int idx, qidx, iqci, last_consumed; 118310696SDavid.Hollister@Sun.COM uintptr_t ibqp; 118410696SDavid.Hollister@Sun.COM uint32_t *qentryp = mdb_alloc(PMCS_QENTRY_SIZE, UM_SLEEP); 118510696SDavid.Hollister@Sun.COM uint32_t *cip; 118610696SDavid.Hollister@Sun.COM 118710696SDavid.Hollister@Sun.COM mdb_printf("\n"); 118810696SDavid.Hollister@Sun.COM mdb_printf("Inbound Queues\n"); 118910696SDavid.Hollister@Sun.COM mdb_printf("--------------\n"); 119010696SDavid.Hollister@Sun.COM 119110696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 119210696SDavid.Hollister@Sun.COM 119310696SDavid.Hollister@Sun.COM for (qidx = 0; qidx < PMCS_NIQ; qidx++) { 119410696SDavid.Hollister@Sun.COM ibqp = (uintptr_t)ss.iqp[qidx]; 119510696SDavid.Hollister@Sun.COM 119610696SDavid.Hollister@Sun.COM if (ibqp == NULL) { 119710696SDavid.Hollister@Sun.COM mdb_printf("No inbound queue ptr for queue #%d\n", 119810696SDavid.Hollister@Sun.COM qidx); 119910696SDavid.Hollister@Sun.COM continue; 120010696SDavid.Hollister@Sun.COM } 120110696SDavid.Hollister@Sun.COM 120210696SDavid.Hollister@Sun.COM mdb_printf("Inbound Queue #%d (Queue Type = %s)\n", qidx, 120310696SDavid.Hollister@Sun.COM ibq_type(qidx)); 120410696SDavid.Hollister@Sun.COM 120510696SDavid.Hollister@Sun.COM cip = (uint32_t *)((void *)ss.cip); 120610696SDavid.Hollister@Sun.COM if (MDB_RD(&iqci, 4, cip + (qidx * 4)) == -1) { 120710696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read iqci\n"); 120810696SDavid.Hollister@Sun.COM break; 120910696SDavid.Hollister@Sun.COM } 121010696SDavid.Hollister@Sun.COM iqci = LE_32(iqci); 121110696SDavid.Hollister@Sun.COM 121210696SDavid.Hollister@Sun.COM mdb_printf("Producer index: %d Consumer index: %d\n\n", 121310696SDavid.Hollister@Sun.COM ss.shadow_iqpi[qidx], iqci); 121410696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 121510696SDavid.Hollister@Sun.COM 121610696SDavid.Hollister@Sun.COM if (iqci == 0) { 121710696SDavid.Hollister@Sun.COM last_consumed = ss.ioq_depth - 1; 121810696SDavid.Hollister@Sun.COM } else { 121910696SDavid.Hollister@Sun.COM last_consumed = iqci - 1; 122010696SDavid.Hollister@Sun.COM } 122110696SDavid.Hollister@Sun.COM 122210696SDavid.Hollister@Sun.COM if (!verbose) { 122310696SDavid.Hollister@Sun.COM mdb_printf("Last processed entry:\n"); 122410696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 122510696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * last_consumed))) 122610696SDavid.Hollister@Sun.COM == -1) { 122710696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 122810696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * 122910696SDavid.Hollister@Sun.COM last_consumed))); 123010696SDavid.Hollister@Sun.COM break; 123110696SDavid.Hollister@Sun.COM } 123210696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(qentryp, last_consumed); 123310696SDavid.Hollister@Sun.COM mdb_printf("\n"); 123410696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 123510696SDavid.Hollister@Sun.COM continue; 123610696SDavid.Hollister@Sun.COM } 123710696SDavid.Hollister@Sun.COM 123810696SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.ioq_depth; idx++) { 123910696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 124010696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * idx))) == -1) { 124110696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 124210696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * idx))); 124310696SDavid.Hollister@Sun.COM break; 124410696SDavid.Hollister@Sun.COM } 124510696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(qentryp, idx); 124610696SDavid.Hollister@Sun.COM } 124710696SDavid.Hollister@Sun.COM 124810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 124910696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 125010696SDavid.Hollister@Sun.COM } 125110696SDavid.Hollister@Sun.COM 125210696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 125310696SDavid.Hollister@Sun.COM mdb_free(qentryp, PMCS_QENTRY_SIZE); 125410696SDavid.Hollister@Sun.COM } 125510696SDavid.Hollister@Sun.COM 125610696SDavid.Hollister@Sun.COM static void 125710696SDavid.Hollister@Sun.COM display_phy(struct pmcs_phy phy, int verbose, int totals_only) 125810696SDavid.Hollister@Sun.COM { 125910696SDavid.Hollister@Sun.COM char *dtype, *speed; 126010696SDavid.Hollister@Sun.COM char *yes = "Yes"; 126110696SDavid.Hollister@Sun.COM char *no = "No"; 126210696SDavid.Hollister@Sun.COM char *cfgd = no; 126310696SDavid.Hollister@Sun.COM char *apend = no; 126410696SDavid.Hollister@Sun.COM char *asent = no; 126510696SDavid.Hollister@Sun.COM char *dead = no; 126610696SDavid.Hollister@Sun.COM char *changed = no; 126710696SDavid.Hollister@Sun.COM 126810696SDavid.Hollister@Sun.COM switch (phy.dtype) { 126910696SDavid.Hollister@Sun.COM case NOTHING: 127010696SDavid.Hollister@Sun.COM dtype = "None"; 127110696SDavid.Hollister@Sun.COM break; 127210696SDavid.Hollister@Sun.COM case SATA: 127310696SDavid.Hollister@Sun.COM dtype = "SATA"; 127410696SDavid.Hollister@Sun.COM if (phy.configured) { 127510696SDavid.Hollister@Sun.COM ++sata_phys; 127610696SDavid.Hollister@Sun.COM } 127710696SDavid.Hollister@Sun.COM break; 127810696SDavid.Hollister@Sun.COM case SAS: 127910696SDavid.Hollister@Sun.COM dtype = "SAS"; 128010696SDavid.Hollister@Sun.COM if (phy.configured) { 128110696SDavid.Hollister@Sun.COM ++sas_phys; 128210696SDavid.Hollister@Sun.COM } 128310696SDavid.Hollister@Sun.COM break; 128410696SDavid.Hollister@Sun.COM case EXPANDER: 128510696SDavid.Hollister@Sun.COM dtype = "EXP"; 128610696SDavid.Hollister@Sun.COM if (phy.configured) { 128710696SDavid.Hollister@Sun.COM ++exp_phys; 128810696SDavid.Hollister@Sun.COM } 128910696SDavid.Hollister@Sun.COM break; 129010696SDavid.Hollister@Sun.COM } 129110696SDavid.Hollister@Sun.COM 129210696SDavid.Hollister@Sun.COM if (phy.dtype == NOTHING) { 129310696SDavid.Hollister@Sun.COM empty_phys++; 129410696SDavid.Hollister@Sun.COM } else if ((phy.dtype == EXPANDER) && phy.configured) { 129510696SDavid.Hollister@Sun.COM num_expanders++; 129610696SDavid.Hollister@Sun.COM } 129710696SDavid.Hollister@Sun.COM 129810696SDavid.Hollister@Sun.COM if (totals_only) { 129910696SDavid.Hollister@Sun.COM return; 130010696SDavid.Hollister@Sun.COM } 130110696SDavid.Hollister@Sun.COM 130210696SDavid.Hollister@Sun.COM switch (phy.link_rate) { 130310696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_1_5GBIT: 130410696SDavid.Hollister@Sun.COM speed = "1.5Gb/s"; 130510696SDavid.Hollister@Sun.COM break; 130610696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_3GBIT: 130710696SDavid.Hollister@Sun.COM speed = "3 Gb/s"; 130810696SDavid.Hollister@Sun.COM break; 130910696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_6GBIT: 131010696SDavid.Hollister@Sun.COM speed = "6 Gb/s"; 131110696SDavid.Hollister@Sun.COM break; 131210696SDavid.Hollister@Sun.COM default: 131310696SDavid.Hollister@Sun.COM speed = "N/A"; 131410696SDavid.Hollister@Sun.COM break; 131510696SDavid.Hollister@Sun.COM } 131610696SDavid.Hollister@Sun.COM 131710696SDavid.Hollister@Sun.COM if ((phy.dtype != NOTHING) || verbose) { 131810696SDavid.Hollister@Sun.COM print_sas_address(&phy); 131910696SDavid.Hollister@Sun.COM 132010696SDavid.Hollister@Sun.COM if (phy.device_id != PMCS_INVALID_DEVICE_ID) { 132110696SDavid.Hollister@Sun.COM mdb_printf(" %3d %4d %6s %4s ", 132210696SDavid.Hollister@Sun.COM phy.device_id, phy.phynum, speed, dtype); 132310696SDavid.Hollister@Sun.COM } else { 132410696SDavid.Hollister@Sun.COM mdb_printf(" N/A %4d %6s %4s ", 132510696SDavid.Hollister@Sun.COM phy.phynum, speed, dtype); 132610696SDavid.Hollister@Sun.COM } 132710696SDavid.Hollister@Sun.COM 132810696SDavid.Hollister@Sun.COM if (verbose) { 132910696SDavid.Hollister@Sun.COM if (phy.abort_sent) { 133010696SDavid.Hollister@Sun.COM asent = yes; 133110696SDavid.Hollister@Sun.COM } 133210696SDavid.Hollister@Sun.COM if (phy.abort_pending) { 133310696SDavid.Hollister@Sun.COM apend = yes; 133410696SDavid.Hollister@Sun.COM } 133510696SDavid.Hollister@Sun.COM if (phy.configured) { 133610696SDavid.Hollister@Sun.COM cfgd = yes; 133710696SDavid.Hollister@Sun.COM } 133810696SDavid.Hollister@Sun.COM if (phy.dead) { 133910696SDavid.Hollister@Sun.COM dead = yes; 134010696SDavid.Hollister@Sun.COM } 134110696SDavid.Hollister@Sun.COM if (phy.changed) { 134210696SDavid.Hollister@Sun.COM changed = yes; 134310696SDavid.Hollister@Sun.COM } 134410696SDavid.Hollister@Sun.COM 134510696SDavid.Hollister@Sun.COM mdb_printf("%-4s %-4s %-4s %-4s %-4s %3d " 134610696SDavid.Hollister@Sun.COM "0x%p ", cfgd, apend, asent, 134710696SDavid.Hollister@Sun.COM changed, dead, phy.ref_count, phy.phy_lock); 134810696SDavid.Hollister@Sun.COM } 134910696SDavid.Hollister@Sun.COM 135010696SDavid.Hollister@Sun.COM mdb_printf("Path: %s\n", phy.path); 135110696SDavid.Hollister@Sun.COM } 135210696SDavid.Hollister@Sun.COM } 135310696SDavid.Hollister@Sun.COM 135410696SDavid.Hollister@Sun.COM static void 135510696SDavid.Hollister@Sun.COM display_phys(struct pmcs_hw ss, int verbose, struct pmcs_phy *parent, int level, 135610696SDavid.Hollister@Sun.COM int totals_only) 135710696SDavid.Hollister@Sun.COM { 135810696SDavid.Hollister@Sun.COM pmcs_phy_t phy; 135910696SDavid.Hollister@Sun.COM pmcs_phy_t *pphy = parent; 136010696SDavid.Hollister@Sun.COM 136110696SDavid.Hollister@Sun.COM mdb_inc_indent(3); 136210696SDavid.Hollister@Sun.COM 136310696SDavid.Hollister@Sun.COM if (parent == NULL) { 136410696SDavid.Hollister@Sun.COM pphy = (pmcs_phy_t *)ss.root_phys; 136510696SDavid.Hollister@Sun.COM } else { 136610696SDavid.Hollister@Sun.COM pphy = (pmcs_phy_t *)parent; 136710696SDavid.Hollister@Sun.COM } 136810696SDavid.Hollister@Sun.COM 136910696SDavid.Hollister@Sun.COM if (level == 0) { 137010696SDavid.Hollister@Sun.COM sas_phys = 0; 137110696SDavid.Hollister@Sun.COM sata_phys = 0; 137210696SDavid.Hollister@Sun.COM exp_phys = 0; 137310696SDavid.Hollister@Sun.COM num_expanders = 0; 137410696SDavid.Hollister@Sun.COM empty_phys = 0; 137510696SDavid.Hollister@Sun.COM } 137610696SDavid.Hollister@Sun.COM 137710696SDavid.Hollister@Sun.COM if (!totals_only) { 137810696SDavid.Hollister@Sun.COM if (level == 0) { 137910696SDavid.Hollister@Sun.COM mdb_printf("PHY information\n"); 138010696SDavid.Hollister@Sun.COM } 138110696SDavid.Hollister@Sun.COM mdb_printf("--------\n"); 138210696SDavid.Hollister@Sun.COM mdb_printf("Level %2d\n", level); 138310696SDavid.Hollister@Sun.COM mdb_printf("--------\n"); 138410696SDavid.Hollister@Sun.COM mdb_printf("SAS Address Hdl Phy# Speed Type "); 138510696SDavid.Hollister@Sun.COM 138610696SDavid.Hollister@Sun.COM if (verbose) { 138710696SDavid.Hollister@Sun.COM mdb_printf("Cfgd AbtP AbtS Chgd Dead Ref Lock\n"); 138810696SDavid.Hollister@Sun.COM } else { 138910696SDavid.Hollister@Sun.COM mdb_printf("\n"); 139010696SDavid.Hollister@Sun.COM } 139110696SDavid.Hollister@Sun.COM } 139210696SDavid.Hollister@Sun.COM 139310696SDavid.Hollister@Sun.COM while (pphy) { 139410696SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), (uintptr_t)pphy) == -1) { 139510696SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, phy); 139610696SDavid.Hollister@Sun.COM break; 139710696SDavid.Hollister@Sun.COM } 139810696SDavid.Hollister@Sun.COM 139910696SDavid.Hollister@Sun.COM display_phy(phy, verbose, totals_only); 140010696SDavid.Hollister@Sun.COM 140110696SDavid.Hollister@Sun.COM if (phy.children) { 140210696SDavid.Hollister@Sun.COM display_phys(ss, verbose, phy.children, level + 1, 140310696SDavid.Hollister@Sun.COM totals_only); 140410696SDavid.Hollister@Sun.COM if (!totals_only) { 140510696SDavid.Hollister@Sun.COM mdb_printf("\n"); 140610696SDavid.Hollister@Sun.COM } 140710696SDavid.Hollister@Sun.COM } 140810696SDavid.Hollister@Sun.COM 140910696SDavid.Hollister@Sun.COM pphy = phy.sibling; 141010696SDavid.Hollister@Sun.COM } 141110696SDavid.Hollister@Sun.COM 141210696SDavid.Hollister@Sun.COM mdb_dec_indent(3); 141310696SDavid.Hollister@Sun.COM 141410696SDavid.Hollister@Sun.COM if (level == 0) { 141510696SDavid.Hollister@Sun.COM if (verbose) { 141610696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP) " 141710696SDavid.Hollister@Sun.COM "(+%d subsidiary + %d empty)\n", "Occupied PHYs:", 141810696SDavid.Hollister@Sun.COM (sas_phys + sata_phys + num_expanders), 141910696SDavid.Hollister@Sun.COM sas_phys, sata_phys, num_expanders, 142010696SDavid.Hollister@Sun.COM (exp_phys - num_expanders), empty_phys); 142110696SDavid.Hollister@Sun.COM } else { 142210696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP)\n", 142310696SDavid.Hollister@Sun.COM "Occupied PHYs:", 142410696SDavid.Hollister@Sun.COM (sas_phys + sata_phys + num_expanders), 142510696SDavid.Hollister@Sun.COM sas_phys, sata_phys, num_expanders); 142610696SDavid.Hollister@Sun.COM } 142710696SDavid.Hollister@Sun.COM } 142810696SDavid.Hollister@Sun.COM } 142910696SDavid.Hollister@Sun.COM 143010696SDavid.Hollister@Sun.COM /* 143110696SDavid.Hollister@Sun.COM * MAX_INST_STRLEN is the largest string size from which we will attempt 143210696SDavid.Hollister@Sun.COM * to convert to an instance number. The string will be formed up as 143310696SDavid.Hollister@Sun.COM * "0t<inst>\0" so that mdb_strtoull can parse it properly. 143410696SDavid.Hollister@Sun.COM */ 143510696SDavid.Hollister@Sun.COM #define MAX_INST_STRLEN 8 143610696SDavid.Hollister@Sun.COM 143710696SDavid.Hollister@Sun.COM static int 143810696SDavid.Hollister@Sun.COM pmcs_dump_tracelog(boolean_t filter, int instance) 143910696SDavid.Hollister@Sun.COM { 144010696SDavid.Hollister@Sun.COM pmcs_tbuf_t *tbuf_addr; 144110696SDavid.Hollister@Sun.COM uint_t tbuf_idx; 144210696SDavid.Hollister@Sun.COM pmcs_tbuf_t tbuf; 144310696SDavid.Hollister@Sun.COM boolean_t wrap, elem_filtered; 144410696SDavid.Hollister@Sun.COM uint_t start_idx, elems_to_print, idx, tbuf_num_elems; 144510696SDavid.Hollister@Sun.COM char *bufp; 144610696SDavid.Hollister@Sun.COM char elem_inst[MAX_INST_STRLEN], ei_idx; 144710696SDavid.Hollister@Sun.COM 144810696SDavid.Hollister@Sun.COM /* Get the address of the first element */ 144910696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_addr, "pmcs_tbuf") == -1) { 145010696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf"); 145110696SDavid.Hollister@Sun.COM return (DCMD_ERR); 145210696SDavid.Hollister@Sun.COM } 145310696SDavid.Hollister@Sun.COM 145410696SDavid.Hollister@Sun.COM /* Get the total number */ 145510696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_num_elems, "pmcs_tbuf_num_elems") == -1) { 145610696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_num_elems"); 145710696SDavid.Hollister@Sun.COM return (DCMD_ERR); 145810696SDavid.Hollister@Sun.COM } 145910696SDavid.Hollister@Sun.COM 146010696SDavid.Hollister@Sun.COM /* Get the current index */ 146110696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_idx, "pmcs_tbuf_idx") == -1) { 146210696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_idx"); 146310696SDavid.Hollister@Sun.COM return (DCMD_ERR); 146410696SDavid.Hollister@Sun.COM } 146510696SDavid.Hollister@Sun.COM 146610696SDavid.Hollister@Sun.COM /* Indicator as to whether the buffer has wrapped */ 146710696SDavid.Hollister@Sun.COM if (mdb_readvar(&wrap, "pmcs_tbuf_wrap") == -1) { 146810696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_wrap"); 146910696SDavid.Hollister@Sun.COM return (DCMD_ERR); 147010696SDavid.Hollister@Sun.COM } 147110696SDavid.Hollister@Sun.COM 147210696SDavid.Hollister@Sun.COM /* Figure out where we start and stop */ 147310696SDavid.Hollister@Sun.COM if (wrap) { 147410696SDavid.Hollister@Sun.COM start_idx = tbuf_idx; 147510696SDavid.Hollister@Sun.COM elems_to_print = tbuf_num_elems; 147610696SDavid.Hollister@Sun.COM } else { 147710696SDavid.Hollister@Sun.COM start_idx = 0; 147810696SDavid.Hollister@Sun.COM elems_to_print = tbuf_idx; 147910696SDavid.Hollister@Sun.COM } 148010696SDavid.Hollister@Sun.COM 148110696SDavid.Hollister@Sun.COM idx = start_idx; 148210696SDavid.Hollister@Sun.COM 148310696SDavid.Hollister@Sun.COM /* Dump the buffer contents */ 148410696SDavid.Hollister@Sun.COM while (elems_to_print != 0) { 148510696SDavid.Hollister@Sun.COM if (MDB_RD(&tbuf, sizeof (pmcs_tbuf_t), (tbuf_addr + idx)) 148610696SDavid.Hollister@Sun.COM == -1) { 148710696SDavid.Hollister@Sun.COM NOREAD(tbuf, (tbuf_addr + idx)); 148810696SDavid.Hollister@Sun.COM return (DCMD_ERR); 148910696SDavid.Hollister@Sun.COM } 149010696SDavid.Hollister@Sun.COM 149110696SDavid.Hollister@Sun.COM elem_filtered = B_FALSE; 149210696SDavid.Hollister@Sun.COM 149310696SDavid.Hollister@Sun.COM if (filter) { 149410696SDavid.Hollister@Sun.COM bufp = tbuf.buf; 149510696SDavid.Hollister@Sun.COM /* Skip the driver name */ 149610696SDavid.Hollister@Sun.COM while (*bufp < '0' || *bufp > '9') { 149710696SDavid.Hollister@Sun.COM bufp++; 149810696SDavid.Hollister@Sun.COM } 149910696SDavid.Hollister@Sun.COM 150010696SDavid.Hollister@Sun.COM ei_idx = 0; 150110696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = '0'; 150210696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = 't'; 150310696SDavid.Hollister@Sun.COM while (*bufp != ':' && ei_idx < (MAX_INST_STRLEN - 1)) { 150410696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = *bufp; 150510696SDavid.Hollister@Sun.COM bufp++; 150610696SDavid.Hollister@Sun.COM } 150710696SDavid.Hollister@Sun.COM elem_inst[ei_idx] = 0; 150810696SDavid.Hollister@Sun.COM 150910696SDavid.Hollister@Sun.COM /* Get the instance */ 151010696SDavid.Hollister@Sun.COM if ((int)mdb_strtoull(elem_inst) != instance) { 151110696SDavid.Hollister@Sun.COM elem_filtered = B_TRUE; 151210696SDavid.Hollister@Sun.COM } 151310696SDavid.Hollister@Sun.COM } 151410696SDavid.Hollister@Sun.COM 151510696SDavid.Hollister@Sun.COM if (!elem_filtered) { 151610696SDavid.Hollister@Sun.COM mdb_printf("%Y.%09ld %s\n", tbuf.timestamp, tbuf.buf); 151710696SDavid.Hollister@Sun.COM } 151810696SDavid.Hollister@Sun.COM 151910696SDavid.Hollister@Sun.COM --elems_to_print; 152010696SDavid.Hollister@Sun.COM if (++idx == tbuf_num_elems) { 152110696SDavid.Hollister@Sun.COM idx = 0; 152210696SDavid.Hollister@Sun.COM } 152310696SDavid.Hollister@Sun.COM } 152410696SDavid.Hollister@Sun.COM 152510696SDavid.Hollister@Sun.COM return (DCMD_OK); 152610696SDavid.Hollister@Sun.COM } 152710696SDavid.Hollister@Sun.COM 152810696SDavid.Hollister@Sun.COM /* 152910696SDavid.Hollister@Sun.COM * Walkers 153010696SDavid.Hollister@Sun.COM */ 153110696SDavid.Hollister@Sun.COM static int 153210696SDavid.Hollister@Sun.COM targets_walk_i(mdb_walk_state_t *wsp) 153310696SDavid.Hollister@Sun.COM { 153410696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 153510696SDavid.Hollister@Sun.COM mdb_warn("Can not perform global walk\n"); 153610696SDavid.Hollister@Sun.COM return (WALK_ERR); 153710696SDavid.Hollister@Sun.COM } 153810696SDavid.Hollister@Sun.COM 153910696SDavid.Hollister@Sun.COM /* 154010696SDavid.Hollister@Sun.COM * Address provided belongs to HBA softstate. Get the targets pointer 154110696SDavid.Hollister@Sun.COM * to begin the walk. 154210696SDavid.Hollister@Sun.COM */ 154310696SDavid.Hollister@Sun.COM if (mdb_vread(&ss, sizeof (pmcs_hw_t), wsp->walk_addr) != 154410696SDavid.Hollister@Sun.COM sizeof (pmcs_hw_t)) { 154510696SDavid.Hollister@Sun.COM mdb_warn("Unable to read HBA softstate\n"); 154610696SDavid.Hollister@Sun.COM return (WALK_ERR); 154710696SDavid.Hollister@Sun.COM } 154810696SDavid.Hollister@Sun.COM 154910696SDavid.Hollister@Sun.COM if (targets == NULL) { 155010696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * ss.max_dev, UM_SLEEP); 155110696SDavid.Hollister@Sun.COM } 155210696SDavid.Hollister@Sun.COM 155310696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * ss.max_dev, ss.targets) == -1) { 155410696SDavid.Hollister@Sun.COM NOREAD(targets, ss.targets); 155510696SDavid.Hollister@Sun.COM return (WALK_ERR); 155610696SDavid.Hollister@Sun.COM } 155710696SDavid.Hollister@Sun.COM 155810696SDavid.Hollister@Sun.COM target_idx = 0; 155910696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(targets[0]); 156010696SDavid.Hollister@Sun.COM wsp->walk_data = mdb_alloc(sizeof (pmcs_xscsi_t), UM_SLEEP); 156110696SDavid.Hollister@Sun.COM 156210696SDavid.Hollister@Sun.COM return (WALK_NEXT); 156310696SDavid.Hollister@Sun.COM } 156410696SDavid.Hollister@Sun.COM 156510696SDavid.Hollister@Sun.COM static int 156610696SDavid.Hollister@Sun.COM targets_walk_s(mdb_walk_state_t *wsp) 156710696SDavid.Hollister@Sun.COM { 156810696SDavid.Hollister@Sun.COM int status; 156910696SDavid.Hollister@Sun.COM 157010696SDavid.Hollister@Sun.COM if (target_idx == ss.max_dev) { 157110696SDavid.Hollister@Sun.COM return (WALK_DONE); 157210696SDavid.Hollister@Sun.COM } 157310696SDavid.Hollister@Sun.COM 157410696SDavid.Hollister@Sun.COM if (mdb_vread(wsp->walk_data, sizeof (pmcs_xscsi_t), 157510696SDavid.Hollister@Sun.COM wsp->walk_addr) == -1) { 157610696SDavid.Hollister@Sun.COM mdb_warn("Failed to read target at %p", (void *)wsp->walk_addr); 157710696SDavid.Hollister@Sun.COM return (WALK_DONE); 157810696SDavid.Hollister@Sun.COM } 157910696SDavid.Hollister@Sun.COM 158010696SDavid.Hollister@Sun.COM status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 158110696SDavid.Hollister@Sun.COM wsp->walk_cbdata); 158210696SDavid.Hollister@Sun.COM 158310696SDavid.Hollister@Sun.COM do { 158410696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(targets[++target_idx]); 158510696SDavid.Hollister@Sun.COM } while ((wsp->walk_addr == NULL) && (target_idx < ss.max_dev)); 158610696SDavid.Hollister@Sun.COM 158710696SDavid.Hollister@Sun.COM if (target_idx == ss.max_dev) { 158810696SDavid.Hollister@Sun.COM return (WALK_DONE); 158910696SDavid.Hollister@Sun.COM } 159010696SDavid.Hollister@Sun.COM 159110696SDavid.Hollister@Sun.COM return (status); 159210696SDavid.Hollister@Sun.COM } 159310696SDavid.Hollister@Sun.COM 159410696SDavid.Hollister@Sun.COM static void 159510696SDavid.Hollister@Sun.COM targets_walk_f(mdb_walk_state_t *wsp) 159610696SDavid.Hollister@Sun.COM { 159710696SDavid.Hollister@Sun.COM mdb_free(wsp->walk_data, sizeof (pmcs_xscsi_t)); 159810696SDavid.Hollister@Sun.COM } 159910696SDavid.Hollister@Sun.COM 160010696SDavid.Hollister@Sun.COM 160110696SDavid.Hollister@Sun.COM static pmcs_phy_t * 160210696SDavid.Hollister@Sun.COM pmcs_next_sibling(pmcs_phy_t *phyp) 160310696SDavid.Hollister@Sun.COM { 160410696SDavid.Hollister@Sun.COM pmcs_phy_t parent; 160510696SDavid.Hollister@Sun.COM 160610696SDavid.Hollister@Sun.COM /* 160710696SDavid.Hollister@Sun.COM * First, if this is a root PHY, there are no more siblings 160810696SDavid.Hollister@Sun.COM */ 160910696SDavid.Hollister@Sun.COM if (phyp->level == 0) { 161010696SDavid.Hollister@Sun.COM return (NULL); 161110696SDavid.Hollister@Sun.COM } 161210696SDavid.Hollister@Sun.COM 161310696SDavid.Hollister@Sun.COM /* 161410696SDavid.Hollister@Sun.COM * Otherwise, next sibling is the parent's sibling 161510696SDavid.Hollister@Sun.COM */ 161610696SDavid.Hollister@Sun.COM while (phyp->level > 0) { 161710696SDavid.Hollister@Sun.COM if (mdb_vread(&parent, sizeof (pmcs_phy_t), 161810696SDavid.Hollister@Sun.COM (uintptr_t)phyp->parent) == -1) { 161910696SDavid.Hollister@Sun.COM mdb_warn("pmcs_next_sibling: Failed to read PHY at %p", 162010696SDavid.Hollister@Sun.COM (void *)phyp->parent); 162110696SDavid.Hollister@Sun.COM return (NULL); 162210696SDavid.Hollister@Sun.COM } 162310696SDavid.Hollister@Sun.COM 162410696SDavid.Hollister@Sun.COM if (parent.sibling != NULL) { 162510696SDavid.Hollister@Sun.COM break; 162610696SDavid.Hollister@Sun.COM } 162710696SDavid.Hollister@Sun.COM 162810696SDavid.Hollister@Sun.COM phyp = phyp->parent; 162910696SDavid.Hollister@Sun.COM } 163010696SDavid.Hollister@Sun.COM 163110696SDavid.Hollister@Sun.COM return (parent.sibling); 163210696SDavid.Hollister@Sun.COM } 163310696SDavid.Hollister@Sun.COM 163410696SDavid.Hollister@Sun.COM static int 163510696SDavid.Hollister@Sun.COM phy_walk_i(mdb_walk_state_t *wsp) 163610696SDavid.Hollister@Sun.COM { 163710696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 163810696SDavid.Hollister@Sun.COM mdb_warn("Can not perform global walk\n"); 163910696SDavid.Hollister@Sun.COM return (WALK_ERR); 164010696SDavid.Hollister@Sun.COM } 164110696SDavid.Hollister@Sun.COM 164210696SDavid.Hollister@Sun.COM /* 164310696SDavid.Hollister@Sun.COM * Address provided belongs to HBA softstate. Get the targets pointer 164410696SDavid.Hollister@Sun.COM * to begin the walk. 164510696SDavid.Hollister@Sun.COM */ 164610696SDavid.Hollister@Sun.COM if (mdb_vread(&ss, sizeof (pmcs_hw_t), wsp->walk_addr) != 164710696SDavid.Hollister@Sun.COM sizeof (pmcs_hw_t)) { 164810696SDavid.Hollister@Sun.COM mdb_warn("Unable to read HBA softstate\n"); 164910696SDavid.Hollister@Sun.COM return (WALK_ERR); 165010696SDavid.Hollister@Sun.COM } 165110696SDavid.Hollister@Sun.COM 165210696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(ss.root_phys); 165310696SDavid.Hollister@Sun.COM wsp->walk_data = mdb_alloc(sizeof (pmcs_phy_t), UM_SLEEP); 165410696SDavid.Hollister@Sun.COM 165510696SDavid.Hollister@Sun.COM return (WALK_NEXT); 165610696SDavid.Hollister@Sun.COM } 165710696SDavid.Hollister@Sun.COM 165810696SDavid.Hollister@Sun.COM static int 165910696SDavid.Hollister@Sun.COM phy_walk_s(mdb_walk_state_t *wsp) 166010696SDavid.Hollister@Sun.COM { 166110696SDavid.Hollister@Sun.COM pmcs_phy_t *phyp, *nphyp; 166210696SDavid.Hollister@Sun.COM int status; 166310696SDavid.Hollister@Sun.COM 166410696SDavid.Hollister@Sun.COM if (mdb_vread(wsp->walk_data, sizeof (pmcs_phy_t), 166510696SDavid.Hollister@Sun.COM wsp->walk_addr) == -1) { 166610696SDavid.Hollister@Sun.COM mdb_warn("phy_walk_s: Failed to read PHY at %p", 166710696SDavid.Hollister@Sun.COM (void *)wsp->walk_addr); 166810696SDavid.Hollister@Sun.COM return (WALK_DONE); 166910696SDavid.Hollister@Sun.COM } 167010696SDavid.Hollister@Sun.COM 167110696SDavid.Hollister@Sun.COM status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 167210696SDavid.Hollister@Sun.COM wsp->walk_cbdata); 167310696SDavid.Hollister@Sun.COM 167410696SDavid.Hollister@Sun.COM phyp = (pmcs_phy_t *)wsp->walk_data; 167510696SDavid.Hollister@Sun.COM if (phyp->children) { 167610696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(phyp->children); 167710696SDavid.Hollister@Sun.COM } else { 167810696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(phyp->sibling); 167910696SDavid.Hollister@Sun.COM } 168010696SDavid.Hollister@Sun.COM 168110696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 168210696SDavid.Hollister@Sun.COM /* 168310696SDavid.Hollister@Sun.COM * We reached the end of this sibling list. Trudge back up 168410696SDavid.Hollister@Sun.COM * to the parent and find the next sibling after the expander 168510696SDavid.Hollister@Sun.COM * we just finished traversing, if there is one. 168610696SDavid.Hollister@Sun.COM */ 168710696SDavid.Hollister@Sun.COM nphyp = pmcs_next_sibling(phyp); 168810696SDavid.Hollister@Sun.COM 168910696SDavid.Hollister@Sun.COM if (nphyp == NULL) { 169010696SDavid.Hollister@Sun.COM return (WALK_DONE); 169110696SDavid.Hollister@Sun.COM } 169210696SDavid.Hollister@Sun.COM 169310696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)nphyp; 169410696SDavid.Hollister@Sun.COM } 169510696SDavid.Hollister@Sun.COM 169610696SDavid.Hollister@Sun.COM return (status); 169710696SDavid.Hollister@Sun.COM } 169810696SDavid.Hollister@Sun.COM 169910696SDavid.Hollister@Sun.COM static void 170010696SDavid.Hollister@Sun.COM phy_walk_f(mdb_walk_state_t *wsp) 170110696SDavid.Hollister@Sun.COM { 170210696SDavid.Hollister@Sun.COM mdb_free(wsp->walk_data, sizeof (pmcs_phy_t)); 170310696SDavid.Hollister@Sun.COM } 170410696SDavid.Hollister@Sun.COM 1705*10743SDavid.Hollister@Sun.COM static void 1706*10743SDavid.Hollister@Sun.COM display_matching_work(struct pmcs_hw ss, uintmax_t index, uintmax_t snum, 1707*10743SDavid.Hollister@Sun.COM uintmax_t tag_type) 1708*10743SDavid.Hollister@Sun.COM { 1709*10743SDavid.Hollister@Sun.COM int idx; 1710*10743SDavid.Hollister@Sun.COM pmcwork_t work, *wp = &work; 1711*10743SDavid.Hollister@Sun.COM uintptr_t _wp; 1712*10743SDavid.Hollister@Sun.COM boolean_t printed_header = B_FALSE; 1713*10743SDavid.Hollister@Sun.COM uint32_t mask, mask_val, match_val; 1714*10743SDavid.Hollister@Sun.COM char *match_type; 1715*10743SDavid.Hollister@Sun.COM 1716*10743SDavid.Hollister@Sun.COM if (index != UINT_MAX) { 1717*10743SDavid.Hollister@Sun.COM match_type = "index"; 1718*10743SDavid.Hollister@Sun.COM mask = PMCS_TAG_INDEX_MASK; 1719*10743SDavid.Hollister@Sun.COM mask_val = index << PMCS_TAG_INDEX_SHIFT; 1720*10743SDavid.Hollister@Sun.COM match_val = index; 1721*10743SDavid.Hollister@Sun.COM } else if (snum != UINT_MAX) { 1722*10743SDavid.Hollister@Sun.COM match_type = "serial number"; 1723*10743SDavid.Hollister@Sun.COM mask = PMCS_TAG_SERNO_MASK; 1724*10743SDavid.Hollister@Sun.COM mask_val = snum << PMCS_TAG_SERNO_SHIFT; 1725*10743SDavid.Hollister@Sun.COM match_val = snum; 1726*10743SDavid.Hollister@Sun.COM } else { 1727*10743SDavid.Hollister@Sun.COM switch (tag_type) { 1728*10743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_NONE: 1729*10743SDavid.Hollister@Sun.COM match_type = "tag type NONE"; 1730*10743SDavid.Hollister@Sun.COM break; 1731*10743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_CBACK: 1732*10743SDavid.Hollister@Sun.COM match_type = "tag type CBACK"; 1733*10743SDavid.Hollister@Sun.COM break; 1734*10743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_WAIT: 1735*10743SDavid.Hollister@Sun.COM match_type = "tag type WAIT"; 1736*10743SDavid.Hollister@Sun.COM break; 1737*10743SDavid.Hollister@Sun.COM } 1738*10743SDavid.Hollister@Sun.COM mask = PMCS_TAG_TYPE_MASK; 1739*10743SDavid.Hollister@Sun.COM mask_val = tag_type << PMCS_TAG_TYPE_SHIFT; 1740*10743SDavid.Hollister@Sun.COM match_val = tag_type; 1741*10743SDavid.Hollister@Sun.COM } 1742*10743SDavid.Hollister@Sun.COM 1743*10743SDavid.Hollister@Sun.COM _wp = (uintptr_t)ss.work; 1744*10743SDavid.Hollister@Sun.COM 1745*10743SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.max_cmd; idx++, _wp += sizeof (pmcwork_t)) { 1746*10743SDavid.Hollister@Sun.COM if (MDB_RD(&work, sizeof (pmcwork_t), _wp) == -1) { 1747*10743SDavid.Hollister@Sun.COM NOREAD(pmcwork_t, _wp); 1748*10743SDavid.Hollister@Sun.COM continue; 1749*10743SDavid.Hollister@Sun.COM } 1750*10743SDavid.Hollister@Sun.COM 1751*10743SDavid.Hollister@Sun.COM if ((work.htag & mask) != mask_val) { 1752*10743SDavid.Hollister@Sun.COM continue; 1753*10743SDavid.Hollister@Sun.COM } 1754*10743SDavid.Hollister@Sun.COM 1755*10743SDavid.Hollister@Sun.COM if (printed_header == B_FALSE) { 1756*10743SDavid.Hollister@Sun.COM if (tag_type) { 1757*10743SDavid.Hollister@Sun.COM mdb_printf("\nWork structures matching %s\n\n", 1758*10743SDavid.Hollister@Sun.COM match_type, match_val); 1759*10743SDavid.Hollister@Sun.COM } else { 1760*10743SDavid.Hollister@Sun.COM mdb_printf("\nWork structures matching %s of " 1761*10743SDavid.Hollister@Sun.COM "0x%x\n\n", match_type, match_val); 1762*10743SDavid.Hollister@Sun.COM } 1763*10743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D\n", 1764*10743SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 1765*10743SDavid.Hollister@Sun.COM printed_header = B_TRUE; 1766*10743SDavid.Hollister@Sun.COM } 1767*10743SDavid.Hollister@Sun.COM 1768*10743SDavid.Hollister@Sun.COM display_one_work(wp, 0, 0); 1769*10743SDavid.Hollister@Sun.COM } 1770*10743SDavid.Hollister@Sun.COM 1771*10743SDavid.Hollister@Sun.COM if (!printed_header) { 1772*10743SDavid.Hollister@Sun.COM mdb_printf("No work structure matches found\n"); 1773*10743SDavid.Hollister@Sun.COM } 1774*10743SDavid.Hollister@Sun.COM } 1775*10743SDavid.Hollister@Sun.COM 1776*10743SDavid.Hollister@Sun.COM static int 1777*10743SDavid.Hollister@Sun.COM pmcs_tag(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1778*10743SDavid.Hollister@Sun.COM { 1779*10743SDavid.Hollister@Sun.COM struct pmcs_hw ss; 1780*10743SDavid.Hollister@Sun.COM uintmax_t tag_type = UINT_MAX; 1781*10743SDavid.Hollister@Sun.COM uintmax_t snum = UINT_MAX; 1782*10743SDavid.Hollister@Sun.COM uintmax_t index = UINT_MAX; 1783*10743SDavid.Hollister@Sun.COM int args = 0; 1784*10743SDavid.Hollister@Sun.COM void *pmcs_state; 1785*10743SDavid.Hollister@Sun.COM char *state_str; 1786*10743SDavid.Hollister@Sun.COM struct dev_info dip; 1787*10743SDavid.Hollister@Sun.COM 1788*10743SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 1789*10743SDavid.Hollister@Sun.COM pmcs_state = NULL; 1790*10743SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 1791*10743SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 1792*10743SDavid.Hollister@Sun.COM return (DCMD_ERR); 1793*10743SDavid.Hollister@Sun.COM } 1794*10743SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_tag", argc, 1795*10743SDavid.Hollister@Sun.COM argv, (uintptr_t)pmcs_state) == -1) { 1796*10743SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed"); 1797*10743SDavid.Hollister@Sun.COM return (DCMD_ERR); 1798*10743SDavid.Hollister@Sun.COM } 1799*10743SDavid.Hollister@Sun.COM return (DCMD_OK); 1800*10743SDavid.Hollister@Sun.COM } 1801*10743SDavid.Hollister@Sun.COM 1802*10743SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 1803*10743SDavid.Hollister@Sun.COM 'i', MDB_OPT_UINT64, &index, 1804*10743SDavid.Hollister@Sun.COM 's', MDB_OPT_UINT64, &snum, 1805*10743SDavid.Hollister@Sun.COM 't', MDB_OPT_UINT64, &tag_type) != argc) 1806*10743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 1807*10743SDavid.Hollister@Sun.COM 1808*10743SDavid.Hollister@Sun.COM /* 1809*10743SDavid.Hollister@Sun.COM * Count the number of supplied options and make sure they are 1810*10743SDavid.Hollister@Sun.COM * within appropriate ranges. If they're set to UINT_MAX, that means 1811*10743SDavid.Hollister@Sun.COM * they were not supplied, in which case reset them to 0. 1812*10743SDavid.Hollister@Sun.COM */ 1813*10743SDavid.Hollister@Sun.COM if (index != UINT_MAX) { 1814*10743SDavid.Hollister@Sun.COM args++; 1815*10743SDavid.Hollister@Sun.COM if (index > PMCS_TAG_INDEX_MASK) { 1816*10743SDavid.Hollister@Sun.COM mdb_warn("Index is out of range\n"); 1817*10743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 1818*10743SDavid.Hollister@Sun.COM } 1819*10743SDavid.Hollister@Sun.COM } 1820*10743SDavid.Hollister@Sun.COM 1821*10743SDavid.Hollister@Sun.COM if (tag_type != UINT_MAX) { 1822*10743SDavid.Hollister@Sun.COM args++; 1823*10743SDavid.Hollister@Sun.COM switch (tag_type) { 1824*10743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_NONE: 1825*10743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_CBACK: 1826*10743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_WAIT: 1827*10743SDavid.Hollister@Sun.COM break; 1828*10743SDavid.Hollister@Sun.COM default: 1829*10743SDavid.Hollister@Sun.COM mdb_warn("Invalid tag type\n"); 1830*10743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 1831*10743SDavid.Hollister@Sun.COM } 1832*10743SDavid.Hollister@Sun.COM } 1833*10743SDavid.Hollister@Sun.COM 1834*10743SDavid.Hollister@Sun.COM if (snum != UINT_MAX) { 1835*10743SDavid.Hollister@Sun.COM args++; 1836*10743SDavid.Hollister@Sun.COM if (snum > (PMCS_TAG_SERNO_MASK >> PMCS_TAG_SERNO_SHIFT)) { 1837*10743SDavid.Hollister@Sun.COM mdb_warn("Serial number is out of range\n"); 1838*10743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 1839*10743SDavid.Hollister@Sun.COM } 1840*10743SDavid.Hollister@Sun.COM } 1841*10743SDavid.Hollister@Sun.COM 1842*10743SDavid.Hollister@Sun.COM /* 1843*10743SDavid.Hollister@Sun.COM * Make sure 1 and only 1 option is specified 1844*10743SDavid.Hollister@Sun.COM */ 1845*10743SDavid.Hollister@Sun.COM if ((args == 0) || (args > 1)) { 1846*10743SDavid.Hollister@Sun.COM mdb_warn("Exactly one of -i, -s and -t must be specified\n"); 1847*10743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 1848*10743SDavid.Hollister@Sun.COM } 1849*10743SDavid.Hollister@Sun.COM 1850*10743SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 1851*10743SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 1852*10743SDavid.Hollister@Sun.COM return (DCMD_ERR); 1853*10743SDavid.Hollister@Sun.COM } 1854*10743SDavid.Hollister@Sun.COM 1855*10743SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 1856*10743SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 1857*10743SDavid.Hollister@Sun.COM return (DCMD_ERR); 1858*10743SDavid.Hollister@Sun.COM } 1859*10743SDavid.Hollister@Sun.COM 1860*10743SDavid.Hollister@Sun.COM /* processing completed */ 1861*10743SDavid.Hollister@Sun.COM 1862*10743SDavid.Hollister@Sun.COM if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) || 1863*10743SDavid.Hollister@Sun.COM (flags & DCMD_LOOPFIRST)) { 1864*10743SDavid.Hollister@Sun.COM if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST)) 1865*10743SDavid.Hollister@Sun.COM mdb_printf("\n"); 1866*10743SDavid.Hollister@Sun.COM mdb_printf("%16s %9s %4s B C WorkFlags wserno DbgMsk %16s\n", 1867*10743SDavid.Hollister@Sun.COM "Address", "State", "Inst", "DIP"); 1868*10743SDavid.Hollister@Sun.COM mdb_printf("=================================" 1869*10743SDavid.Hollister@Sun.COM "============================================\n"); 1870*10743SDavid.Hollister@Sun.COM } 1871*10743SDavid.Hollister@Sun.COM 1872*10743SDavid.Hollister@Sun.COM switch (ss.state) { 1873*10743SDavid.Hollister@Sun.COM case STATE_NIL: 1874*10743SDavid.Hollister@Sun.COM state_str = "Invalid"; 1875*10743SDavid.Hollister@Sun.COM break; 1876*10743SDavid.Hollister@Sun.COM case STATE_PROBING: 1877*10743SDavid.Hollister@Sun.COM state_str = "Probing"; 1878*10743SDavid.Hollister@Sun.COM break; 1879*10743SDavid.Hollister@Sun.COM case STATE_RUNNING: 1880*10743SDavid.Hollister@Sun.COM state_str = "Running"; 1881*10743SDavid.Hollister@Sun.COM break; 1882*10743SDavid.Hollister@Sun.COM case STATE_UNPROBING: 1883*10743SDavid.Hollister@Sun.COM state_str = "Unprobing"; 1884*10743SDavid.Hollister@Sun.COM break; 1885*10743SDavid.Hollister@Sun.COM case STATE_DEAD: 1886*10743SDavid.Hollister@Sun.COM state_str = "Dead"; 1887*10743SDavid.Hollister@Sun.COM break; 1888*10743SDavid.Hollister@Sun.COM } 1889*10743SDavid.Hollister@Sun.COM 1890*10743SDavid.Hollister@Sun.COM mdb_printf("%16p %9s %4d %1d %1d 0x%08x 0x%04x 0x%04x %16p\n", addr, 1891*10743SDavid.Hollister@Sun.COM state_str, dip.devi_instance, ss.blocked, ss.configuring, 1892*10743SDavid.Hollister@Sun.COM ss.work_flags, ss.wserno, ss.debug_mask, ss.dip); 1893*10743SDavid.Hollister@Sun.COM mdb_printf("\n"); 1894*10743SDavid.Hollister@Sun.COM 1895*10743SDavid.Hollister@Sun.COM mdb_inc_indent(4); 1896*10743SDavid.Hollister@Sun.COM display_matching_work(ss, index, snum, tag_type); 1897*10743SDavid.Hollister@Sun.COM mdb_dec_indent(4); 1898*10743SDavid.Hollister@Sun.COM mdb_printf("\n"); 1899*10743SDavid.Hollister@Sun.COM 1900*10743SDavid.Hollister@Sun.COM return (DCMD_OK); 1901*10743SDavid.Hollister@Sun.COM } 1902*10743SDavid.Hollister@Sun.COM 190310696SDavid.Hollister@Sun.COM static int 190410696SDavid.Hollister@Sun.COM pmcs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 190510696SDavid.Hollister@Sun.COM { 190610696SDavid.Hollister@Sun.COM struct pmcs_hw ss; 190710696SDavid.Hollister@Sun.COM uint_t verbose = FALSE; 190810696SDavid.Hollister@Sun.COM uint_t phy_info = FALSE; 190910696SDavid.Hollister@Sun.COM uint_t hw_info = FALSE; 191010696SDavid.Hollister@Sun.COM uint_t target_info = FALSE; 191110696SDavid.Hollister@Sun.COM uint_t work_info = FALSE; 191210696SDavid.Hollister@Sun.COM uint_t ic_info = FALSE; 191310696SDavid.Hollister@Sun.COM uint_t iport_info = FALSE; 191410696SDavid.Hollister@Sun.COM uint_t waitqs_info = FALSE; 191510696SDavid.Hollister@Sun.COM uint_t tracelog = FALSE; 191610696SDavid.Hollister@Sun.COM uint_t ibq = FALSE; 191710696SDavid.Hollister@Sun.COM uint_t obq = FALSE; 191810696SDavid.Hollister@Sun.COM uint_t tgt_phy_count = FALSE; 1919*10743SDavid.Hollister@Sun.COM uint_t compq = FALSE; 192010696SDavid.Hollister@Sun.COM int rv = DCMD_OK; 192110696SDavid.Hollister@Sun.COM void *pmcs_state; 192210696SDavid.Hollister@Sun.COM char *state_str; 192310696SDavid.Hollister@Sun.COM struct dev_info dip; 192410696SDavid.Hollister@Sun.COM 192510696SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 192610696SDavid.Hollister@Sun.COM pmcs_state = NULL; 192710696SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 192810696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 192910696SDavid.Hollister@Sun.COM return (DCMD_ERR); 193010696SDavid.Hollister@Sun.COM } 193110696SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs", argc, argv, 193210696SDavid.Hollister@Sun.COM (uintptr_t)pmcs_state) == -1) { 193310696SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed"); 193410696SDavid.Hollister@Sun.COM return (DCMD_ERR); 193510696SDavid.Hollister@Sun.COM } 193610696SDavid.Hollister@Sun.COM return (DCMD_OK); 193710696SDavid.Hollister@Sun.COM } 193810696SDavid.Hollister@Sun.COM 193910696SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 1940*10743SDavid.Hollister@Sun.COM 'c', MDB_OPT_SETBITS, TRUE, &compq, 194110696SDavid.Hollister@Sun.COM 'h', MDB_OPT_SETBITS, TRUE, &hw_info, 194210696SDavid.Hollister@Sun.COM 'i', MDB_OPT_SETBITS, TRUE, &ic_info, 194310696SDavid.Hollister@Sun.COM 'I', MDB_OPT_SETBITS, TRUE, &iport_info, 194410696SDavid.Hollister@Sun.COM 'l', MDB_OPT_SETBITS, TRUE, &tracelog, 194510696SDavid.Hollister@Sun.COM 'p', MDB_OPT_SETBITS, TRUE, &phy_info, 194610696SDavid.Hollister@Sun.COM 'q', MDB_OPT_SETBITS, TRUE, &ibq, 194710696SDavid.Hollister@Sun.COM 'Q', MDB_OPT_SETBITS, TRUE, &obq, 194810696SDavid.Hollister@Sun.COM 't', MDB_OPT_SETBITS, TRUE, &target_info, 194910696SDavid.Hollister@Sun.COM 'T', MDB_OPT_SETBITS, TRUE, &tgt_phy_count, 195010696SDavid.Hollister@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose, 195110696SDavid.Hollister@Sun.COM 'w', MDB_OPT_SETBITS, TRUE, &work_info, 195210696SDavid.Hollister@Sun.COM 'W', MDB_OPT_SETBITS, TRUE, &waitqs_info, 195310696SDavid.Hollister@Sun.COM NULL) != argc) 195410696SDavid.Hollister@Sun.COM return (DCMD_USAGE); 195510696SDavid.Hollister@Sun.COM 195610696SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 195710696SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 195810696SDavid.Hollister@Sun.COM return (DCMD_ERR); 195910696SDavid.Hollister@Sun.COM } 196010696SDavid.Hollister@Sun.COM 196110696SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 196210696SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 196310696SDavid.Hollister@Sun.COM return (DCMD_ERR); 196410696SDavid.Hollister@Sun.COM } 196510696SDavid.Hollister@Sun.COM 196610696SDavid.Hollister@Sun.COM /* 196710696SDavid.Hollister@Sun.COM * Dumping the trace log is special. It's global, not per-HBA. 196810696SDavid.Hollister@Sun.COM * Thus, a provided address is ignored. In addition, other options 196910696SDavid.Hollister@Sun.COM * cannot be specified at the same time. 197010696SDavid.Hollister@Sun.COM */ 197110696SDavid.Hollister@Sun.COM if (tracelog) { 197210696SDavid.Hollister@Sun.COM if (hw_info || ic_info || iport_info || phy_info || work_info || 1973*10743SDavid.Hollister@Sun.COM target_info || waitqs_info || ibq || obq || tgt_phy_count || 1974*10743SDavid.Hollister@Sun.COM compq) { 197510696SDavid.Hollister@Sun.COM return (DCMD_USAGE); 197610696SDavid.Hollister@Sun.COM } 197710696SDavid.Hollister@Sun.COM 197810696SDavid.Hollister@Sun.COM if ((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) { 197910696SDavid.Hollister@Sun.COM return (pmcs_dump_tracelog(B_TRUE, dip.devi_instance)); 198010696SDavid.Hollister@Sun.COM } else if (flags & DCMD_LOOPFIRST) { 198110696SDavid.Hollister@Sun.COM return (pmcs_dump_tracelog(B_FALSE, 0)); 198210696SDavid.Hollister@Sun.COM } else { 198310696SDavid.Hollister@Sun.COM return (DCMD_OK); 198410696SDavid.Hollister@Sun.COM } 198510696SDavid.Hollister@Sun.COM } 198610696SDavid.Hollister@Sun.COM 198710696SDavid.Hollister@Sun.COM /* processing completed */ 198810696SDavid.Hollister@Sun.COM 198910696SDavid.Hollister@Sun.COM if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) || 199010696SDavid.Hollister@Sun.COM (flags & DCMD_LOOPFIRST) || phy_info || target_info || hw_info || 1991*10743SDavid.Hollister@Sun.COM work_info || waitqs_info || ibq || obq || tgt_phy_count || compq) { 199210696SDavid.Hollister@Sun.COM if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST)) 199310696SDavid.Hollister@Sun.COM mdb_printf("\n"); 199410696SDavid.Hollister@Sun.COM mdb_printf("%16s %9s %4s B C WorkFlags wserno DbgMsk %16s\n", 199510696SDavid.Hollister@Sun.COM "Address", "State", "Inst", "DIP"); 199610696SDavid.Hollister@Sun.COM mdb_printf("=================================" 199710696SDavid.Hollister@Sun.COM "============================================\n"); 199810696SDavid.Hollister@Sun.COM } 199910696SDavid.Hollister@Sun.COM 200010696SDavid.Hollister@Sun.COM switch (ss.state) { 200110696SDavid.Hollister@Sun.COM case STATE_NIL: 200210696SDavid.Hollister@Sun.COM state_str = "Invalid"; 200310696SDavid.Hollister@Sun.COM break; 200410696SDavid.Hollister@Sun.COM case STATE_PROBING: 200510696SDavid.Hollister@Sun.COM state_str = "Probing"; 200610696SDavid.Hollister@Sun.COM break; 200710696SDavid.Hollister@Sun.COM case STATE_RUNNING: 200810696SDavid.Hollister@Sun.COM state_str = "Running"; 200910696SDavid.Hollister@Sun.COM break; 201010696SDavid.Hollister@Sun.COM case STATE_UNPROBING: 201110696SDavid.Hollister@Sun.COM state_str = "Unprobing"; 201210696SDavid.Hollister@Sun.COM break; 201310696SDavid.Hollister@Sun.COM case STATE_DEAD: 201410696SDavid.Hollister@Sun.COM state_str = "Dead"; 201510696SDavid.Hollister@Sun.COM break; 201610696SDavid.Hollister@Sun.COM } 201710696SDavid.Hollister@Sun.COM 201810696SDavid.Hollister@Sun.COM mdb_printf("%16p %9s %4d %1d %1d 0x%08x 0x%04x 0x%04x %16p\n", addr, 201910696SDavid.Hollister@Sun.COM state_str, dip.devi_instance, ss.blocked, ss.configuring, 202010696SDavid.Hollister@Sun.COM ss.work_flags, ss.wserno, ss.debug_mask, ss.dip); 202110696SDavid.Hollister@Sun.COM mdb_printf("\n"); 202210696SDavid.Hollister@Sun.COM 202310696SDavid.Hollister@Sun.COM mdb_inc_indent(4); 202410696SDavid.Hollister@Sun.COM 202510696SDavid.Hollister@Sun.COM if (waitqs_info) 202610696SDavid.Hollister@Sun.COM display_waitqs(ss, verbose); 202710696SDavid.Hollister@Sun.COM 202810696SDavid.Hollister@Sun.COM if (hw_info) 202910696SDavid.Hollister@Sun.COM display_hwinfo(ss, verbose); 203010696SDavid.Hollister@Sun.COM 203110696SDavid.Hollister@Sun.COM if (phy_info || tgt_phy_count) 203210696SDavid.Hollister@Sun.COM display_phys(ss, verbose, NULL, 0, tgt_phy_count); 203310696SDavid.Hollister@Sun.COM 203410696SDavid.Hollister@Sun.COM if (target_info || tgt_phy_count) 203510696SDavid.Hollister@Sun.COM display_targets(ss, verbose, tgt_phy_count); 203610696SDavid.Hollister@Sun.COM 203710696SDavid.Hollister@Sun.COM if (work_info) 203810696SDavid.Hollister@Sun.COM display_work(ss, verbose); 203910696SDavid.Hollister@Sun.COM 204010696SDavid.Hollister@Sun.COM if (ic_info) 204110696SDavid.Hollister@Sun.COM display_ic(ss, verbose); 204210696SDavid.Hollister@Sun.COM 204310696SDavid.Hollister@Sun.COM if (ibq) 204410696SDavid.Hollister@Sun.COM display_inbound_queues(ss, verbose); 204510696SDavid.Hollister@Sun.COM 204610696SDavid.Hollister@Sun.COM if (obq) 204710696SDavid.Hollister@Sun.COM display_outbound_queues(ss, verbose); 204810696SDavid.Hollister@Sun.COM 204910696SDavid.Hollister@Sun.COM if (iport_info) 205010696SDavid.Hollister@Sun.COM display_iport(ss, addr, verbose); 205110696SDavid.Hollister@Sun.COM 2052*10743SDavid.Hollister@Sun.COM if (compq) 2053*10743SDavid.Hollister@Sun.COM display_completion_queue(ss); 2054*10743SDavid.Hollister@Sun.COM 205510696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 205610696SDavid.Hollister@Sun.COM 205710696SDavid.Hollister@Sun.COM return (rv); 205810696SDavid.Hollister@Sun.COM } 205910696SDavid.Hollister@Sun.COM 206010696SDavid.Hollister@Sun.COM void 206110696SDavid.Hollister@Sun.COM pmcs_help() 206210696SDavid.Hollister@Sun.COM { 206310696SDavid.Hollister@Sun.COM mdb_printf("Prints summary information about each pmcs instance.\n" 2064*10743SDavid.Hollister@Sun.COM " -c: Dump the completion queue\n" 206510696SDavid.Hollister@Sun.COM " -h: Print more detailed hardware information\n" 206610696SDavid.Hollister@Sun.COM " -i: Print interrupt coalescing information\n" 206710696SDavid.Hollister@Sun.COM " -I: Print information about each iport\n" 206810696SDavid.Hollister@Sun.COM " -l: Dump the trace log (cannot be used with other options)\n" 206910696SDavid.Hollister@Sun.COM " -p: Print information about each attached PHY\n" 207010696SDavid.Hollister@Sun.COM " -q: Dump inbound queues\n" 207110696SDavid.Hollister@Sun.COM " -Q: Dump outbound queues\n" 207210696SDavid.Hollister@Sun.COM " -t: Print information about each known target\n" 207310696SDavid.Hollister@Sun.COM " -T: Print target and PHY count summary\n" 207410696SDavid.Hollister@Sun.COM " -w: Dump work structures\n" 207510696SDavid.Hollister@Sun.COM " -W: List pmcs cmds waiting on various queues\n" 207610696SDavid.Hollister@Sun.COM " -v: Add verbosity to the above options\n"); 207710696SDavid.Hollister@Sun.COM } 207810696SDavid.Hollister@Sun.COM 2079*10743SDavid.Hollister@Sun.COM void 2080*10743SDavid.Hollister@Sun.COM pmcs_tag_help() 2081*10743SDavid.Hollister@Sun.COM { 2082*10743SDavid.Hollister@Sun.COM mdb_printf("Print all work structures by matching the tag.\n" 2083*10743SDavid.Hollister@Sun.COM " -i index: Match tag index (0x000 - 0xfff)\n" 2084*10743SDavid.Hollister@Sun.COM " -s serialnumber: Match serial number (0x0000 - 0xffff)\n" 2085*10743SDavid.Hollister@Sun.COM " -t tagtype: Match tag type [NONE(1), CBACK(2), " 2086*10743SDavid.Hollister@Sun.COM "WAIT(3)]\n"); 2087*10743SDavid.Hollister@Sun.COM } 2088*10743SDavid.Hollister@Sun.COM 208910696SDavid.Hollister@Sun.COM static const mdb_dcmd_t dcmds[] = { 2090*10743SDavid.Hollister@Sun.COM { "pmcs", "?[-chiIpQqtTwWv] | -l", "print pmcs information", 209110696SDavid.Hollister@Sun.COM pmcs_dcmd, pmcs_help 209210696SDavid.Hollister@Sun.COM }, 2093*10743SDavid.Hollister@Sun.COM { "pmcs_tag", "?[-t tagtype|-s serialnum|-i index]", 2094*10743SDavid.Hollister@Sun.COM "Find work structures by tag type, serial number or index", 2095*10743SDavid.Hollister@Sun.COM pmcs_tag, pmcs_tag_help 2096*10743SDavid.Hollister@Sun.COM }, 209710696SDavid.Hollister@Sun.COM { NULL } 209810696SDavid.Hollister@Sun.COM }; 209910696SDavid.Hollister@Sun.COM 210010696SDavid.Hollister@Sun.COM static const mdb_walker_t walkers[] = { 210110696SDavid.Hollister@Sun.COM { "pmcs_targets", "walk target structures", 210210696SDavid.Hollister@Sun.COM targets_walk_i, targets_walk_s, targets_walk_f }, 210310696SDavid.Hollister@Sun.COM { "pmcs_phys", "walk PHY structures", 210410696SDavid.Hollister@Sun.COM phy_walk_i, phy_walk_s, phy_walk_f }, 210510696SDavid.Hollister@Sun.COM { NULL } 210610696SDavid.Hollister@Sun.COM }; 210710696SDavid.Hollister@Sun.COM 210810696SDavid.Hollister@Sun.COM static const mdb_modinfo_t modinfo = { 210910696SDavid.Hollister@Sun.COM MDB_API_VERSION, dcmds, walkers 211010696SDavid.Hollister@Sun.COM }; 211110696SDavid.Hollister@Sun.COM 211210696SDavid.Hollister@Sun.COM const mdb_modinfo_t * 211310696SDavid.Hollister@Sun.COM _mdb_init(void) 211410696SDavid.Hollister@Sun.COM { 211510696SDavid.Hollister@Sun.COM return (&modinfo); 211610696SDavid.Hollister@Sun.COM } 2117