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 /* 2211601SDavid.Hollister@Sun.COM * Copyright 2010 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> 2811334SReed.Liu@Sun.COM #include <mdb/mdb_ctf.h> 2910696SDavid.Hollister@Sun.COM #include <sys/sysinfo.h> 3011048SDavid.Hollister@Sun.COM #include <sys/byteorder.h> 3111334SReed.Liu@Sun.COM #include <sys/nvpair.h> 3211334SReed.Liu@Sun.COM #include <sys/damap.h> 3310696SDavid.Hollister@Sun.COM #include <sys/scsi/scsi.h> 3410696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs.h> 3511694SDavid.Hollister@Sun.COM #ifndef _KMDB 3611694SDavid.Hollister@Sun.COM #include <sys/types.h> 3711694SDavid.Hollister@Sun.COM #include <sys/stat.h> 3811694SDavid.Hollister@Sun.COM #include <fcntl.h> 3911694SDavid.Hollister@Sun.COM #include <unistd.h> 4011694SDavid.Hollister@Sun.COM #endif /* _KMDB */ 4110696SDavid.Hollister@Sun.COM 4211334SReed.Liu@Sun.COM /* 4311334SReed.Liu@Sun.COM * We need use this to pass the settings when display_iport 4411334SReed.Liu@Sun.COM */ 4511334SReed.Liu@Sun.COM typedef struct per_iport_setting { 4611334SReed.Liu@Sun.COM uint_t pis_damap_info; /* -m: DAM/damap */ 4711334SReed.Liu@Sun.COM uint_t pis_dtc_info; /* -d: device tree children: dev_info/path_info */ 4811334SReed.Liu@Sun.COM } per_iport_setting_t; 4911334SReed.Liu@Sun.COM 5011334SReed.Liu@Sun.COM #define MDB_RD(a, b, c) mdb_vread(a, b, (uintptr_t)c) 5111334SReed.Liu@Sun.COM #define NOREAD(a, b) mdb_warn("could not read " #a " at 0x%p", b) 5210696SDavid.Hollister@Sun.COM 5310696SDavid.Hollister@Sun.COM static pmcs_hw_t ss; 5410696SDavid.Hollister@Sun.COM static pmcs_xscsi_t **targets = NULL; 5510696SDavid.Hollister@Sun.COM static int target_idx; 5610696SDavid.Hollister@Sun.COM 5710696SDavid.Hollister@Sun.COM static uint32_t sas_phys, sata_phys, exp_phys, num_expanders, empty_phys; 5810696SDavid.Hollister@Sun.COM 5910696SDavid.Hollister@Sun.COM static pmcs_phy_t *pmcs_next_sibling(pmcs_phy_t *phyp); 6010743SDavid.Hollister@Sun.COM static void display_one_work(pmcwork_t *wp, int verbose, int idx); 6110696SDavid.Hollister@Sun.COM 6210696SDavid.Hollister@Sun.COM static void 6310696SDavid.Hollister@Sun.COM print_sas_address(pmcs_phy_t *phy) 6410696SDavid.Hollister@Sun.COM { 6510696SDavid.Hollister@Sun.COM int idx; 6610696SDavid.Hollister@Sun.COM 6710696SDavid.Hollister@Sun.COM for (idx = 0; idx < 8; idx++) { 6810696SDavid.Hollister@Sun.COM mdb_printf("%02x", phy->sas_address[idx]); 6910696SDavid.Hollister@Sun.COM } 7010696SDavid.Hollister@Sun.COM } 7110696SDavid.Hollister@Sun.COM 7210696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 7310696SDavid.Hollister@Sun.COM static void 7410696SDavid.Hollister@Sun.COM display_ic(struct pmcs_hw m, int verbose) 7510696SDavid.Hollister@Sun.COM { 7610696SDavid.Hollister@Sun.COM int msec_per_tick; 7710696SDavid.Hollister@Sun.COM 7810696SDavid.Hollister@Sun.COM if (mdb_readvar(&msec_per_tick, "msec_per_tick") == -1) { 7910696SDavid.Hollister@Sun.COM mdb_warn("can't read msec_per_tick"); 8010696SDavid.Hollister@Sun.COM msec_per_tick = 0; 8110696SDavid.Hollister@Sun.COM } 8210696SDavid.Hollister@Sun.COM 8310696SDavid.Hollister@Sun.COM mdb_printf("\n"); 8410696SDavid.Hollister@Sun.COM mdb_printf("Interrupt coalescing timer info\n"); 8510696SDavid.Hollister@Sun.COM mdb_printf("-------------------------------\n"); 8610696SDavid.Hollister@Sun.COM if (msec_per_tick == 0) { 8710696SDavid.Hollister@Sun.COM mdb_printf("Quantum : ?? ms\n"); 8810696SDavid.Hollister@Sun.COM } else { 8910696SDavid.Hollister@Sun.COM mdb_printf("Quantum : %d ms\n", 9010696SDavid.Hollister@Sun.COM m.io_intr_coal.quantum * msec_per_tick); 9110696SDavid.Hollister@Sun.COM } 9210696SDavid.Hollister@Sun.COM mdb_printf("Timer enabled : "); 9310696SDavid.Hollister@Sun.COM if (m.io_intr_coal.timer_on) { 9410696SDavid.Hollister@Sun.COM mdb_printf("Yes\n"); 9510696SDavid.Hollister@Sun.COM mdb_printf("Coalescing timer value : %d us\n", 9610696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_coal_timer); 9710696SDavid.Hollister@Sun.COM } else { 9810696SDavid.Hollister@Sun.COM mdb_printf("No\n"); 9910696SDavid.Hollister@Sun.COM } 10010696SDavid.Hollister@Sun.COM mdb_printf("Total nsecs between interrupts: %ld\n", 10110696SDavid.Hollister@Sun.COM m.io_intr_coal.nsecs_between_intrs); 10210696SDavid.Hollister@Sun.COM mdb_printf("Time of last I/O interrupt : %ld\n", 10310696SDavid.Hollister@Sun.COM m.io_intr_coal.last_io_comp); 10410696SDavid.Hollister@Sun.COM mdb_printf("Number of I/O interrupts : %d\n", 10510696SDavid.Hollister@Sun.COM m.io_intr_coal.num_intrs); 10610696SDavid.Hollister@Sun.COM mdb_printf("Number of I/O completions : %d\n", 10710696SDavid.Hollister@Sun.COM m.io_intr_coal.num_io_completions); 10810696SDavid.Hollister@Sun.COM mdb_printf("Max I/O completion interrupts : %d\n", 10910696SDavid.Hollister@Sun.COM m.io_intr_coal.max_io_completions); 11010696SDavid.Hollister@Sun.COM mdb_printf("Measured ECHO int latency : %d ns\n", 11110696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_latency); 11210696SDavid.Hollister@Sun.COM mdb_printf("Interrupt threshold : %d\n", 11310696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_threshold); 11410696SDavid.Hollister@Sun.COM } 11510696SDavid.Hollister@Sun.COM 11610696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 11710696SDavid.Hollister@Sun.COM static int 11810696SDavid.Hollister@Sun.COM pmcs_iport_phy_walk_cb(uintptr_t addr, const void *wdata, void *priv) 11910696SDavid.Hollister@Sun.COM { 12010696SDavid.Hollister@Sun.COM struct pmcs_phy phy; 12110696SDavid.Hollister@Sun.COM 12210696SDavid.Hollister@Sun.COM if (mdb_vread(&phy, sizeof (struct pmcs_phy), addr) != 12310696SDavid.Hollister@Sun.COM sizeof (struct pmcs_phy)) { 12410696SDavid.Hollister@Sun.COM return (DCMD_ERR); 12510696SDavid.Hollister@Sun.COM } 12610696SDavid.Hollister@Sun.COM 12710696SDavid.Hollister@Sun.COM mdb_printf("%16p %2d\n", addr, phy.phynum); 12810696SDavid.Hollister@Sun.COM 12910696SDavid.Hollister@Sun.COM return (0); 13010696SDavid.Hollister@Sun.COM } 13110696SDavid.Hollister@Sun.COM 13211334SReed.Liu@Sun.COM static int 13311334SReed.Liu@Sun.COM display_iport_damap(dev_info_t *pdip) 13411334SReed.Liu@Sun.COM { 13511334SReed.Liu@Sun.COM int rval = DCMD_ERR; 13611334SReed.Liu@Sun.COM struct dev_info dip; 13711334SReed.Liu@Sun.COM scsi_hba_tran_t sht; 13811334SReed.Liu@Sun.COM mdb_ctf_id_t istm_ctfid; /* impl_scsi_tgtmap_t ctf_id */ 13911334SReed.Liu@Sun.COM ulong_t tmd_offset = 0; /* tgtmap_dam offset to impl_scsi_tgtmap_t */ 14011334SReed.Liu@Sun.COM uintptr_t dam0; 14111334SReed.Liu@Sun.COM uintptr_t dam1; 14211334SReed.Liu@Sun.COM 14311334SReed.Liu@Sun.COM if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)pdip) != 14411334SReed.Liu@Sun.COM sizeof (struct dev_info)) { 14511334SReed.Liu@Sun.COM return (rval); 14611334SReed.Liu@Sun.COM } 14711334SReed.Liu@Sun.COM 14811334SReed.Liu@Sun.COM if (dip.devi_driver_data == NULL) { 14911334SReed.Liu@Sun.COM return (rval); 15011334SReed.Liu@Sun.COM } 15111334SReed.Liu@Sun.COM 15211334SReed.Liu@Sun.COM if (mdb_vread(&sht, sizeof (scsi_hba_tran_t), 15311334SReed.Liu@Sun.COM (uintptr_t)dip.devi_driver_data) != sizeof (scsi_hba_tran_t)) { 15411334SReed.Liu@Sun.COM return (rval); 15511334SReed.Liu@Sun.COM } 15611334SReed.Liu@Sun.COM 15711334SReed.Liu@Sun.COM if (sht.tran_tgtmap == NULL) { 15811334SReed.Liu@Sun.COM return (rval); 15911334SReed.Liu@Sun.COM } 16011334SReed.Liu@Sun.COM 16111334SReed.Liu@Sun.COM if (mdb_ctf_lookup_by_name("impl_scsi_tgtmap_t", &istm_ctfid) != 0) { 16211334SReed.Liu@Sun.COM return (rval); 16311334SReed.Liu@Sun.COM } 16411334SReed.Liu@Sun.COM 16511334SReed.Liu@Sun.COM if (mdb_ctf_offsetof(istm_ctfid, "tgtmap_dam", &tmd_offset) != 0) { 16611334SReed.Liu@Sun.COM return (rval); 16711334SReed.Liu@Sun.COM } 16811334SReed.Liu@Sun.COM 16911334SReed.Liu@Sun.COM tmd_offset /= NBBY; 17011334SReed.Liu@Sun.COM mdb_vread(&dam0, sizeof (dam0), 17111334SReed.Liu@Sun.COM (uintptr_t)(tmd_offset + (char *)sht.tran_tgtmap)); 17211334SReed.Liu@Sun.COM mdb_vread(&dam1, sizeof (dam1), 17311334SReed.Liu@Sun.COM (uintptr_t)(sizeof (dam0) + tmd_offset + (char *)sht.tran_tgtmap)); 17411334SReed.Liu@Sun.COM 17511334SReed.Liu@Sun.COM if (dam0 != NULL) { 17611334SReed.Liu@Sun.COM rval = mdb_call_dcmd("damap", dam0, DCMD_ADDRSPEC, 0, NULL); 17711334SReed.Liu@Sun.COM mdb_printf("\n"); 17811334SReed.Liu@Sun.COM if (rval != DCMD_OK) { 17911334SReed.Liu@Sun.COM return (rval); 18011334SReed.Liu@Sun.COM } 18111334SReed.Liu@Sun.COM } 18211334SReed.Liu@Sun.COM 18311334SReed.Liu@Sun.COM if (dam1 != NULL) { 18411334SReed.Liu@Sun.COM rval = mdb_call_dcmd("damap", dam1, DCMD_ADDRSPEC, 0, NULL); 18511334SReed.Liu@Sun.COM mdb_printf("\n"); 18611334SReed.Liu@Sun.COM } 18711334SReed.Liu@Sun.COM 18811334SReed.Liu@Sun.COM return (rval); 18911334SReed.Liu@Sun.COM } 19011334SReed.Liu@Sun.COM 19111334SReed.Liu@Sun.COM /* ARGSUSED */ 19211334SReed.Liu@Sun.COM static int 19311334SReed.Liu@Sun.COM display_iport_di_cb(uintptr_t addr, const void *wdata, void *priv) 19411334SReed.Liu@Sun.COM { 19511334SReed.Liu@Sun.COM uint_t *idx = (uint_t *)priv; 19611334SReed.Liu@Sun.COM struct dev_info dip; 19711334SReed.Liu@Sun.COM char devi_name[MAXNAMELEN]; 19811334SReed.Liu@Sun.COM char devi_addr[MAXNAMELEN]; 19911334SReed.Liu@Sun.COM 20011334SReed.Liu@Sun.COM if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)addr) != 20111334SReed.Liu@Sun.COM sizeof (struct dev_info)) { 20211334SReed.Liu@Sun.COM return (DCMD_ERR); 20311334SReed.Liu@Sun.COM } 20411334SReed.Liu@Sun.COM 20511334SReed.Liu@Sun.COM if (mdb_readstr(devi_name, sizeof (devi_name), 20611334SReed.Liu@Sun.COM (uintptr_t)dip.devi_node_name) == -1) { 20711334SReed.Liu@Sun.COM devi_name[0] = '?'; 20811334SReed.Liu@Sun.COM devi_name[1] = '\0'; 20911334SReed.Liu@Sun.COM } 21011334SReed.Liu@Sun.COM 21111334SReed.Liu@Sun.COM if (mdb_readstr(devi_addr, sizeof (devi_addr), 21211334SReed.Liu@Sun.COM (uintptr_t)dip.devi_addr) == -1) { 21311334SReed.Liu@Sun.COM devi_addr[0] = '?'; 21411334SReed.Liu@Sun.COM devi_addr[1] = '\0'; 21511334SReed.Liu@Sun.COM } 21611334SReed.Liu@Sun.COM 21711334SReed.Liu@Sun.COM mdb_printf(" %3d: @%-21s%10s@\t%p::devinfo -s\n", 21811334SReed.Liu@Sun.COM (*idx)++, devi_addr, devi_name, addr); 21911334SReed.Liu@Sun.COM return (DCMD_OK); 22011334SReed.Liu@Sun.COM } 22111334SReed.Liu@Sun.COM 22211334SReed.Liu@Sun.COM /* ARGSUSED */ 22311334SReed.Liu@Sun.COM static int 22411334SReed.Liu@Sun.COM display_iport_pi_cb(uintptr_t addr, const void *wdata, void *priv) 22511334SReed.Liu@Sun.COM { 22611334SReed.Liu@Sun.COM uint_t *idx = (uint_t *)priv; 22711334SReed.Liu@Sun.COM struct mdi_pathinfo mpi; 22811334SReed.Liu@Sun.COM char pi_addr[MAXNAMELEN]; 22911334SReed.Liu@Sun.COM 23011334SReed.Liu@Sun.COM if (mdb_vread(&mpi, sizeof (struct mdi_pathinfo), (uintptr_t)addr) != 23111334SReed.Liu@Sun.COM sizeof (struct mdi_pathinfo)) { 23211334SReed.Liu@Sun.COM return (DCMD_ERR); 23311334SReed.Liu@Sun.COM } 23411334SReed.Liu@Sun.COM 23511334SReed.Liu@Sun.COM if (mdb_readstr(pi_addr, sizeof (pi_addr), 23611334SReed.Liu@Sun.COM (uintptr_t)mpi.pi_addr) == -1) { 23711334SReed.Liu@Sun.COM pi_addr[0] = '?'; 23811334SReed.Liu@Sun.COM pi_addr[1] = '\0'; 23911334SReed.Liu@Sun.COM } 24011334SReed.Liu@Sun.COM 24111334SReed.Liu@Sun.COM mdb_printf(" %3d: @%-21s %p::print struct mdi_pathinfo\n", 24211334SReed.Liu@Sun.COM (*idx)++, pi_addr, addr); 24311334SReed.Liu@Sun.COM return (DCMD_OK); 24411334SReed.Liu@Sun.COM } 24511334SReed.Liu@Sun.COM 24611334SReed.Liu@Sun.COM static int 24711334SReed.Liu@Sun.COM display_iport_dtc(dev_info_t *pdip) 24811334SReed.Liu@Sun.COM { 24911334SReed.Liu@Sun.COM int rval = DCMD_ERR; 25011334SReed.Liu@Sun.COM struct dev_info dip; 25111334SReed.Liu@Sun.COM struct mdi_phci phci; 25211334SReed.Liu@Sun.COM uint_t didx = 1; 25311334SReed.Liu@Sun.COM uint_t pidx = 1; 25411334SReed.Liu@Sun.COM 25511334SReed.Liu@Sun.COM if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)pdip) != 25611334SReed.Liu@Sun.COM sizeof (struct dev_info)) { 25711334SReed.Liu@Sun.COM return (rval); 25811334SReed.Liu@Sun.COM } 25911334SReed.Liu@Sun.COM 26011334SReed.Liu@Sun.COM mdb_printf("Device tree children - dev_info:\n"); 26111334SReed.Liu@Sun.COM if (dip.devi_child == NULL) { 26211334SReed.Liu@Sun.COM mdb_printf("\tdevi_child is NULL, no dev_info\n\n"); 26311334SReed.Liu@Sun.COM goto skip_di; 26411334SReed.Liu@Sun.COM } 26511334SReed.Liu@Sun.COM 26611334SReed.Liu@Sun.COM /* 26711334SReed.Liu@Sun.COM * First, we dump the iport's children dev_info node information. 26811334SReed.Liu@Sun.COM * use existing walker: devinfo_siblings 26911334SReed.Liu@Sun.COM */ 27011334SReed.Liu@Sun.COM mdb_printf("\t#: @unit-address name@\tdrill-down\n"); 27111334SReed.Liu@Sun.COM rval = mdb_pwalk("devinfo_siblings", display_iport_di_cb, 27211334SReed.Liu@Sun.COM (void *)&didx, (uintptr_t)dip.devi_child); 27311334SReed.Liu@Sun.COM mdb_printf("\n"); 27411334SReed.Liu@Sun.COM 27511334SReed.Liu@Sun.COM skip_di: 27611334SReed.Liu@Sun.COM /* 27711334SReed.Liu@Sun.COM * Then we try to dump the iport's path_info node information. 27811334SReed.Liu@Sun.COM * use existing walker: mdipi_phci_list 27911334SReed.Liu@Sun.COM */ 28011334SReed.Liu@Sun.COM mdb_printf("Device tree children - path_info:\n"); 28111334SReed.Liu@Sun.COM if (mdb_vread(&phci, sizeof (struct mdi_phci), 28211334SReed.Liu@Sun.COM (uintptr_t)dip.devi_mdi_xhci) != sizeof (struct mdi_phci)) { 28311334SReed.Liu@Sun.COM mdb_printf("\tdevi_mdi_xhci is NULL, no path_info\n\n"); 28411334SReed.Liu@Sun.COM return (rval); 28511334SReed.Liu@Sun.COM } 28611334SReed.Liu@Sun.COM 28711334SReed.Liu@Sun.COM if (phci.ph_path_head == NULL) { 28811334SReed.Liu@Sun.COM mdb_printf("\tph_path_head is NULL, no path_info\n\n"); 28911334SReed.Liu@Sun.COM return (rval); 29011334SReed.Liu@Sun.COM } 29111334SReed.Liu@Sun.COM 29211334SReed.Liu@Sun.COM mdb_printf("\t#: @unit-address drill-down\n"); 29311334SReed.Liu@Sun.COM rval = mdb_pwalk("mdipi_phci_list", display_iport_pi_cb, 29411334SReed.Liu@Sun.COM (void *)&pidx, (uintptr_t)phci.ph_path_head); 29511334SReed.Liu@Sun.COM mdb_printf("\n"); 29611334SReed.Liu@Sun.COM return (rval); 29711334SReed.Liu@Sun.COM } 29811334SReed.Liu@Sun.COM 29911334SReed.Liu@Sun.COM static void 30011334SReed.Liu@Sun.COM display_iport_more(dev_info_t *dip, per_iport_setting_t *pis) 30111334SReed.Liu@Sun.COM { 30211334SReed.Liu@Sun.COM if (pis->pis_damap_info) { 30311334SReed.Liu@Sun.COM (void) display_iport_damap(dip); 30411334SReed.Liu@Sun.COM } 30511334SReed.Liu@Sun.COM 30611334SReed.Liu@Sun.COM if (pis->pis_dtc_info) { 30711334SReed.Liu@Sun.COM (void) display_iport_dtc(dip); 30811334SReed.Liu@Sun.COM } 30911334SReed.Liu@Sun.COM } 31011334SReed.Liu@Sun.COM 31110696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 31210696SDavid.Hollister@Sun.COM static int 31310696SDavid.Hollister@Sun.COM pmcs_iport_walk_cb(uintptr_t addr, const void *wdata, void *priv) 31410696SDavid.Hollister@Sun.COM { 31510696SDavid.Hollister@Sun.COM struct pmcs_iport iport; 31610696SDavid.Hollister@Sun.COM uintptr_t list_addr; 31710696SDavid.Hollister@Sun.COM char *ua_state; 31810696SDavid.Hollister@Sun.COM char portid[4]; 31910696SDavid.Hollister@Sun.COM char unit_address[34]; 32011334SReed.Liu@Sun.COM per_iport_setting_t *pis = (per_iport_setting_t *)priv; 32110696SDavid.Hollister@Sun.COM 32210696SDavid.Hollister@Sun.COM if (mdb_vread(&iport, sizeof (struct pmcs_iport), addr) != 32310696SDavid.Hollister@Sun.COM sizeof (struct pmcs_iport)) { 32410696SDavid.Hollister@Sun.COM return (DCMD_ERR); 32510696SDavid.Hollister@Sun.COM } 32610696SDavid.Hollister@Sun.COM 32710696SDavid.Hollister@Sun.COM if (mdb_readstr(unit_address, sizeof (unit_address), 32810696SDavid.Hollister@Sun.COM (uintptr_t)(iport.ua)) == -1) { 32910696SDavid.Hollister@Sun.COM strncpy(unit_address, "Unset", sizeof (unit_address)); 33010696SDavid.Hollister@Sun.COM } 33110696SDavid.Hollister@Sun.COM 33210696SDavid.Hollister@Sun.COM if (iport.portid == 0xffff) { 33310696SDavid.Hollister@Sun.COM mdb_snprintf(portid, sizeof (portid), "%s", "-"); 33411347SRamana.Srikanth@Sun.COM } else if (iport.portid == PMCS_IPORT_INVALID_PORT_ID) { 33511347SRamana.Srikanth@Sun.COM mdb_snprintf(portid, sizeof (portid), "%s", "N/A"); 33610696SDavid.Hollister@Sun.COM } else { 33710696SDavid.Hollister@Sun.COM mdb_snprintf(portid, sizeof (portid), "%d", iport.portid); 33810696SDavid.Hollister@Sun.COM } 33910696SDavid.Hollister@Sun.COM 34010696SDavid.Hollister@Sun.COM switch (iport.ua_state) { 34110696SDavid.Hollister@Sun.COM case UA_INACTIVE: 34210696SDavid.Hollister@Sun.COM ua_state = "Inactive"; 34310696SDavid.Hollister@Sun.COM break; 34410696SDavid.Hollister@Sun.COM case UA_PEND_ACTIVATE: 34510696SDavid.Hollister@Sun.COM ua_state = "PendActivate"; 34610696SDavid.Hollister@Sun.COM break; 34710696SDavid.Hollister@Sun.COM case UA_ACTIVE: 34810696SDavid.Hollister@Sun.COM ua_state = "Active"; 34910696SDavid.Hollister@Sun.COM break; 35010696SDavid.Hollister@Sun.COM case UA_PEND_DEACTIVATE: 35110696SDavid.Hollister@Sun.COM ua_state = "PendDeactivate"; 35210696SDavid.Hollister@Sun.COM break; 35310696SDavid.Hollister@Sun.COM default: 35410696SDavid.Hollister@Sun.COM ua_state = "Unknown"; 35510696SDavid.Hollister@Sun.COM } 35610696SDavid.Hollister@Sun.COM 35710696SDavid.Hollister@Sun.COM if (strlen(unit_address) < 3) { 35810696SDavid.Hollister@Sun.COM /* Standard iport unit address */ 35910696SDavid.Hollister@Sun.COM mdb_printf("UA %-16s %16s %8s %8s %16s", "Iport", "UA State", 36010696SDavid.Hollister@Sun.COM "PortID", "NumPhys", "DIP\n"); 36110696SDavid.Hollister@Sun.COM mdb_printf("%2s %16p %16s %8s %8d %16p\n", unit_address, addr, 36210696SDavid.Hollister@Sun.COM ua_state, portid, iport.nphy, iport.dip); 36310696SDavid.Hollister@Sun.COM } else { 36410696SDavid.Hollister@Sun.COM /* Temporary iport unit address */ 36510696SDavid.Hollister@Sun.COM mdb_printf("%-32s %16s %20s %8s %8s %16s", "UA", "Iport", 36610696SDavid.Hollister@Sun.COM "UA State", "PortID", "NumPhys", "DIP\n"); 36710696SDavid.Hollister@Sun.COM mdb_printf("%32s %16p %20s %8s %8d %16p\n", unit_address, addr, 36810696SDavid.Hollister@Sun.COM ua_state, portid, iport.nphy, iport.dip); 36910696SDavid.Hollister@Sun.COM } 37010696SDavid.Hollister@Sun.COM 37110696SDavid.Hollister@Sun.COM if (iport.nphy > 0) { 37210696SDavid.Hollister@Sun.COM mdb_inc_indent(4); 37310696SDavid.Hollister@Sun.COM mdb_printf("%-18s %8s", "Phy", "PhyNum\n"); 37410696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 37510696SDavid.Hollister@Sun.COM list_addr = 37610696SDavid.Hollister@Sun.COM (uintptr_t)(addr + offsetof(struct pmcs_iport, phys)); 37710696SDavid.Hollister@Sun.COM if (mdb_pwalk("list", pmcs_iport_phy_walk_cb, NULL, 37810696SDavid.Hollister@Sun.COM list_addr) == -1) { 37910696SDavid.Hollister@Sun.COM mdb_warn("pmcs iport walk failed"); 38010696SDavid.Hollister@Sun.COM } 38110696SDavid.Hollister@Sun.COM mdb_dec_indent(6); 38210696SDavid.Hollister@Sun.COM mdb_printf("\n"); 38310696SDavid.Hollister@Sun.COM } 38410696SDavid.Hollister@Sun.COM 38511334SReed.Liu@Sun.COM /* 38611334SReed.Liu@Sun.COM * See if we need to show more information based on 'd' or 'm' options 38711334SReed.Liu@Sun.COM */ 38811334SReed.Liu@Sun.COM display_iport_more(iport.dip, pis); 38911334SReed.Liu@Sun.COM 39010696SDavid.Hollister@Sun.COM return (0); 39110696SDavid.Hollister@Sun.COM } 39210696SDavid.Hollister@Sun.COM 39310696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 39410696SDavid.Hollister@Sun.COM static void 39511334SReed.Liu@Sun.COM display_iport(struct pmcs_hw m, uintptr_t addr, int verbose, 39611334SReed.Liu@Sun.COM per_iport_setting_t *pis) 39710696SDavid.Hollister@Sun.COM { 39810696SDavid.Hollister@Sun.COM uintptr_t list_addr; 39910696SDavid.Hollister@Sun.COM 40010696SDavid.Hollister@Sun.COM if (m.iports_attached) { 40110696SDavid.Hollister@Sun.COM mdb_printf("Iport information:\n"); 40210696SDavid.Hollister@Sun.COM mdb_printf("-----------------\n"); 40310696SDavid.Hollister@Sun.COM } else { 40410696SDavid.Hollister@Sun.COM mdb_printf("No Iports found.\n\n"); 40510696SDavid.Hollister@Sun.COM return; 40610696SDavid.Hollister@Sun.COM } 40710696SDavid.Hollister@Sun.COM 40810696SDavid.Hollister@Sun.COM list_addr = (uintptr_t)(addr + offsetof(struct pmcs_hw, iports)); 40910696SDavid.Hollister@Sun.COM 41011334SReed.Liu@Sun.COM if (mdb_pwalk("list", pmcs_iport_walk_cb, pis, list_addr) == -1) { 41110696SDavid.Hollister@Sun.COM mdb_warn("pmcs iport walk failed"); 41210696SDavid.Hollister@Sun.COM } 41310696SDavid.Hollister@Sun.COM 41410696SDavid.Hollister@Sun.COM mdb_printf("\n"); 41510696SDavid.Hollister@Sun.COM } 41610696SDavid.Hollister@Sun.COM 41711048SDavid.Hollister@Sun.COM /* ARGSUSED */ 41811048SDavid.Hollister@Sun.COM static int 41911048SDavid.Hollister@Sun.COM pmcs_utarget_walk_cb(uintptr_t addr, const void *wdata, void *priv) 42011048SDavid.Hollister@Sun.COM { 42111048SDavid.Hollister@Sun.COM pmcs_phy_t phy; 42211048SDavid.Hollister@Sun.COM 42311048SDavid.Hollister@Sun.COM if (mdb_vread(&phy, sizeof (pmcs_phy_t), (uintptr_t)addr) == -1) { 42411048SDavid.Hollister@Sun.COM mdb_warn("pmcs_utarget_walk_cb: Failed to read PHY at %p", 42511048SDavid.Hollister@Sun.COM (void *)addr); 42611048SDavid.Hollister@Sun.COM return (DCMD_ERR); 42711048SDavid.Hollister@Sun.COM } 42811048SDavid.Hollister@Sun.COM 42911048SDavid.Hollister@Sun.COM if (phy.configured && (phy.target == NULL)) { 43011048SDavid.Hollister@Sun.COM mdb_printf("SAS address: "); 43111048SDavid.Hollister@Sun.COM print_sas_address(&phy); 43211048SDavid.Hollister@Sun.COM mdb_printf(" DType: "); 43311048SDavid.Hollister@Sun.COM switch (phy.dtype) { 43411048SDavid.Hollister@Sun.COM case SAS: 43511048SDavid.Hollister@Sun.COM mdb_printf("%4s", "SAS"); 43611048SDavid.Hollister@Sun.COM break; 43711048SDavid.Hollister@Sun.COM case SATA: 43811048SDavid.Hollister@Sun.COM mdb_printf("%4s", "SATA"); 43911048SDavid.Hollister@Sun.COM break; 44011048SDavid.Hollister@Sun.COM case EXPANDER: 44111048SDavid.Hollister@Sun.COM mdb_printf("%4s", "SMP"); 44211048SDavid.Hollister@Sun.COM break; 44311048SDavid.Hollister@Sun.COM default: 44411048SDavid.Hollister@Sun.COM mdb_printf("%4s", "N/A"); 44511048SDavid.Hollister@Sun.COM break; 44611048SDavid.Hollister@Sun.COM } 44711048SDavid.Hollister@Sun.COM mdb_printf(" Path: %s\n", phy.path); 44811048SDavid.Hollister@Sun.COM } 44911048SDavid.Hollister@Sun.COM 45011048SDavid.Hollister@Sun.COM return (0); 45111048SDavid.Hollister@Sun.COM } 45211048SDavid.Hollister@Sun.COM 45311048SDavid.Hollister@Sun.COM static void 45411048SDavid.Hollister@Sun.COM display_unconfigured_targets(uintptr_t addr) 45511048SDavid.Hollister@Sun.COM { 45611048SDavid.Hollister@Sun.COM mdb_printf("Unconfigured target SAS address:\n\n"); 45711048SDavid.Hollister@Sun.COM 45811048SDavid.Hollister@Sun.COM if (mdb_pwalk("pmcs_phys", pmcs_utarget_walk_cb, NULL, addr) == -1) { 45911048SDavid.Hollister@Sun.COM mdb_warn("pmcs phys walk failed"); 46011048SDavid.Hollister@Sun.COM } 46111048SDavid.Hollister@Sun.COM } 46211048SDavid.Hollister@Sun.COM 46310743SDavid.Hollister@Sun.COM static void 46410743SDavid.Hollister@Sun.COM display_completion_queue(struct pmcs_hw ss) 46510743SDavid.Hollister@Sun.COM { 46610743SDavid.Hollister@Sun.COM pmcs_iocomp_cb_t ccb, *ccbp; 46710743SDavid.Hollister@Sun.COM pmcwork_t work; 46810743SDavid.Hollister@Sun.COM 46910743SDavid.Hollister@Sun.COM if (ss.iocomp_cb_head == NULL) { 47010743SDavid.Hollister@Sun.COM mdb_printf("Completion queue is empty.\n"); 47110743SDavid.Hollister@Sun.COM return; 47210743SDavid.Hollister@Sun.COM } 47310743SDavid.Hollister@Sun.COM 47410743SDavid.Hollister@Sun.COM ccbp = ss.iocomp_cb_head; 47510743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D\n", 47610743SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 47710743SDavid.Hollister@Sun.COM 47810743SDavid.Hollister@Sun.COM while (ccbp) { 47910743SDavid.Hollister@Sun.COM if (mdb_vread(&ccb, sizeof (pmcs_iocomp_cb_t), 48010743SDavid.Hollister@Sun.COM (uintptr_t)ccbp) != sizeof (pmcs_iocomp_cb_t)) { 48110743SDavid.Hollister@Sun.COM mdb_warn("Unable to read completion queue entry\n"); 48210743SDavid.Hollister@Sun.COM return; 48310743SDavid.Hollister@Sun.COM } 48410743SDavid.Hollister@Sun.COM 48510743SDavid.Hollister@Sun.COM if (mdb_vread(&work, sizeof (pmcwork_t), (uintptr_t)ccb.pwrk) 48610743SDavid.Hollister@Sun.COM != sizeof (pmcwork_t)) { 48710743SDavid.Hollister@Sun.COM mdb_warn("Unable to read work structure\n"); 48810743SDavid.Hollister@Sun.COM return; 48910743SDavid.Hollister@Sun.COM } 49010743SDavid.Hollister@Sun.COM 49110743SDavid.Hollister@Sun.COM /* 49210743SDavid.Hollister@Sun.COM * Only print the work structure if it's still active. If 49310743SDavid.Hollister@Sun.COM * it's not, it's been completed since we started looking at 49410743SDavid.Hollister@Sun.COM * it. 49510743SDavid.Hollister@Sun.COM */ 49610743SDavid.Hollister@Sun.COM if (work.state != PMCS_WORK_STATE_NIL) { 49710743SDavid.Hollister@Sun.COM display_one_work(&work, 0, 0); 49810743SDavid.Hollister@Sun.COM } 49910743SDavid.Hollister@Sun.COM ccbp = ccb.next; 50010743SDavid.Hollister@Sun.COM } 50110743SDavid.Hollister@Sun.COM } 50210743SDavid.Hollister@Sun.COM 50310696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 50410696SDavid.Hollister@Sun.COM static void 50510696SDavid.Hollister@Sun.COM display_hwinfo(struct pmcs_hw m, int verbose) 50610696SDavid.Hollister@Sun.COM { 50710696SDavid.Hollister@Sun.COM struct pmcs_hw *mp = &m; 50810696SDavid.Hollister@Sun.COM char *fwsupport; 50910696SDavid.Hollister@Sun.COM 51010696SDavid.Hollister@Sun.COM switch (PMCS_FW_TYPE(mp)) { 51110696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_RELEASED: 51210696SDavid.Hollister@Sun.COM fwsupport = "Released"; 51310696SDavid.Hollister@Sun.COM break; 51410696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_DEVELOPMENT: 51510696SDavid.Hollister@Sun.COM fwsupport = "Development"; 51610696SDavid.Hollister@Sun.COM break; 51710696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_ALPHA: 51810696SDavid.Hollister@Sun.COM fwsupport = "Alpha"; 51910696SDavid.Hollister@Sun.COM break; 52010696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_BETA: 52110696SDavid.Hollister@Sun.COM fwsupport = "Beta"; 52210696SDavid.Hollister@Sun.COM break; 52310696SDavid.Hollister@Sun.COM default: 52410696SDavid.Hollister@Sun.COM fwsupport = "Special"; 52510696SDavid.Hollister@Sun.COM break; 52610696SDavid.Hollister@Sun.COM } 52710696SDavid.Hollister@Sun.COM 52810696SDavid.Hollister@Sun.COM mdb_printf("\nHardware information:\n"); 52910696SDavid.Hollister@Sun.COM mdb_printf("---------------------\n"); 53010696SDavid.Hollister@Sun.COM 53110696SDavid.Hollister@Sun.COM mdb_printf("Chip revision: %c\n", 'A' + m.chiprev); 53210696SDavid.Hollister@Sun.COM mdb_printf("SAS WWID: %"PRIx64"\n", m.sas_wwns[0]); 53310696SDavid.Hollister@Sun.COM mdb_printf("Firmware version: %x.%x.%x (%s)\n", 53410696SDavid.Hollister@Sun.COM PMCS_FW_MAJOR(mp), PMCS_FW_MINOR(mp), PMCS_FW_MICRO(mp), 53510696SDavid.Hollister@Sun.COM fwsupport); 536*11980SDavid.Hollister@Sun.COM mdb_printf("ILA version: %08x\n", m.ila_ver); 537*11980SDavid.Hollister@Sun.COM mdb_printf("Active f/w img: %c\n", (m.fw_active_img) ? 'A' : 'B'); 53810696SDavid.Hollister@Sun.COM 53910696SDavid.Hollister@Sun.COM mdb_printf("Number of PHYs: %d\n", m.nphy); 54010696SDavid.Hollister@Sun.COM mdb_printf("Maximum commands: %d\n", m.max_cmd); 54110696SDavid.Hollister@Sun.COM mdb_printf("Maximum devices: %d\n", m.max_dev); 54210696SDavid.Hollister@Sun.COM mdb_printf("I/O queue depth: %d\n", m.ioq_depth); 54310696SDavid.Hollister@Sun.COM if (m.fwlog == 0) { 54410696SDavid.Hollister@Sun.COM mdb_printf("Firmware logging: Disabled\n"); 54510696SDavid.Hollister@Sun.COM } else { 54610696SDavid.Hollister@Sun.COM mdb_printf("Firmware logging: Enabled (%d)\n", m.fwlog); 54710696SDavid.Hollister@Sun.COM } 548*11980SDavid.Hollister@Sun.COM if (m.fwlog_file == 0) { 549*11980SDavid.Hollister@Sun.COM mdb_printf("Firmware logfile: Not configured\n"); 550*11980SDavid.Hollister@Sun.COM } else { 551*11980SDavid.Hollister@Sun.COM mdb_printf("Firmware logfile: Configured\n"); 552*11980SDavid.Hollister@Sun.COM mdb_inc_indent(2); 553*11980SDavid.Hollister@Sun.COM mdb_printf("AAP1 log file: %s\n", m.fwlogfile_aap1); 554*11980SDavid.Hollister@Sun.COM mdb_printf("IOP logfile: %s\n", m.fwlogfile_iop); 555*11980SDavid.Hollister@Sun.COM mdb_dec_indent(2); 556*11980SDavid.Hollister@Sun.COM } 55710696SDavid.Hollister@Sun.COM } 55810696SDavid.Hollister@Sun.COM 55910696SDavid.Hollister@Sun.COM static void 56010696SDavid.Hollister@Sun.COM display_targets(struct pmcs_hw m, int verbose, int totals_only) 56110696SDavid.Hollister@Sun.COM { 56210696SDavid.Hollister@Sun.COM char *dtype; 56310696SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 56410696SDavid.Hollister@Sun.COM pmcs_phy_t phy; 56510696SDavid.Hollister@Sun.COM uint16_t max_dev, idx; 56610696SDavid.Hollister@Sun.COM uint32_t sas_targets = 0, smp_targets = 0, sata_targets = 0; 56710696SDavid.Hollister@Sun.COM 56810696SDavid.Hollister@Sun.COM max_dev = m.max_dev; 56910696SDavid.Hollister@Sun.COM 57010696SDavid.Hollister@Sun.COM if (targets == NULL) { 57110696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * max_dev, UM_SLEEP); 57210696SDavid.Hollister@Sun.COM } 57310696SDavid.Hollister@Sun.COM 57410696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * max_dev, m.targets) == -1) { 57510696SDavid.Hollister@Sun.COM NOREAD(targets, m.targets); 57610696SDavid.Hollister@Sun.COM return; 57710696SDavid.Hollister@Sun.COM } 57810696SDavid.Hollister@Sun.COM 57910696SDavid.Hollister@Sun.COM if (!totals_only) { 58010696SDavid.Hollister@Sun.COM mdb_printf("\nTarget information:\n"); 58110696SDavid.Hollister@Sun.COM mdb_printf("---------------------------------------\n"); 58211347SRamana.Srikanth@Sun.COM mdb_printf("VTGT %-16s %-16s %-5s %4s %6s %s", "SAS Address", 58311347SRamana.Srikanth@Sun.COM "PHY Address", "DType", "Actv", "OnChip", "DS"); 58410696SDavid.Hollister@Sun.COM mdb_printf("\n"); 58510696SDavid.Hollister@Sun.COM } 58610696SDavid.Hollister@Sun.COM 58710696SDavid.Hollister@Sun.COM for (idx = 0; idx < max_dev; idx++) { 58810696SDavid.Hollister@Sun.COM if (targets[idx] == NULL) { 58910696SDavid.Hollister@Sun.COM continue; 59010696SDavid.Hollister@Sun.COM } 59110696SDavid.Hollister@Sun.COM 59210696SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), targets[idx]) == -1) { 59310696SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, targets[idx]); 59410696SDavid.Hollister@Sun.COM continue; 59510696SDavid.Hollister@Sun.COM } 59610696SDavid.Hollister@Sun.COM 59710696SDavid.Hollister@Sun.COM /* 59810755SJesse.Butler@Sun.COM * It has to be new or assigned to be of interest. 59910696SDavid.Hollister@Sun.COM */ 60010755SJesse.Butler@Sun.COM if (xs.new == 0 && xs.assigned == 0) { 60110696SDavid.Hollister@Sun.COM continue; 60210696SDavid.Hollister@Sun.COM } 60310696SDavid.Hollister@Sun.COM 60410696SDavid.Hollister@Sun.COM switch (xs.dtype) { 60510696SDavid.Hollister@Sun.COM case NOTHING: 60610696SDavid.Hollister@Sun.COM dtype = "None"; 60710696SDavid.Hollister@Sun.COM break; 60810696SDavid.Hollister@Sun.COM case SATA: 60910696SDavid.Hollister@Sun.COM dtype = "SATA"; 61010696SDavid.Hollister@Sun.COM sata_targets++; 61110696SDavid.Hollister@Sun.COM break; 61210696SDavid.Hollister@Sun.COM case SAS: 61310696SDavid.Hollister@Sun.COM dtype = "SAS"; 61410696SDavid.Hollister@Sun.COM sas_targets++; 61510696SDavid.Hollister@Sun.COM break; 61610696SDavid.Hollister@Sun.COM case EXPANDER: 61710696SDavid.Hollister@Sun.COM dtype = "SMP"; 61810696SDavid.Hollister@Sun.COM smp_targets++; 61910696SDavid.Hollister@Sun.COM break; 62010696SDavid.Hollister@Sun.COM } 62110696SDavid.Hollister@Sun.COM 62210696SDavid.Hollister@Sun.COM if (totals_only) { 62310696SDavid.Hollister@Sun.COM continue; 62410696SDavid.Hollister@Sun.COM } 62510696SDavid.Hollister@Sun.COM 62610696SDavid.Hollister@Sun.COM if (xs.phy) { 62710696SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), xs.phy) == -1) { 62810696SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, xs.phy); 62910696SDavid.Hollister@Sun.COM continue; 63010696SDavid.Hollister@Sun.COM } 63110696SDavid.Hollister@Sun.COM mdb_printf("%4d ", idx); 63210696SDavid.Hollister@Sun.COM print_sas_address(&phy); 63310696SDavid.Hollister@Sun.COM mdb_printf(" %16p", xs.phy); 63410696SDavid.Hollister@Sun.COM } else { 63510696SDavid.Hollister@Sun.COM mdb_printf("%4d %16s", idx, "<no phy avail>"); 63610696SDavid.Hollister@Sun.COM } 63710696SDavid.Hollister@Sun.COM mdb_printf(" %5s", dtype); 63811347SRamana.Srikanth@Sun.COM mdb_printf(" %4d", xs.actv_pkts); 63911347SRamana.Srikanth@Sun.COM mdb_printf(" %6d", xs.actv_cnt); 64010696SDavid.Hollister@Sun.COM mdb_printf(" %2d", xs.dev_state); 64110696SDavid.Hollister@Sun.COM 64210696SDavid.Hollister@Sun.COM if (verbose) { 64310696SDavid.Hollister@Sun.COM if (xs.new) { 64410696SDavid.Hollister@Sun.COM mdb_printf(" new"); 64510755SJesse.Butler@Sun.COM } 64610755SJesse.Butler@Sun.COM if (xs.assigned) { 64710696SDavid.Hollister@Sun.COM mdb_printf(" assigned"); 64810696SDavid.Hollister@Sun.COM } 64910696SDavid.Hollister@Sun.COM if (xs.draining) { 65010696SDavid.Hollister@Sun.COM mdb_printf(" draining"); 65110696SDavid.Hollister@Sun.COM } 65210696SDavid.Hollister@Sun.COM if (xs.reset_wait) { 65310696SDavid.Hollister@Sun.COM mdb_printf(" reset_wait"); 65410696SDavid.Hollister@Sun.COM } 65510696SDavid.Hollister@Sun.COM if (xs.resetting) { 65610696SDavid.Hollister@Sun.COM mdb_printf(" resetting"); 65710696SDavid.Hollister@Sun.COM } 65810696SDavid.Hollister@Sun.COM if (xs.recover_wait) { 65910696SDavid.Hollister@Sun.COM mdb_printf(" recover_wait"); 66010696SDavid.Hollister@Sun.COM } 66110696SDavid.Hollister@Sun.COM if (xs.recovering) { 66210696SDavid.Hollister@Sun.COM mdb_printf(" recovering"); 66310696SDavid.Hollister@Sun.COM } 66410696SDavid.Hollister@Sun.COM if (xs.event_recovery) { 66510696SDavid.Hollister@Sun.COM mdb_printf(" event recovery"); 66610696SDavid.Hollister@Sun.COM } 66710696SDavid.Hollister@Sun.COM if (xs.special_running) { 66810696SDavid.Hollister@Sun.COM mdb_printf(" special_active"); 66910696SDavid.Hollister@Sun.COM } 67010696SDavid.Hollister@Sun.COM if (xs.ncq) { 67110696SDavid.Hollister@Sun.COM mdb_printf(" ncq_tagmap=0x%x qdepth=%d", 67210696SDavid.Hollister@Sun.COM xs.tagmap, xs.qdepth); 67310696SDavid.Hollister@Sun.COM } else if (xs.pio) { 67410696SDavid.Hollister@Sun.COM mdb_printf(" pio"); 67510696SDavid.Hollister@Sun.COM } 67610696SDavid.Hollister@Sun.COM } 67710696SDavid.Hollister@Sun.COM 67810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 67910696SDavid.Hollister@Sun.COM } 68010696SDavid.Hollister@Sun.COM 68110696SDavid.Hollister@Sun.COM if (!totals_only) { 68210696SDavid.Hollister@Sun.COM mdb_printf("\n"); 68310696SDavid.Hollister@Sun.COM } 68410696SDavid.Hollister@Sun.COM 68510696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP)\n", 68610696SDavid.Hollister@Sun.COM "Configured targets:", (sas_targets + sata_targets + smp_targets), 68710696SDavid.Hollister@Sun.COM sas_targets, sata_targets, smp_targets); 68810696SDavid.Hollister@Sun.COM } 68910696SDavid.Hollister@Sun.COM 69010743SDavid.Hollister@Sun.COM static char * 69110743SDavid.Hollister@Sun.COM work_state_to_string(uint32_t state) 69210743SDavid.Hollister@Sun.COM { 69310743SDavid.Hollister@Sun.COM char *state_string; 69410743SDavid.Hollister@Sun.COM 69510743SDavid.Hollister@Sun.COM switch (state) { 69610743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_NIL: 69710743SDavid.Hollister@Sun.COM state_string = "Free"; 69810743SDavid.Hollister@Sun.COM break; 69910743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_READY: 70010743SDavid.Hollister@Sun.COM state_string = "Ready"; 70110743SDavid.Hollister@Sun.COM break; 70210743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_ONCHIP: 70310743SDavid.Hollister@Sun.COM state_string = "On Chip"; 70410743SDavid.Hollister@Sun.COM break; 70510743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_INTR: 70610743SDavid.Hollister@Sun.COM state_string = "In Intr"; 70710743SDavid.Hollister@Sun.COM break; 70810743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_IOCOMPQ: 70910743SDavid.Hollister@Sun.COM state_string = "I/O Comp"; 71010743SDavid.Hollister@Sun.COM break; 71110743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_ABORTED: 71210743SDavid.Hollister@Sun.COM state_string = "I/O Aborted"; 71310743SDavid.Hollister@Sun.COM break; 71410743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_TIMED_OUT: 71510743SDavid.Hollister@Sun.COM state_string = "I/O Timed Out"; 71610743SDavid.Hollister@Sun.COM break; 71710743SDavid.Hollister@Sun.COM default: 71810743SDavid.Hollister@Sun.COM state_string = "INVALID"; 71910743SDavid.Hollister@Sun.COM break; 72010743SDavid.Hollister@Sun.COM } 72110743SDavid.Hollister@Sun.COM 72210743SDavid.Hollister@Sun.COM return (state_string); 72310743SDavid.Hollister@Sun.COM } 72410743SDavid.Hollister@Sun.COM 72510743SDavid.Hollister@Sun.COM static void 72610743SDavid.Hollister@Sun.COM display_one_work(pmcwork_t *wp, int verbose, int idx) 72710743SDavid.Hollister@Sun.COM { 72810743SDavid.Hollister@Sun.COM char *state, *last_state; 72910743SDavid.Hollister@Sun.COM char *path; 73010743SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 73110743SDavid.Hollister@Sun.COM pmcs_phy_t phy; 73210743SDavid.Hollister@Sun.COM int tgt; 73310743SDavid.Hollister@Sun.COM 73410743SDavid.Hollister@Sun.COM state = work_state_to_string(wp->state); 73510743SDavid.Hollister@Sun.COM last_state = work_state_to_string(wp->last_state); 73610743SDavid.Hollister@Sun.COM 73710743SDavid.Hollister@Sun.COM if (wp->ssp_event && wp->ssp_event != 0xffffffff) { 73810743SDavid.Hollister@Sun.COM mdb_printf("SSP event 0x%x", wp->ssp_event); 73910743SDavid.Hollister@Sun.COM } 74010743SDavid.Hollister@Sun.COM 74110743SDavid.Hollister@Sun.COM tgt = -1; 74210743SDavid.Hollister@Sun.COM if (wp->xp) { 74310743SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), wp->xp) == -1) { 74410743SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, wp->xp); 74510743SDavid.Hollister@Sun.COM } else { 74610743SDavid.Hollister@Sun.COM tgt = xs.target_num; 74710743SDavid.Hollister@Sun.COM } 74810743SDavid.Hollister@Sun.COM } 74910743SDavid.Hollister@Sun.COM if (wp->phy) { 75010743SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), wp->phy) == -1) { 75110743SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, wp->phy); 75210743SDavid.Hollister@Sun.COM } 75310743SDavid.Hollister@Sun.COM path = phy.path; 75410743SDavid.Hollister@Sun.COM } else { 75510743SDavid.Hollister@Sun.COM path = "N/A"; 75610743SDavid.Hollister@Sun.COM } 75710743SDavid.Hollister@Sun.COM 75810743SDavid.Hollister@Sun.COM if (verbose) { 75910743SDavid.Hollister@Sun.COM mdb_printf("%4d ", idx); 76010743SDavid.Hollister@Sun.COM } 76110743SDavid.Hollister@Sun.COM if (tgt == -1) { 76210743SDavid.Hollister@Sun.COM mdb_printf("%08x %10s %20s N/A %8u %1d %1d ", 76310743SDavid.Hollister@Sun.COM wp->htag, state, path, wp->timer, 76410743SDavid.Hollister@Sun.COM wp->onwire, wp->dead); 76510743SDavid.Hollister@Sun.COM } else { 76610743SDavid.Hollister@Sun.COM mdb_printf("%08x %10s %20s %8d %8u %1d %1d ", 76710743SDavid.Hollister@Sun.COM wp->htag, state, path, tgt, wp->timer, 76810743SDavid.Hollister@Sun.COM wp->onwire, wp->dead); 76910743SDavid.Hollister@Sun.COM } 77010743SDavid.Hollister@Sun.COM if (verbose) { 77111601SDavid.Hollister@Sun.COM mdb_printf("%08x %10s 0x%016p 0x%016p 0x%016p\n", 77211601SDavid.Hollister@Sun.COM wp->last_htag, last_state, wp->last_phy, wp->last_xp, 77311601SDavid.Hollister@Sun.COM wp->last_arg); 77410743SDavid.Hollister@Sun.COM } else { 77510743SDavid.Hollister@Sun.COM mdb_printf("\n"); 77610743SDavid.Hollister@Sun.COM } 77710743SDavid.Hollister@Sun.COM } 77810743SDavid.Hollister@Sun.COM 77910696SDavid.Hollister@Sun.COM static void 78010696SDavid.Hollister@Sun.COM display_work(struct pmcs_hw m, int verbose) 78110696SDavid.Hollister@Sun.COM { 78210696SDavid.Hollister@Sun.COM int idx; 78310743SDavid.Hollister@Sun.COM boolean_t header_printed = B_FALSE; 78410696SDavid.Hollister@Sun.COM pmcwork_t work, *wp = &work; 78510696SDavid.Hollister@Sun.COM uintptr_t _wp; 78610696SDavid.Hollister@Sun.COM 78710696SDavid.Hollister@Sun.COM mdb_printf("\nActive Work structure information:\n"); 78810696SDavid.Hollister@Sun.COM mdb_printf("----------------------------------\n"); 78910696SDavid.Hollister@Sun.COM 79010696SDavid.Hollister@Sun.COM _wp = (uintptr_t)m.work; 79110696SDavid.Hollister@Sun.COM 79210696SDavid.Hollister@Sun.COM for (idx = 0; idx < m.max_cmd; idx++, _wp += sizeof (pmcwork_t)) { 79310696SDavid.Hollister@Sun.COM if (MDB_RD(&work, sizeof (pmcwork_t), _wp) == -1) { 79410696SDavid.Hollister@Sun.COM NOREAD(pmcwork_t, _wp); 79510696SDavid.Hollister@Sun.COM continue; 79610696SDavid.Hollister@Sun.COM } 79710743SDavid.Hollister@Sun.COM 79810743SDavid.Hollister@Sun.COM if (!verbose && (wp->htag == PMCS_TAG_TYPE_FREE)) { 79910696SDavid.Hollister@Sun.COM continue; 80010696SDavid.Hollister@Sun.COM } 80110743SDavid.Hollister@Sun.COM 80210743SDavid.Hollister@Sun.COM if (header_printed == B_FALSE) { 80310743SDavid.Hollister@Sun.COM if (verbose) { 80410743SDavid.Hollister@Sun.COM mdb_printf("%4s ", "Idx"); 80510743SDavid.Hollister@Sun.COM } 80610743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D ", 80710696SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 80810743SDavid.Hollister@Sun.COM if (verbose) { 80911601SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %18s %18s %18s\n", 81011601SDavid.Hollister@Sun.COM "LastHTAG", "LastState", "LastPHY", 81111601SDavid.Hollister@Sun.COM "LastTgt", "LastArg"); 81210743SDavid.Hollister@Sun.COM } else { 81310743SDavid.Hollister@Sun.COM mdb_printf("\n"); 81410743SDavid.Hollister@Sun.COM } 81510743SDavid.Hollister@Sun.COM header_printed = B_TRUE; 81610696SDavid.Hollister@Sun.COM } 81710743SDavid.Hollister@Sun.COM 81810743SDavid.Hollister@Sun.COM display_one_work(wp, verbose, idx); 81910696SDavid.Hollister@Sun.COM } 82010696SDavid.Hollister@Sun.COM } 82110696SDavid.Hollister@Sun.COM 82210696SDavid.Hollister@Sun.COM static void 82310743SDavid.Hollister@Sun.COM print_spcmd(pmcs_cmd_t *sp, void *kaddr, int printhdr, int verbose) 82410696SDavid.Hollister@Sun.COM { 82510743SDavid.Hollister@Sun.COM int cdb_size, idx; 82610743SDavid.Hollister@Sun.COM struct scsi_pkt pkt; 82710743SDavid.Hollister@Sun.COM uchar_t cdb[256]; 82810743SDavid.Hollister@Sun.COM 82910696SDavid.Hollister@Sun.COM if (printhdr) { 83010743SDavid.Hollister@Sun.COM if (verbose) { 83110743SDavid.Hollister@Sun.COM mdb_printf("%16s %16s %16s %8s %s CDB\n", "Command", 83210743SDavid.Hollister@Sun.COM "SCSA pkt", "DMA Chunks", "HTAG", "SATL Tag"); 83310743SDavid.Hollister@Sun.COM } else { 83410743SDavid.Hollister@Sun.COM mdb_printf("%16s %16s %16s %8s %s\n", "Command", 83510743SDavid.Hollister@Sun.COM "SCSA pkt", "DMA Chunks", "HTAG", "SATL Tag"); 83610743SDavid.Hollister@Sun.COM } 83710696SDavid.Hollister@Sun.COM } 83810743SDavid.Hollister@Sun.COM 83910743SDavid.Hollister@Sun.COM mdb_printf("%16p %16p %16p %08x %08x ", 84010696SDavid.Hollister@Sun.COM kaddr, sp->cmd_pkt, sp->cmd_clist, sp->cmd_tag, sp->cmd_satltag); 84110743SDavid.Hollister@Sun.COM 84210743SDavid.Hollister@Sun.COM /* 84310743SDavid.Hollister@Sun.COM * If we're printing verbose, dump the CDB as well. 84410743SDavid.Hollister@Sun.COM */ 84510743SDavid.Hollister@Sun.COM if (verbose) { 84610743SDavid.Hollister@Sun.COM if (sp->cmd_pkt) { 84710743SDavid.Hollister@Sun.COM if (mdb_vread(&pkt, sizeof (struct scsi_pkt), 84810743SDavid.Hollister@Sun.COM (uintptr_t)sp->cmd_pkt) != 84910743SDavid.Hollister@Sun.COM sizeof (struct scsi_pkt)) { 85010743SDavid.Hollister@Sun.COM mdb_warn("Unable to read SCSI pkt\n"); 85110743SDavid.Hollister@Sun.COM return; 85210743SDavid.Hollister@Sun.COM } 85310743SDavid.Hollister@Sun.COM cdb_size = pkt.pkt_cdblen; 85410743SDavid.Hollister@Sun.COM if (mdb_vread(&cdb[0], cdb_size, 85510743SDavid.Hollister@Sun.COM (uintptr_t)pkt.pkt_cdbp) != cdb_size) { 85610743SDavid.Hollister@Sun.COM mdb_warn("Unable to read CDB\n"); 85710743SDavid.Hollister@Sun.COM return; 85810743SDavid.Hollister@Sun.COM } 85910743SDavid.Hollister@Sun.COM 86010743SDavid.Hollister@Sun.COM for (idx = 0; idx < cdb_size; idx++) { 86110743SDavid.Hollister@Sun.COM mdb_printf("%02x ", cdb[idx]); 86210743SDavid.Hollister@Sun.COM } 86310743SDavid.Hollister@Sun.COM } else { 86410743SDavid.Hollister@Sun.COM mdb_printf("N/A"); 86510743SDavid.Hollister@Sun.COM } 86610743SDavid.Hollister@Sun.COM 86710743SDavid.Hollister@Sun.COM mdb_printf("\n"); 86810743SDavid.Hollister@Sun.COM } else { 86910743SDavid.Hollister@Sun.COM mdb_printf("\n"); 87010743SDavid.Hollister@Sun.COM } 87110696SDavid.Hollister@Sun.COM } 87210696SDavid.Hollister@Sun.COM 87310696SDavid.Hollister@Sun.COM /*ARGSUSED1*/ 87410696SDavid.Hollister@Sun.COM static void 87510696SDavid.Hollister@Sun.COM display_waitqs(struct pmcs_hw m, int verbose) 87610696SDavid.Hollister@Sun.COM { 87710696SDavid.Hollister@Sun.COM pmcs_cmd_t *sp, s; 87810696SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 87910696SDavid.Hollister@Sun.COM int first, i; 88010696SDavid.Hollister@Sun.COM int max_dev = m.max_dev; 88110696SDavid.Hollister@Sun.COM 88210696SDavid.Hollister@Sun.COM sp = m.dq.stqh_first; 88310696SDavid.Hollister@Sun.COM first = 1; 88410696SDavid.Hollister@Sun.COM while (sp) { 88510696SDavid.Hollister@Sun.COM if (first) { 88610696SDavid.Hollister@Sun.COM mdb_printf("\nDead Command Queue:\n"); 88710696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 88810696SDavid.Hollister@Sun.COM } 88910696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 89010696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 89110696SDavid.Hollister@Sun.COM break; 89210696SDavid.Hollister@Sun.COM } 89310743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 89410696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 89510696SDavid.Hollister@Sun.COM first = 0; 89610696SDavid.Hollister@Sun.COM } 89710696SDavid.Hollister@Sun.COM 89810696SDavid.Hollister@Sun.COM sp = m.cq.stqh_first; 89910696SDavid.Hollister@Sun.COM first = 1; 90010696SDavid.Hollister@Sun.COM while (sp) { 90110696SDavid.Hollister@Sun.COM if (first) { 90210696SDavid.Hollister@Sun.COM mdb_printf("\nCompletion Command Queue:\n"); 90310696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 90410696SDavid.Hollister@Sun.COM } 90510696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 90610696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 90710696SDavid.Hollister@Sun.COM break; 90810696SDavid.Hollister@Sun.COM } 90910743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 91010696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 91110696SDavid.Hollister@Sun.COM first = 0; 91210696SDavid.Hollister@Sun.COM } 91310696SDavid.Hollister@Sun.COM 91410696SDavid.Hollister@Sun.COM 91510696SDavid.Hollister@Sun.COM if (targets == NULL) { 91610696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * max_dev, UM_SLEEP); 91710696SDavid.Hollister@Sun.COM } 91810696SDavid.Hollister@Sun.COM 91910696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * max_dev, m.targets) == -1) { 92010696SDavid.Hollister@Sun.COM NOREAD(targets, m.targets); 92110696SDavid.Hollister@Sun.COM return; 92210696SDavid.Hollister@Sun.COM } 92310696SDavid.Hollister@Sun.COM 92410696SDavid.Hollister@Sun.COM for (i = 0; i < max_dev; i++) { 92510696SDavid.Hollister@Sun.COM if (targets[i] == NULL) { 92610696SDavid.Hollister@Sun.COM continue; 92710696SDavid.Hollister@Sun.COM } 92810696SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), targets[i]) == -1) { 92910696SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, targets[i]); 93010696SDavid.Hollister@Sun.COM continue; 93110696SDavid.Hollister@Sun.COM } 93210696SDavid.Hollister@Sun.COM sp = xs.wq.stqh_first; 93310696SDavid.Hollister@Sun.COM first = 1; 93410696SDavid.Hollister@Sun.COM while (sp) { 93510696SDavid.Hollister@Sun.COM if (first) { 93610696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Wait Queue:\n", 93710696SDavid.Hollister@Sun.COM xs.target_num); 93810696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 93910696SDavid.Hollister@Sun.COM } 94010696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 94110696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 94210696SDavid.Hollister@Sun.COM break; 94310696SDavid.Hollister@Sun.COM } 94410743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 94510696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 94610696SDavid.Hollister@Sun.COM first = 0; 94710696SDavid.Hollister@Sun.COM } 94810696SDavid.Hollister@Sun.COM sp = xs.aq.stqh_first; 94910696SDavid.Hollister@Sun.COM first = 1; 95010696SDavid.Hollister@Sun.COM while (sp) { 95110696SDavid.Hollister@Sun.COM if (first) { 95210696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Active Queue:\n", 95310696SDavid.Hollister@Sun.COM xs.target_num); 95410696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 95510696SDavid.Hollister@Sun.COM } 95610696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 95710696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 95810696SDavid.Hollister@Sun.COM break; 95910696SDavid.Hollister@Sun.COM } 96010743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 96110696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 96210696SDavid.Hollister@Sun.COM first = 0; 96310696SDavid.Hollister@Sun.COM } 96410696SDavid.Hollister@Sun.COM sp = xs.sq.stqh_first; 96510696SDavid.Hollister@Sun.COM first = 1; 96610696SDavid.Hollister@Sun.COM while (sp) { 96710696SDavid.Hollister@Sun.COM if (first) { 96810696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Special Queue:\n", 96910696SDavid.Hollister@Sun.COM xs.target_num); 97010696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 97110696SDavid.Hollister@Sun.COM } 97210696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 97310696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 97410696SDavid.Hollister@Sun.COM break; 97510696SDavid.Hollister@Sun.COM } 97610743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 97710696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 97810696SDavid.Hollister@Sun.COM first = 0; 97910696SDavid.Hollister@Sun.COM } 98010696SDavid.Hollister@Sun.COM } 98110696SDavid.Hollister@Sun.COM } 98210696SDavid.Hollister@Sun.COM 98310696SDavid.Hollister@Sun.COM static char * 98410696SDavid.Hollister@Sun.COM ibq_type(int qnum) 98510696SDavid.Hollister@Sun.COM { 98610696SDavid.Hollister@Sun.COM if (qnum < 0 || qnum >= PMCS_NIQ) { 98710696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 98810696SDavid.Hollister@Sun.COM } 98910696SDavid.Hollister@Sun.COM 99010696SDavid.Hollister@Sun.COM if (qnum < PMCS_IQ_OTHER) { 99110696SDavid.Hollister@Sun.COM return ("I/O"); 99210696SDavid.Hollister@Sun.COM } 99310696SDavid.Hollister@Sun.COM 99410696SDavid.Hollister@Sun.COM return ("Other"); 99510696SDavid.Hollister@Sun.COM } 99610696SDavid.Hollister@Sun.COM 99710696SDavid.Hollister@Sun.COM static char * 99810696SDavid.Hollister@Sun.COM obq_type(int qnum) 99910696SDavid.Hollister@Sun.COM { 100010696SDavid.Hollister@Sun.COM switch (qnum) { 100110696SDavid.Hollister@Sun.COM case PMCS_OQ_IODONE: 100210696SDavid.Hollister@Sun.COM return ("I/O"); 100310696SDavid.Hollister@Sun.COM break; 100410696SDavid.Hollister@Sun.COM case PMCS_OQ_GENERAL: 100510696SDavid.Hollister@Sun.COM return ("General"); 100610696SDavid.Hollister@Sun.COM break; 100710696SDavid.Hollister@Sun.COM case PMCS_OQ_EVENTS: 100810696SDavid.Hollister@Sun.COM return ("Events"); 100910696SDavid.Hollister@Sun.COM break; 101010696SDavid.Hollister@Sun.COM default: 101110696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 101210696SDavid.Hollister@Sun.COM } 101310696SDavid.Hollister@Sun.COM } 101410696SDavid.Hollister@Sun.COM 101510696SDavid.Hollister@Sun.COM static char * 101610696SDavid.Hollister@Sun.COM iomb_cat(uint32_t cat) 101710696SDavid.Hollister@Sun.COM { 101810696SDavid.Hollister@Sun.COM switch (cat) { 101910696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_NET: 102010696SDavid.Hollister@Sun.COM return ("NET"); 102110696SDavid.Hollister@Sun.COM break; 102210696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_FC: 102310696SDavid.Hollister@Sun.COM return ("FC"); 102410696SDavid.Hollister@Sun.COM break; 102510696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_SAS: 102610696SDavid.Hollister@Sun.COM return ("SAS"); 102710696SDavid.Hollister@Sun.COM break; 102810696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_SCSI: 102910696SDavid.Hollister@Sun.COM return ("SCSI"); 103010696SDavid.Hollister@Sun.COM break; 103110696SDavid.Hollister@Sun.COM default: 103210696SDavid.Hollister@Sun.COM return ("???"); 103310696SDavid.Hollister@Sun.COM } 103410696SDavid.Hollister@Sun.COM } 103510696SDavid.Hollister@Sun.COM 103610696SDavid.Hollister@Sun.COM static char * 103711601SDavid.Hollister@Sun.COM iomb_event(uint8_t event) 103811601SDavid.Hollister@Sun.COM { 103911601SDavid.Hollister@Sun.COM switch (event) { 104011601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_STOP_STATUS: 104111601SDavid.Hollister@Sun.COM return ("PHY STOP"); 104211601SDavid.Hollister@Sun.COM break; 104311601SDavid.Hollister@Sun.COM case IOP_EVENT_SAS_PHY_UP: 104411601SDavid.Hollister@Sun.COM return ("PHY UP"); 104511601SDavid.Hollister@Sun.COM break; 104611601SDavid.Hollister@Sun.COM case IOP_EVENT_SATA_PHY_UP: 104711601SDavid.Hollister@Sun.COM return ("SATA PHY UP"); 104811601SDavid.Hollister@Sun.COM break; 104911601SDavid.Hollister@Sun.COM case IOP_EVENT_SATA_SPINUP_HOLD: 105011601SDavid.Hollister@Sun.COM return ("SATA SPINUP HOLD"); 105111601SDavid.Hollister@Sun.COM break; 105211601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_DOWN: 105311601SDavid.Hollister@Sun.COM return ("PHY DOWN"); 105411601SDavid.Hollister@Sun.COM break; 105511601SDavid.Hollister@Sun.COM case IOP_EVENT_BROADCAST_CHANGE: 105611601SDavid.Hollister@Sun.COM return ("BROADCAST CHANGE"); 105711601SDavid.Hollister@Sun.COM break; 105811601SDavid.Hollister@Sun.COM case IOP_EVENT_BROADCAST_SES: 105911601SDavid.Hollister@Sun.COM return ("BROADCAST SES"); 106011601SDavid.Hollister@Sun.COM break; 106111601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_INBOUND_CRC: 106211601SDavid.Hollister@Sun.COM return ("INBOUND CRC ERROR"); 106311601SDavid.Hollister@Sun.COM break; 106411601SDavid.Hollister@Sun.COM case IOP_EVENT_HARD_RESET_RECEIVED: 106511601SDavid.Hollister@Sun.COM return ("HARD RESET"); 106611601SDavid.Hollister@Sun.COM break; 106711601SDavid.Hollister@Sun.COM case IOP_EVENT_EVENT_ID_FRAME_TIMO: 106811601SDavid.Hollister@Sun.COM return ("IDENTIFY FRAME TIMEOUT"); 106911601SDavid.Hollister@Sun.COM break; 107011601SDavid.Hollister@Sun.COM case IOP_EVENT_BROADCAST_EXP: 107111601SDavid.Hollister@Sun.COM return ("BROADCAST EXPANDER"); 107211601SDavid.Hollister@Sun.COM break; 107311601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_START_STATUS: 107411601SDavid.Hollister@Sun.COM return ("PHY START"); 107511601SDavid.Hollister@Sun.COM break; 107611601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_INVALID_DWORD: 107711601SDavid.Hollister@Sun.COM return ("INVALID DWORD"); 107811601SDavid.Hollister@Sun.COM break; 107911601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_DISPARITY_ERROR: 108011601SDavid.Hollister@Sun.COM return ("DISPARITY ERROR"); 108111601SDavid.Hollister@Sun.COM break; 108211601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_CODE_VIOLATION: 108311601SDavid.Hollister@Sun.COM return ("CODE VIOLATION"); 108411601SDavid.Hollister@Sun.COM break; 108511601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_LOSS_OF_DWORD_SYN: 108611601SDavid.Hollister@Sun.COM return ("LOSS OF DWORD SYNC"); 108711601SDavid.Hollister@Sun.COM break; 108811601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_PHY_RESET_FAILD: 108911601SDavid.Hollister@Sun.COM return ("PHY RESET FAILED"); 109011601SDavid.Hollister@Sun.COM break; 109111601SDavid.Hollister@Sun.COM case IOP_EVENT_PORT_RECOVERY_TIMER_TMO: 109211601SDavid.Hollister@Sun.COM return ("PORT RECOVERY TIMEOUT"); 109311601SDavid.Hollister@Sun.COM break; 109411601SDavid.Hollister@Sun.COM case IOP_EVENT_PORT_RECOVER: 109511601SDavid.Hollister@Sun.COM return ("PORT RECOVERY"); 109611601SDavid.Hollister@Sun.COM break; 109711601SDavid.Hollister@Sun.COM case IOP_EVENT_PORT_RESET_TIMER_TMO: 109811601SDavid.Hollister@Sun.COM return ("PORT RESET TIMEOUT"); 109911601SDavid.Hollister@Sun.COM break; 110011601SDavid.Hollister@Sun.COM case IOP_EVENT_PORT_RESET_COMPLETE: 110111601SDavid.Hollister@Sun.COM return ("PORT RESET COMPLETE"); 110211601SDavid.Hollister@Sun.COM break; 110311601SDavid.Hollister@Sun.COM case IOP_EVENT_BROADCAST_ASYNC_EVENT: 110411601SDavid.Hollister@Sun.COM return ("BROADCAST ASYNC"); 110511601SDavid.Hollister@Sun.COM break; 110611601SDavid.Hollister@Sun.COM case IOP_EVENT_IT_NEXUS_LOSS: 110711601SDavid.Hollister@Sun.COM return ("I/T NEXUS LOSS"); 110811601SDavid.Hollister@Sun.COM break; 110911601SDavid.Hollister@Sun.COM default: 111011601SDavid.Hollister@Sun.COM return ("Unknown Event"); 111111601SDavid.Hollister@Sun.COM } 111211601SDavid.Hollister@Sun.COM } 111311601SDavid.Hollister@Sun.COM 111411601SDavid.Hollister@Sun.COM static char * 111510696SDavid.Hollister@Sun.COM inbound_iomb_opcode(uint32_t opcode) 111610696SDavid.Hollister@Sun.COM { 111710696SDavid.Hollister@Sun.COM switch (opcode) { 111810696SDavid.Hollister@Sun.COM case PMCIN_ECHO: 111910696SDavid.Hollister@Sun.COM return ("ECHO"); 112010696SDavid.Hollister@Sun.COM break; 112110696SDavid.Hollister@Sun.COM case PMCIN_GET_INFO: 112210696SDavid.Hollister@Sun.COM return ("GET_INFO"); 112310696SDavid.Hollister@Sun.COM break; 112410696SDavid.Hollister@Sun.COM case PMCIN_GET_VPD: 112510696SDavid.Hollister@Sun.COM return ("GET_VPD"); 112610696SDavid.Hollister@Sun.COM break; 112710696SDavid.Hollister@Sun.COM case PMCIN_PHY_START: 112810696SDavid.Hollister@Sun.COM return ("PHY_START"); 112910696SDavid.Hollister@Sun.COM break; 113010696SDavid.Hollister@Sun.COM case PMCIN_PHY_STOP: 113110696SDavid.Hollister@Sun.COM return ("PHY_STOP"); 113210696SDavid.Hollister@Sun.COM break; 113310696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_IO_START: 113410696SDavid.Hollister@Sun.COM return ("INI_IO_START"); 113510696SDavid.Hollister@Sun.COM break; 113610696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_TM_START: 113710696SDavid.Hollister@Sun.COM return ("INI_TM_START"); 113810696SDavid.Hollister@Sun.COM break; 113910696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EXT_IO_START: 114010696SDavid.Hollister@Sun.COM return ("INI_EXT_IO_START"); 114110696SDavid.Hollister@Sun.COM break; 114210696SDavid.Hollister@Sun.COM case PMCIN_DEVICE_HANDLE_ACCEPT: 114310696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_ACCEPT"); 114410696SDavid.Hollister@Sun.COM break; 114510696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_IO_START: 114610696SDavid.Hollister@Sun.COM return ("TGT_IO_START"); 114710696SDavid.Hollister@Sun.COM break; 114810696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_RESPONSE_START: 114910696SDavid.Hollister@Sun.COM return ("TGT_RESPONSE_START"); 115010696SDavid.Hollister@Sun.COM break; 115110696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EDC_EXT_IO_START: 115210696SDavid.Hollister@Sun.COM return ("INI_EDC_EXT_IO_START"); 115310696SDavid.Hollister@Sun.COM break; 115410696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EDC_EXT_IO_START1: 115510696SDavid.Hollister@Sun.COM return ("INI_EDC_EXT_IO_START1"); 115610696SDavid.Hollister@Sun.COM break; 115710696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_EDC_IO_START: 115810696SDavid.Hollister@Sun.COM return ("TGT_EDC_IO_START"); 115910696SDavid.Hollister@Sun.COM break; 116010696SDavid.Hollister@Sun.COM case PMCIN_SSP_ABORT: 116110696SDavid.Hollister@Sun.COM return ("SSP_ABORT"); 116210696SDavid.Hollister@Sun.COM break; 116310696SDavid.Hollister@Sun.COM case PMCIN_DEREGISTER_DEVICE_HANDLE: 116410696SDavid.Hollister@Sun.COM return ("DEREGISTER_DEVICE_HANDLE"); 116510696SDavid.Hollister@Sun.COM break; 116610696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_HANDLE: 116710696SDavid.Hollister@Sun.COM return ("GET_DEVICE_HANDLE"); 116810696SDavid.Hollister@Sun.COM break; 116910696SDavid.Hollister@Sun.COM case PMCIN_SMP_REQUEST: 117010696SDavid.Hollister@Sun.COM return ("SMP_REQUEST"); 117110696SDavid.Hollister@Sun.COM break; 117210696SDavid.Hollister@Sun.COM case PMCIN_SMP_RESPONSE: 117310696SDavid.Hollister@Sun.COM return ("SMP_RESPONSE"); 117410696SDavid.Hollister@Sun.COM break; 117510696SDavid.Hollister@Sun.COM case PMCIN_SMP_ABORT: 117610696SDavid.Hollister@Sun.COM return ("SMP_ABORT"); 117710696SDavid.Hollister@Sun.COM break; 117810696SDavid.Hollister@Sun.COM case PMCIN_ASSISTED_DISCOVERY: 117910696SDavid.Hollister@Sun.COM return ("ASSISTED_DISCOVERY"); 118010696SDavid.Hollister@Sun.COM break; 118110696SDavid.Hollister@Sun.COM case PMCIN_REGISTER_DEVICE: 118210696SDavid.Hollister@Sun.COM return ("REGISTER_DEVICE"); 118310696SDavid.Hollister@Sun.COM break; 118410696SDavid.Hollister@Sun.COM case PMCIN_SATA_HOST_IO_START: 118510696SDavid.Hollister@Sun.COM return ("SATA_HOST_IO_START"); 118610696SDavid.Hollister@Sun.COM break; 118710696SDavid.Hollister@Sun.COM case PMCIN_SATA_ABORT: 118810696SDavid.Hollister@Sun.COM return ("SATA_ABORT"); 118910696SDavid.Hollister@Sun.COM break; 119010696SDavid.Hollister@Sun.COM case PMCIN_LOCAL_PHY_CONTROL: 119110696SDavid.Hollister@Sun.COM return ("LOCAL_PHY_CONTROL"); 119210696SDavid.Hollister@Sun.COM break; 119310696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_INFO: 119410696SDavid.Hollister@Sun.COM return ("GET_DEVICE_INFO"); 119510696SDavid.Hollister@Sun.COM break; 119610696SDavid.Hollister@Sun.COM case PMCIN_TWI: 119710696SDavid.Hollister@Sun.COM return ("TWI"); 119810696SDavid.Hollister@Sun.COM break; 119910696SDavid.Hollister@Sun.COM case PMCIN_FW_FLASH_UPDATE: 120010696SDavid.Hollister@Sun.COM return ("FW_FLASH_UPDATE"); 120110696SDavid.Hollister@Sun.COM break; 120210696SDavid.Hollister@Sun.COM case PMCIN_SET_VPD: 120310696SDavid.Hollister@Sun.COM return ("SET_VPD"); 120410696SDavid.Hollister@Sun.COM break; 120510696SDavid.Hollister@Sun.COM case PMCIN_GPIO: 120610696SDavid.Hollister@Sun.COM return ("GPIO"); 120710696SDavid.Hollister@Sun.COM break; 120810696SDavid.Hollister@Sun.COM case PMCIN_SAS_DIAG_MODE_START_END: 120910696SDavid.Hollister@Sun.COM return ("SAS_DIAG_MODE_START_END"); 121010696SDavid.Hollister@Sun.COM break; 121110696SDavid.Hollister@Sun.COM case PMCIN_SAS_DIAG_EXECUTE: 121210696SDavid.Hollister@Sun.COM return ("SAS_DIAG_EXECUTE"); 121310696SDavid.Hollister@Sun.COM break; 121410696SDavid.Hollister@Sun.COM case PMCIN_SAW_HW_EVENT_ACK: 121510696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT_ACK"); 121610696SDavid.Hollister@Sun.COM break; 121710696SDavid.Hollister@Sun.COM case PMCIN_GET_TIME_STAMP: 121810696SDavid.Hollister@Sun.COM return ("GET_TIME_STAMP"); 121910696SDavid.Hollister@Sun.COM break; 122010696SDavid.Hollister@Sun.COM case PMCIN_PORT_CONTROL: 122110696SDavid.Hollister@Sun.COM return ("PORT_CONTROL"); 122210696SDavid.Hollister@Sun.COM break; 122310696SDavid.Hollister@Sun.COM case PMCIN_GET_NVMD_DATA: 122410696SDavid.Hollister@Sun.COM return ("GET_NVMD_DATA"); 122510696SDavid.Hollister@Sun.COM break; 122610696SDavid.Hollister@Sun.COM case PMCIN_SET_NVMD_DATA: 122710696SDavid.Hollister@Sun.COM return ("SET_NVMD_DATA"); 122810696SDavid.Hollister@Sun.COM break; 122910696SDavid.Hollister@Sun.COM case PMCIN_SET_DEVICE_STATE: 123010696SDavid.Hollister@Sun.COM return ("SET_DEVICE_STATE"); 123110696SDavid.Hollister@Sun.COM break; 123210696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_STATE: 123310696SDavid.Hollister@Sun.COM return ("GET_DEVICE_STATE"); 123410696SDavid.Hollister@Sun.COM break; 123510696SDavid.Hollister@Sun.COM default: 123610696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 123710696SDavid.Hollister@Sun.COM break; 123810696SDavid.Hollister@Sun.COM } 123910696SDavid.Hollister@Sun.COM } 124010696SDavid.Hollister@Sun.COM 124110696SDavid.Hollister@Sun.COM static char * 124210696SDavid.Hollister@Sun.COM outbound_iomb_opcode(uint32_t opcode) 124310696SDavid.Hollister@Sun.COM { 124410696SDavid.Hollister@Sun.COM switch (opcode) { 124510696SDavid.Hollister@Sun.COM case PMCOUT_ECHO: 124610696SDavid.Hollister@Sun.COM return ("ECHO"); 124710696SDavid.Hollister@Sun.COM break; 124810696SDavid.Hollister@Sun.COM case PMCOUT_GET_INFO: 124910696SDavid.Hollister@Sun.COM return ("GET_INFO"); 125010696SDavid.Hollister@Sun.COM break; 125110696SDavid.Hollister@Sun.COM case PMCOUT_GET_VPD: 125210696SDavid.Hollister@Sun.COM return ("GET_VPD"); 125310696SDavid.Hollister@Sun.COM break; 125410696SDavid.Hollister@Sun.COM case PMCOUT_SAS_HW_EVENT: 125510696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT"); 125610696SDavid.Hollister@Sun.COM break; 125710696SDavid.Hollister@Sun.COM case PMCOUT_SSP_COMPLETION: 125810696SDavid.Hollister@Sun.COM return ("SSP_COMPLETION"); 125910696SDavid.Hollister@Sun.COM break; 126010696SDavid.Hollister@Sun.COM case PMCOUT_SMP_COMPLETION: 126110696SDavid.Hollister@Sun.COM return ("SMP_COMPLETION"); 126210696SDavid.Hollister@Sun.COM break; 126310696SDavid.Hollister@Sun.COM case PMCOUT_LOCAL_PHY_CONTROL: 126410696SDavid.Hollister@Sun.COM return ("LOCAL_PHY_CONTROL"); 126510696SDavid.Hollister@Sun.COM break; 126610696SDavid.Hollister@Sun.COM case PMCOUT_SAS_ASSISTED_DISCOVERY_EVENT: 126710696SDavid.Hollister@Sun.COM return ("SAS_ASSISTED_DISCOVERY_SENT"); 126810696SDavid.Hollister@Sun.COM break; 126910696SDavid.Hollister@Sun.COM case PMCOUT_SATA_ASSISTED_DISCOVERY_EVENT: 127010696SDavid.Hollister@Sun.COM return ("SATA_ASSISTED_DISCOVERY_SENT"); 127110696SDavid.Hollister@Sun.COM break; 127210696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_REGISTRATION: 127310696SDavid.Hollister@Sun.COM return ("DEVICE_REGISTRATION"); 127410696SDavid.Hollister@Sun.COM break; 127510696SDavid.Hollister@Sun.COM case PMCOUT_DEREGISTER_DEVICE_HANDLE: 127610696SDavid.Hollister@Sun.COM return ("DEREGISTER_DEVICE_HANDLE"); 127710696SDavid.Hollister@Sun.COM break; 127810696SDavid.Hollister@Sun.COM case PMCOUT_GET_DEVICE_HANDLE: 127910696SDavid.Hollister@Sun.COM return ("GET_DEVICE_HANDLE"); 128010696SDavid.Hollister@Sun.COM break; 128110696SDavid.Hollister@Sun.COM case PMCOUT_SATA_COMPLETION: 128210696SDavid.Hollister@Sun.COM return ("SATA_COMPLETION"); 128310696SDavid.Hollister@Sun.COM break; 128410696SDavid.Hollister@Sun.COM case PMCOUT_SATA_EVENT: 128510696SDavid.Hollister@Sun.COM return ("SATA_EVENT"); 128610696SDavid.Hollister@Sun.COM break; 128710696SDavid.Hollister@Sun.COM case PMCOUT_SSP_EVENT: 128810696SDavid.Hollister@Sun.COM return ("SSP_EVENT"); 128910696SDavid.Hollister@Sun.COM break; 129010696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_HANDLE_ARRIVED: 129110696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_ARRIVED"); 129210696SDavid.Hollister@Sun.COM break; 129310696SDavid.Hollister@Sun.COM case PMCOUT_SMP_REQUEST_RECEIVED: 129410696SDavid.Hollister@Sun.COM return ("SMP_REQUEST_RECEIVED"); 129510696SDavid.Hollister@Sun.COM break; 129610696SDavid.Hollister@Sun.COM case PMCOUT_SSP_REQUEST_RECEIVED: 129710696SDavid.Hollister@Sun.COM return ("SSP_REQUEST_RECEIVED"); 129810696SDavid.Hollister@Sun.COM break; 129910696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_INFO: 130010696SDavid.Hollister@Sun.COM return ("DEVICE_INFO"); 130110696SDavid.Hollister@Sun.COM break; 130210696SDavid.Hollister@Sun.COM case PMCOUT_FW_FLASH_UPDATE: 130310696SDavid.Hollister@Sun.COM return ("FW_FLASH_UPDATE"); 130410696SDavid.Hollister@Sun.COM break; 130510696SDavid.Hollister@Sun.COM case PMCOUT_SET_VPD: 130610696SDavid.Hollister@Sun.COM return ("SET_VPD"); 130710696SDavid.Hollister@Sun.COM break; 130810696SDavid.Hollister@Sun.COM case PMCOUT_GPIO: 130910696SDavid.Hollister@Sun.COM return ("GPIO"); 131010696SDavid.Hollister@Sun.COM break; 131110696SDavid.Hollister@Sun.COM case PMCOUT_GPIO_EVENT: 131210696SDavid.Hollister@Sun.COM return ("GPIO_EVENT"); 131310696SDavid.Hollister@Sun.COM break; 131410696SDavid.Hollister@Sun.COM case PMCOUT_GENERAL_EVENT: 131510696SDavid.Hollister@Sun.COM return ("GENERAL_EVENT"); 131610696SDavid.Hollister@Sun.COM break; 131710696SDavid.Hollister@Sun.COM case PMCOUT_TWI: 131810696SDavid.Hollister@Sun.COM return ("TWI"); 131910696SDavid.Hollister@Sun.COM break; 132010696SDavid.Hollister@Sun.COM case PMCOUT_SSP_ABORT: 132110696SDavid.Hollister@Sun.COM return ("SSP_ABORT"); 132210696SDavid.Hollister@Sun.COM break; 132310696SDavid.Hollister@Sun.COM case PMCOUT_SATA_ABORT: 132410696SDavid.Hollister@Sun.COM return ("SATA_ABORT"); 132510696SDavid.Hollister@Sun.COM break; 132610696SDavid.Hollister@Sun.COM case PMCOUT_SAS_DIAG_MODE_START_END: 132710696SDavid.Hollister@Sun.COM return ("SAS_DIAG_MODE_START_END"); 132810696SDavid.Hollister@Sun.COM break; 132910696SDavid.Hollister@Sun.COM case PMCOUT_SAS_DIAG_EXECUTE: 133010696SDavid.Hollister@Sun.COM return ("SAS_DIAG_EXECUTE"); 133110696SDavid.Hollister@Sun.COM break; 133210696SDavid.Hollister@Sun.COM case PMCOUT_GET_TIME_STAMP: 133310696SDavid.Hollister@Sun.COM return ("GET_TIME_STAMP"); 133410696SDavid.Hollister@Sun.COM break; 133510696SDavid.Hollister@Sun.COM case PMCOUT_SAS_HW_EVENT_ACK_ACK: 133610696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT_ACK_ACK"); 133710696SDavid.Hollister@Sun.COM break; 133810696SDavid.Hollister@Sun.COM case PMCOUT_PORT_CONTROL: 133910696SDavid.Hollister@Sun.COM return ("PORT_CONTROL"); 134010696SDavid.Hollister@Sun.COM break; 134110696SDavid.Hollister@Sun.COM case PMCOUT_SKIP_ENTRIES: 134210696SDavid.Hollister@Sun.COM return ("SKIP_ENTRIES"); 134310696SDavid.Hollister@Sun.COM break; 134410696SDavid.Hollister@Sun.COM case PMCOUT_SMP_ABORT: 134510696SDavid.Hollister@Sun.COM return ("SMP_ABORT"); 134610696SDavid.Hollister@Sun.COM break; 134710696SDavid.Hollister@Sun.COM case PMCOUT_GET_NVMD_DATA: 134810696SDavid.Hollister@Sun.COM return ("GET_NVMD_DATA"); 134910696SDavid.Hollister@Sun.COM break; 135010696SDavid.Hollister@Sun.COM case PMCOUT_SET_NVMD_DATA: 135110696SDavid.Hollister@Sun.COM return ("SET_NVMD_DATA"); 135210696SDavid.Hollister@Sun.COM break; 135310696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_HANDLE_REMOVED: 135410696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_REMOVED"); 135510696SDavid.Hollister@Sun.COM break; 135610696SDavid.Hollister@Sun.COM case PMCOUT_SET_DEVICE_STATE: 135710696SDavid.Hollister@Sun.COM return ("SET_DEVICE_STATE"); 135810696SDavid.Hollister@Sun.COM break; 135910696SDavid.Hollister@Sun.COM case PMCOUT_GET_DEVICE_STATE: 136010696SDavid.Hollister@Sun.COM return ("GET_DEVICE_STATE"); 136110696SDavid.Hollister@Sun.COM break; 136210696SDavid.Hollister@Sun.COM case PMCOUT_SET_DEVICE_INFO: 136310696SDavid.Hollister@Sun.COM return ("SET_DEVICE_INFO"); 136410696SDavid.Hollister@Sun.COM break; 136510696SDavid.Hollister@Sun.COM default: 136610696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 136710696SDavid.Hollister@Sun.COM break; 136810696SDavid.Hollister@Sun.COM } 136910696SDavid.Hollister@Sun.COM } 137010696SDavid.Hollister@Sun.COM 137110696SDavid.Hollister@Sun.COM static void 137210696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(uint32_t *qentryp, int idx) 137310696SDavid.Hollister@Sun.COM { 137410696SDavid.Hollister@Sun.COM int qeidx; 137510696SDavid.Hollister@Sun.COM uint32_t word0 = LE_32(*qentryp); 137611601SDavid.Hollister@Sun.COM uint32_t word1 = LE_32(*(qentryp + 1)); 137711601SDavid.Hollister@Sun.COM uint8_t iop_event; 137810696SDavid.Hollister@Sun.COM 137910696SDavid.Hollister@Sun.COM mdb_printf("Entry #%02d\n", idx); 138010696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 138110696SDavid.Hollister@Sun.COM 138210696SDavid.Hollister@Sun.COM mdb_printf("Header: 0x%08x (", word0); 138310696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_VALID) { 138410696SDavid.Hollister@Sun.COM mdb_printf("VALID, "); 138510696SDavid.Hollister@Sun.COM } 138610696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_HIPRI) { 138710696SDavid.Hollister@Sun.COM mdb_printf("HIPRI, "); 138810696SDavid.Hollister@Sun.COM } 138910696SDavid.Hollister@Sun.COM mdb_printf("OBID=%d, ", 139010696SDavid.Hollister@Sun.COM (word0 & PMCS_IOMB_OBID_MASK) >> PMCS_IOMB_OBID_SHIFT); 139110696SDavid.Hollister@Sun.COM mdb_printf("CAT=%s, ", 139210696SDavid.Hollister@Sun.COM iomb_cat((word0 & PMCS_IOMB_CAT_MASK) >> PMCS_IOMB_CAT_SHIFT)); 139310696SDavid.Hollister@Sun.COM mdb_printf("OPCODE=%s", 139410696SDavid.Hollister@Sun.COM outbound_iomb_opcode(word0 & PMCS_IOMB_OPCODE_MASK)); 139511601SDavid.Hollister@Sun.COM if ((word0 & PMCS_IOMB_OPCODE_MASK) == PMCOUT_SAS_HW_EVENT) { 139611601SDavid.Hollister@Sun.COM iop_event = IOP_EVENT_EVENT(word1); 139711601SDavid.Hollister@Sun.COM mdb_printf(" <%s>", iomb_event(iop_event)); 139811601SDavid.Hollister@Sun.COM } 139910696SDavid.Hollister@Sun.COM mdb_printf(")\n"); 140010696SDavid.Hollister@Sun.COM 140110696SDavid.Hollister@Sun.COM mdb_printf("Remaining Payload:\n"); 140210696SDavid.Hollister@Sun.COM 140310696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 140410696SDavid.Hollister@Sun.COM for (qeidx = 1; qeidx < (PMCS_QENTRY_SIZE / 4); qeidx++) { 140510696SDavid.Hollister@Sun.COM mdb_printf("%08x ", LE_32(*(qentryp + qeidx))); 140610696SDavid.Hollister@Sun.COM } 140710696SDavid.Hollister@Sun.COM mdb_printf("\n"); 140810696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 140910696SDavid.Hollister@Sun.COM } 141010696SDavid.Hollister@Sun.COM 141110696SDavid.Hollister@Sun.COM static void 141210696SDavid.Hollister@Sun.COM display_outbound_queues(struct pmcs_hw ss, uint_t verbose) 141310696SDavid.Hollister@Sun.COM { 141410696SDavid.Hollister@Sun.COM int idx, qidx; 141510696SDavid.Hollister@Sun.COM uintptr_t obqp; 141610696SDavid.Hollister@Sun.COM uint32_t *cip; 141710696SDavid.Hollister@Sun.COM uint32_t *qentryp = mdb_alloc(PMCS_QENTRY_SIZE, UM_SLEEP); 141810696SDavid.Hollister@Sun.COM uint32_t last_consumed, oqpi; 141910696SDavid.Hollister@Sun.COM 142010696SDavid.Hollister@Sun.COM mdb_printf("\n"); 142110696SDavid.Hollister@Sun.COM mdb_printf("Outbound Queues\n"); 142210696SDavid.Hollister@Sun.COM mdb_printf("---------------\n"); 142310696SDavid.Hollister@Sun.COM 142410696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 142510696SDavid.Hollister@Sun.COM 142610696SDavid.Hollister@Sun.COM for (qidx = 0; qidx < PMCS_NOQ; qidx++) { 142710696SDavid.Hollister@Sun.COM obqp = (uintptr_t)ss.oqp[qidx]; 142810696SDavid.Hollister@Sun.COM 142910696SDavid.Hollister@Sun.COM if (obqp == NULL) { 143010696SDavid.Hollister@Sun.COM mdb_printf("No outbound queue ptr for queue #%d\n", 143110696SDavid.Hollister@Sun.COM qidx); 143210696SDavid.Hollister@Sun.COM continue; 143310696SDavid.Hollister@Sun.COM } 143410696SDavid.Hollister@Sun.COM 143510696SDavid.Hollister@Sun.COM mdb_printf("Outbound Queue #%d (Queue Type = %s)\n", qidx, 143610696SDavid.Hollister@Sun.COM obq_type(qidx)); 143710696SDavid.Hollister@Sun.COM /* 143810696SDavid.Hollister@Sun.COM * Chip is the producer, so read the actual producer index 143910696SDavid.Hollister@Sun.COM * and not the driver's version 144010696SDavid.Hollister@Sun.COM */ 144110696SDavid.Hollister@Sun.COM cip = (uint32_t *)((void *)ss.cip); 144210696SDavid.Hollister@Sun.COM if (MDB_RD(&oqpi, 4, cip + OQPI_BASE_OFFSET + 144310696SDavid.Hollister@Sun.COM (qidx * 4)) == -1) { 144410696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read oqpi\n"); 144510696SDavid.Hollister@Sun.COM break; 144610696SDavid.Hollister@Sun.COM } 144710696SDavid.Hollister@Sun.COM 144810696SDavid.Hollister@Sun.COM mdb_printf("Producer index: %d Consumer index: %d\n\n", 144910696SDavid.Hollister@Sun.COM LE_32(oqpi), ss.oqci[qidx]); 145010696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 145110696SDavid.Hollister@Sun.COM 145210696SDavid.Hollister@Sun.COM if (ss.oqci[qidx] == 0) { 145310696SDavid.Hollister@Sun.COM last_consumed = ss.ioq_depth - 1; 145410696SDavid.Hollister@Sun.COM } else { 145510696SDavid.Hollister@Sun.COM last_consumed = ss.oqci[qidx] - 1; 145610696SDavid.Hollister@Sun.COM } 145710696SDavid.Hollister@Sun.COM 145810696SDavid.Hollister@Sun.COM 145910696SDavid.Hollister@Sun.COM if (!verbose) { 146010696SDavid.Hollister@Sun.COM mdb_printf("Last processed entry:\n"); 146110696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 146210696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * last_consumed))) 146310696SDavid.Hollister@Sun.COM == -1) { 146410696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 146510696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * 146610696SDavid.Hollister@Sun.COM last_consumed))); 146710696SDavid.Hollister@Sun.COM break; 146810696SDavid.Hollister@Sun.COM } 146910696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(qentryp, last_consumed); 147010696SDavid.Hollister@Sun.COM mdb_printf("\n"); 147110696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 147210696SDavid.Hollister@Sun.COM continue; 147310696SDavid.Hollister@Sun.COM } 147410696SDavid.Hollister@Sun.COM 147510696SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.ioq_depth; idx++) { 147610696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 147710696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * idx))) == -1) { 147810696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 147910696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * idx))); 148010696SDavid.Hollister@Sun.COM break; 148110696SDavid.Hollister@Sun.COM } 148210696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(qentryp, idx); 148310696SDavid.Hollister@Sun.COM } 148410696SDavid.Hollister@Sun.COM 148510696SDavid.Hollister@Sun.COM mdb_printf("\n"); 148610696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 148710696SDavid.Hollister@Sun.COM } 148810696SDavid.Hollister@Sun.COM 148910696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 149010696SDavid.Hollister@Sun.COM mdb_free(qentryp, PMCS_QENTRY_SIZE); 149110696SDavid.Hollister@Sun.COM } 149210696SDavid.Hollister@Sun.COM 149310696SDavid.Hollister@Sun.COM static void 149410696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(uint32_t *qentryp, int idx) 149510696SDavid.Hollister@Sun.COM { 149610696SDavid.Hollister@Sun.COM int qeidx; 149710696SDavid.Hollister@Sun.COM uint32_t word0 = LE_32(*qentryp); 149810696SDavid.Hollister@Sun.COM 149910696SDavid.Hollister@Sun.COM mdb_printf("Entry #%02d\n", idx); 150010696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 150110696SDavid.Hollister@Sun.COM 150210696SDavid.Hollister@Sun.COM mdb_printf("Header: 0x%08x (", word0); 150310696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_VALID) { 150410696SDavid.Hollister@Sun.COM mdb_printf("VALID, "); 150510696SDavid.Hollister@Sun.COM } 150610696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_HIPRI) { 150710696SDavid.Hollister@Sun.COM mdb_printf("HIPRI, "); 150810696SDavid.Hollister@Sun.COM } 150910696SDavid.Hollister@Sun.COM mdb_printf("OBID=%d, ", 151010696SDavid.Hollister@Sun.COM (word0 & PMCS_IOMB_OBID_MASK) >> PMCS_IOMB_OBID_SHIFT); 151110696SDavid.Hollister@Sun.COM mdb_printf("CAT=%s, ", 151210696SDavid.Hollister@Sun.COM iomb_cat((word0 & PMCS_IOMB_CAT_MASK) >> PMCS_IOMB_CAT_SHIFT)); 151310696SDavid.Hollister@Sun.COM mdb_printf("OPCODE=%s", 151410696SDavid.Hollister@Sun.COM inbound_iomb_opcode(word0 & PMCS_IOMB_OPCODE_MASK)); 151510696SDavid.Hollister@Sun.COM mdb_printf(")\n"); 151610696SDavid.Hollister@Sun.COM 151710696SDavid.Hollister@Sun.COM mdb_printf("HTAG: 0x%08x\n", LE_32(*(qentryp + 1))); 151810696SDavid.Hollister@Sun.COM mdb_printf("Remaining Payload:\n"); 151910696SDavid.Hollister@Sun.COM 152010696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 152110696SDavid.Hollister@Sun.COM for (qeidx = 2; qeidx < (PMCS_QENTRY_SIZE / 4); qeidx++) { 152210696SDavid.Hollister@Sun.COM mdb_printf("%08x ", LE_32(*(qentryp + qeidx))); 152310696SDavid.Hollister@Sun.COM } 152410696SDavid.Hollister@Sun.COM mdb_printf("\n"); 152510696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 152610696SDavid.Hollister@Sun.COM } 152710696SDavid.Hollister@Sun.COM 152810696SDavid.Hollister@Sun.COM static void 152910696SDavid.Hollister@Sun.COM display_inbound_queues(struct pmcs_hw ss, uint_t verbose) 153010696SDavid.Hollister@Sun.COM { 153110696SDavid.Hollister@Sun.COM int idx, qidx, iqci, last_consumed; 153210696SDavid.Hollister@Sun.COM uintptr_t ibqp; 153310696SDavid.Hollister@Sun.COM uint32_t *qentryp = mdb_alloc(PMCS_QENTRY_SIZE, UM_SLEEP); 153410696SDavid.Hollister@Sun.COM uint32_t *cip; 153510696SDavid.Hollister@Sun.COM 153610696SDavid.Hollister@Sun.COM mdb_printf("\n"); 153710696SDavid.Hollister@Sun.COM mdb_printf("Inbound Queues\n"); 153810696SDavid.Hollister@Sun.COM mdb_printf("--------------\n"); 153910696SDavid.Hollister@Sun.COM 154010696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 154110696SDavid.Hollister@Sun.COM 154210696SDavid.Hollister@Sun.COM for (qidx = 0; qidx < PMCS_NIQ; qidx++) { 154310696SDavid.Hollister@Sun.COM ibqp = (uintptr_t)ss.iqp[qidx]; 154410696SDavid.Hollister@Sun.COM 154510696SDavid.Hollister@Sun.COM if (ibqp == NULL) { 154610696SDavid.Hollister@Sun.COM mdb_printf("No inbound queue ptr for queue #%d\n", 154710696SDavid.Hollister@Sun.COM qidx); 154810696SDavid.Hollister@Sun.COM continue; 154910696SDavid.Hollister@Sun.COM } 155010696SDavid.Hollister@Sun.COM 155110696SDavid.Hollister@Sun.COM mdb_printf("Inbound Queue #%d (Queue Type = %s)\n", qidx, 155210696SDavid.Hollister@Sun.COM ibq_type(qidx)); 155310696SDavid.Hollister@Sun.COM 155410696SDavid.Hollister@Sun.COM cip = (uint32_t *)((void *)ss.cip); 155510696SDavid.Hollister@Sun.COM if (MDB_RD(&iqci, 4, cip + (qidx * 4)) == -1) { 155610696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read iqci\n"); 155710696SDavid.Hollister@Sun.COM break; 155810696SDavid.Hollister@Sun.COM } 155910696SDavid.Hollister@Sun.COM iqci = LE_32(iqci); 156010696SDavid.Hollister@Sun.COM 156110696SDavid.Hollister@Sun.COM mdb_printf("Producer index: %d Consumer index: %d\n\n", 156210696SDavid.Hollister@Sun.COM ss.shadow_iqpi[qidx], iqci); 156310696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 156410696SDavid.Hollister@Sun.COM 156510696SDavid.Hollister@Sun.COM if (iqci == 0) { 156610696SDavid.Hollister@Sun.COM last_consumed = ss.ioq_depth - 1; 156710696SDavid.Hollister@Sun.COM } else { 156810696SDavid.Hollister@Sun.COM last_consumed = iqci - 1; 156910696SDavid.Hollister@Sun.COM } 157010696SDavid.Hollister@Sun.COM 157110696SDavid.Hollister@Sun.COM if (!verbose) { 157210696SDavid.Hollister@Sun.COM mdb_printf("Last processed entry:\n"); 157310696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 157410696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * last_consumed))) 157510696SDavid.Hollister@Sun.COM == -1) { 157610696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 157710696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * 157810696SDavid.Hollister@Sun.COM last_consumed))); 157910696SDavid.Hollister@Sun.COM break; 158010696SDavid.Hollister@Sun.COM } 158110696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(qentryp, last_consumed); 158210696SDavid.Hollister@Sun.COM mdb_printf("\n"); 158310696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 158410696SDavid.Hollister@Sun.COM continue; 158510696SDavid.Hollister@Sun.COM } 158610696SDavid.Hollister@Sun.COM 158710696SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.ioq_depth; idx++) { 158810696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 158910696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * idx))) == -1) { 159010696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 159110696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * idx))); 159210696SDavid.Hollister@Sun.COM break; 159310696SDavid.Hollister@Sun.COM } 159410696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(qentryp, idx); 159510696SDavid.Hollister@Sun.COM } 159610696SDavid.Hollister@Sun.COM 159710696SDavid.Hollister@Sun.COM mdb_printf("\n"); 159810696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 159910696SDavid.Hollister@Sun.COM } 160010696SDavid.Hollister@Sun.COM 160110696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 160210696SDavid.Hollister@Sun.COM mdb_free(qentryp, PMCS_QENTRY_SIZE); 160310696SDavid.Hollister@Sun.COM } 160410696SDavid.Hollister@Sun.COM 160511601SDavid.Hollister@Sun.COM /* 160611601SDavid.Hollister@Sun.COM * phy is our copy of the PHY structure. phyp is the pointer to the actual 160711601SDavid.Hollister@Sun.COM * kernel PHY data structure 160811601SDavid.Hollister@Sun.COM */ 160910696SDavid.Hollister@Sun.COM static void 161011601SDavid.Hollister@Sun.COM display_phy(struct pmcs_phy phy, struct pmcs_phy *phyp, int verbose, 161111601SDavid.Hollister@Sun.COM int totals_only) 161210696SDavid.Hollister@Sun.COM { 161310696SDavid.Hollister@Sun.COM char *dtype, *speed; 161410696SDavid.Hollister@Sun.COM char *yes = "Yes"; 161510696SDavid.Hollister@Sun.COM char *no = "No"; 161610696SDavid.Hollister@Sun.COM char *cfgd = no; 161710696SDavid.Hollister@Sun.COM char *apend = no; 161810696SDavid.Hollister@Sun.COM char *asent = no; 161910696SDavid.Hollister@Sun.COM char *dead = no; 162010696SDavid.Hollister@Sun.COM char *changed = no; 162111601SDavid.Hollister@Sun.COM char route_attr, route_method; 162210696SDavid.Hollister@Sun.COM 162310696SDavid.Hollister@Sun.COM switch (phy.dtype) { 162410696SDavid.Hollister@Sun.COM case NOTHING: 162510696SDavid.Hollister@Sun.COM dtype = "None"; 162610696SDavid.Hollister@Sun.COM break; 162710696SDavid.Hollister@Sun.COM case SATA: 162810696SDavid.Hollister@Sun.COM dtype = "SATA"; 162910696SDavid.Hollister@Sun.COM if (phy.configured) { 163010696SDavid.Hollister@Sun.COM ++sata_phys; 163110696SDavid.Hollister@Sun.COM } 163210696SDavid.Hollister@Sun.COM break; 163310696SDavid.Hollister@Sun.COM case SAS: 163410696SDavid.Hollister@Sun.COM dtype = "SAS"; 163510696SDavid.Hollister@Sun.COM if (phy.configured) { 163610696SDavid.Hollister@Sun.COM ++sas_phys; 163710696SDavid.Hollister@Sun.COM } 163810696SDavid.Hollister@Sun.COM break; 163910696SDavid.Hollister@Sun.COM case EXPANDER: 164010696SDavid.Hollister@Sun.COM dtype = "EXP"; 164110696SDavid.Hollister@Sun.COM if (phy.configured) { 164210696SDavid.Hollister@Sun.COM ++exp_phys; 164310696SDavid.Hollister@Sun.COM } 164410696SDavid.Hollister@Sun.COM break; 164510696SDavid.Hollister@Sun.COM } 164610696SDavid.Hollister@Sun.COM 164710696SDavid.Hollister@Sun.COM if (phy.dtype == NOTHING) { 164810696SDavid.Hollister@Sun.COM empty_phys++; 164910696SDavid.Hollister@Sun.COM } else if ((phy.dtype == EXPANDER) && phy.configured) { 165010696SDavid.Hollister@Sun.COM num_expanders++; 165110696SDavid.Hollister@Sun.COM } 165210696SDavid.Hollister@Sun.COM 165310696SDavid.Hollister@Sun.COM if (totals_only) { 165410696SDavid.Hollister@Sun.COM return; 165510696SDavid.Hollister@Sun.COM } 165610696SDavid.Hollister@Sun.COM 165710696SDavid.Hollister@Sun.COM switch (phy.link_rate) { 165810696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_1_5GBIT: 165910696SDavid.Hollister@Sun.COM speed = "1.5Gb/s"; 166010696SDavid.Hollister@Sun.COM break; 166110696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_3GBIT: 166210696SDavid.Hollister@Sun.COM speed = "3 Gb/s"; 166310696SDavid.Hollister@Sun.COM break; 166410696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_6GBIT: 166510696SDavid.Hollister@Sun.COM speed = "6 Gb/s"; 166610696SDavid.Hollister@Sun.COM break; 166710696SDavid.Hollister@Sun.COM default: 166810696SDavid.Hollister@Sun.COM speed = "N/A"; 166910696SDavid.Hollister@Sun.COM break; 167010696SDavid.Hollister@Sun.COM } 167110696SDavid.Hollister@Sun.COM 167210696SDavid.Hollister@Sun.COM if ((phy.dtype != NOTHING) || verbose) { 167310696SDavid.Hollister@Sun.COM print_sas_address(&phy); 167410696SDavid.Hollister@Sun.COM 167510696SDavid.Hollister@Sun.COM if (phy.device_id != PMCS_INVALID_DEVICE_ID) { 167610696SDavid.Hollister@Sun.COM mdb_printf(" %3d %4d %6s %4s ", 167710696SDavid.Hollister@Sun.COM phy.device_id, phy.phynum, speed, dtype); 167810696SDavid.Hollister@Sun.COM } else { 167910696SDavid.Hollister@Sun.COM mdb_printf(" N/A %4d %6s %4s ", 168010696SDavid.Hollister@Sun.COM phy.phynum, speed, dtype); 168110696SDavid.Hollister@Sun.COM } 168210696SDavid.Hollister@Sun.COM 168310696SDavid.Hollister@Sun.COM if (verbose) { 168410696SDavid.Hollister@Sun.COM if (phy.abort_sent) { 168510696SDavid.Hollister@Sun.COM asent = yes; 168610696SDavid.Hollister@Sun.COM } 168710696SDavid.Hollister@Sun.COM if (phy.abort_pending) { 168810696SDavid.Hollister@Sun.COM apend = yes; 168910696SDavid.Hollister@Sun.COM } 169010696SDavid.Hollister@Sun.COM if (phy.configured) { 169110696SDavid.Hollister@Sun.COM cfgd = yes; 169210696SDavid.Hollister@Sun.COM } 169310696SDavid.Hollister@Sun.COM if (phy.dead) { 169410696SDavid.Hollister@Sun.COM dead = yes; 169510696SDavid.Hollister@Sun.COM } 169610696SDavid.Hollister@Sun.COM if (phy.changed) { 169710696SDavid.Hollister@Sun.COM changed = yes; 169810696SDavid.Hollister@Sun.COM } 169910696SDavid.Hollister@Sun.COM 170011601SDavid.Hollister@Sun.COM switch (phy.routing_attr) { 170111601SDavid.Hollister@Sun.COM case SMP_ROUTING_DIRECT: 170211601SDavid.Hollister@Sun.COM route_attr = 'D'; 170311601SDavid.Hollister@Sun.COM break; 170411601SDavid.Hollister@Sun.COM case SMP_ROUTING_SUBTRACTIVE: 170511601SDavid.Hollister@Sun.COM route_attr = 'S'; 170611601SDavid.Hollister@Sun.COM break; 170711601SDavid.Hollister@Sun.COM case SMP_ROUTING_TABLE: 170811601SDavid.Hollister@Sun.COM route_attr = 'T'; 170911601SDavid.Hollister@Sun.COM break; 171011601SDavid.Hollister@Sun.COM default: 171111601SDavid.Hollister@Sun.COM route_attr = '?'; 171211601SDavid.Hollister@Sun.COM break; 171311601SDavid.Hollister@Sun.COM } 171411601SDavid.Hollister@Sun.COM 171511601SDavid.Hollister@Sun.COM switch (phy.routing_method) { 171611601SDavid.Hollister@Sun.COM case SMP_ROUTING_DIRECT: 171711601SDavid.Hollister@Sun.COM route_method = 'D'; 171811601SDavid.Hollister@Sun.COM break; 171911601SDavid.Hollister@Sun.COM case SMP_ROUTING_SUBTRACTIVE: 172011601SDavid.Hollister@Sun.COM route_method = 'S'; 172111601SDavid.Hollister@Sun.COM break; 172211601SDavid.Hollister@Sun.COM case SMP_ROUTING_TABLE: 172311601SDavid.Hollister@Sun.COM route_method = 'T'; 172411601SDavid.Hollister@Sun.COM break; 172511601SDavid.Hollister@Sun.COM default: 172611601SDavid.Hollister@Sun.COM route_attr = '?'; 172711601SDavid.Hollister@Sun.COM break; 172811601SDavid.Hollister@Sun.COM } 172911601SDavid.Hollister@Sun.COM 173011601SDavid.Hollister@Sun.COM mdb_printf("%-4s %-4s %-4s %-4s %-4s %3d %3c/%1c %3d " 173111601SDavid.Hollister@Sun.COM "%1d 0x%p ", cfgd, apend, asent, changed, dead, 173211601SDavid.Hollister@Sun.COM phy.ref_count, route_attr, route_method, 173311601SDavid.Hollister@Sun.COM phy.enum_attempts, phy.reenumerate, phy.phy_lock); 173410696SDavid.Hollister@Sun.COM } 173510696SDavid.Hollister@Sun.COM 173610696SDavid.Hollister@Sun.COM mdb_printf("Path: %s\n", phy.path); 173711601SDavid.Hollister@Sun.COM 173811601SDavid.Hollister@Sun.COM /* 173911601SDavid.Hollister@Sun.COM * In verbose mode, on the next line print the drill down 174011601SDavid.Hollister@Sun.COM * info to see either the DISCOVER response or the REPORT 174111601SDavid.Hollister@Sun.COM * GENERAL response depending on the PHY's dtype 174211601SDavid.Hollister@Sun.COM */ 174311601SDavid.Hollister@Sun.COM if (verbose) { 174411601SDavid.Hollister@Sun.COM uintptr_t tphyp = (uintptr_t)phyp; 174511601SDavid.Hollister@Sun.COM 174611601SDavid.Hollister@Sun.COM mdb_inc_indent(4); 174711601SDavid.Hollister@Sun.COM switch (phy.dtype) { 174811601SDavid.Hollister@Sun.COM case EXPANDER: 174911601SDavid.Hollister@Sun.COM if (!phy.configured) { 175011601SDavid.Hollister@Sun.COM break; 175111601SDavid.Hollister@Sun.COM } 175211601SDavid.Hollister@Sun.COM mdb_printf("REPORT GENERAL response: %p::" 175311601SDavid.Hollister@Sun.COM "print smp_report_general_resp_t\n", 175411601SDavid.Hollister@Sun.COM (tphyp + offsetof(struct pmcs_phy, 175511601SDavid.Hollister@Sun.COM rg_resp))); 175611601SDavid.Hollister@Sun.COM break; 175711601SDavid.Hollister@Sun.COM case SAS: 175811601SDavid.Hollister@Sun.COM case SATA: 175911601SDavid.Hollister@Sun.COM mdb_printf("DISCOVER response: %p::" 176011601SDavid.Hollister@Sun.COM "print smp_discover_resp_t\n", 176111601SDavid.Hollister@Sun.COM (tphyp + offsetof(struct pmcs_phy, 176211601SDavid.Hollister@Sun.COM disc_resp))); 176311601SDavid.Hollister@Sun.COM break; 176411601SDavid.Hollister@Sun.COM default: 176511601SDavid.Hollister@Sun.COM break; 176611601SDavid.Hollister@Sun.COM } 176711601SDavid.Hollister@Sun.COM mdb_dec_indent(4); 176811601SDavid.Hollister@Sun.COM } 176910696SDavid.Hollister@Sun.COM } 177010696SDavid.Hollister@Sun.COM } 177110696SDavid.Hollister@Sun.COM 177210696SDavid.Hollister@Sun.COM static void 177310696SDavid.Hollister@Sun.COM display_phys(struct pmcs_hw ss, int verbose, struct pmcs_phy *parent, int level, 177410696SDavid.Hollister@Sun.COM int totals_only) 177510696SDavid.Hollister@Sun.COM { 177610696SDavid.Hollister@Sun.COM pmcs_phy_t phy; 177710696SDavid.Hollister@Sun.COM pmcs_phy_t *pphy = parent; 177810696SDavid.Hollister@Sun.COM 177910696SDavid.Hollister@Sun.COM mdb_inc_indent(3); 178010696SDavid.Hollister@Sun.COM 178110696SDavid.Hollister@Sun.COM if (parent == NULL) { 178210696SDavid.Hollister@Sun.COM pphy = (pmcs_phy_t *)ss.root_phys; 178310696SDavid.Hollister@Sun.COM } else { 178410696SDavid.Hollister@Sun.COM pphy = (pmcs_phy_t *)parent; 178510696SDavid.Hollister@Sun.COM } 178610696SDavid.Hollister@Sun.COM 178710696SDavid.Hollister@Sun.COM if (level == 0) { 178810696SDavid.Hollister@Sun.COM sas_phys = 0; 178910696SDavid.Hollister@Sun.COM sata_phys = 0; 179010696SDavid.Hollister@Sun.COM exp_phys = 0; 179110696SDavid.Hollister@Sun.COM num_expanders = 0; 179210696SDavid.Hollister@Sun.COM empty_phys = 0; 179310696SDavid.Hollister@Sun.COM } 179410696SDavid.Hollister@Sun.COM 179510696SDavid.Hollister@Sun.COM if (!totals_only) { 179610696SDavid.Hollister@Sun.COM if (level == 0) { 179710696SDavid.Hollister@Sun.COM mdb_printf("PHY information\n"); 179810696SDavid.Hollister@Sun.COM } 179910696SDavid.Hollister@Sun.COM mdb_printf("--------\n"); 180010696SDavid.Hollister@Sun.COM mdb_printf("Level %2d\n", level); 180110696SDavid.Hollister@Sun.COM mdb_printf("--------\n"); 180210696SDavid.Hollister@Sun.COM mdb_printf("SAS Address Hdl Phy# Speed Type "); 180310696SDavid.Hollister@Sun.COM 180410696SDavid.Hollister@Sun.COM if (verbose) { 180511601SDavid.Hollister@Sun.COM mdb_printf("Cfgd AbtP AbtS Chgd Dead Ref RtA/M Enm R " 180611601SDavid.Hollister@Sun.COM "Lock\n"); 180710696SDavid.Hollister@Sun.COM } else { 180810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 180910696SDavid.Hollister@Sun.COM } 181010696SDavid.Hollister@Sun.COM } 181110696SDavid.Hollister@Sun.COM 181210696SDavid.Hollister@Sun.COM while (pphy) { 181310696SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), (uintptr_t)pphy) == -1) { 181410696SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, phy); 181510696SDavid.Hollister@Sun.COM break; 181610696SDavid.Hollister@Sun.COM } 181710696SDavid.Hollister@Sun.COM 181811601SDavid.Hollister@Sun.COM display_phy(phy, pphy, verbose, totals_only); 181910696SDavid.Hollister@Sun.COM 182010696SDavid.Hollister@Sun.COM if (phy.children) { 182110696SDavid.Hollister@Sun.COM display_phys(ss, verbose, phy.children, level + 1, 182210696SDavid.Hollister@Sun.COM totals_only); 182310696SDavid.Hollister@Sun.COM if (!totals_only) { 182410696SDavid.Hollister@Sun.COM mdb_printf("\n"); 182510696SDavid.Hollister@Sun.COM } 182610696SDavid.Hollister@Sun.COM } 182710696SDavid.Hollister@Sun.COM 182810696SDavid.Hollister@Sun.COM pphy = phy.sibling; 182910696SDavid.Hollister@Sun.COM } 183010696SDavid.Hollister@Sun.COM 183110696SDavid.Hollister@Sun.COM mdb_dec_indent(3); 183210696SDavid.Hollister@Sun.COM 183310696SDavid.Hollister@Sun.COM if (level == 0) { 183410696SDavid.Hollister@Sun.COM if (verbose) { 183510696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP) " 183610696SDavid.Hollister@Sun.COM "(+%d subsidiary + %d empty)\n", "Occupied PHYs:", 183710696SDavid.Hollister@Sun.COM (sas_phys + sata_phys + num_expanders), 183810696SDavid.Hollister@Sun.COM sas_phys, sata_phys, num_expanders, 183910696SDavid.Hollister@Sun.COM (exp_phys - num_expanders), empty_phys); 184010696SDavid.Hollister@Sun.COM } else { 184110696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP)\n", 184210696SDavid.Hollister@Sun.COM "Occupied PHYs:", 184310696SDavid.Hollister@Sun.COM (sas_phys + sata_phys + num_expanders), 184410696SDavid.Hollister@Sun.COM sas_phys, sata_phys, num_expanders); 184510696SDavid.Hollister@Sun.COM } 184610696SDavid.Hollister@Sun.COM } 184710696SDavid.Hollister@Sun.COM } 184810696SDavid.Hollister@Sun.COM 184910696SDavid.Hollister@Sun.COM /* 185011048SDavid.Hollister@Sun.COM * filter is used to indicate whether we are filtering log messages based 185111048SDavid.Hollister@Sun.COM * on "instance". The other filtering (based on options) depends on the 185211048SDavid.Hollister@Sun.COM * values that are passed in for "sas_addr" and "phy_path". 185311048SDavid.Hollister@Sun.COM * 185410696SDavid.Hollister@Sun.COM * MAX_INST_STRLEN is the largest string size from which we will attempt 185510696SDavid.Hollister@Sun.COM * to convert to an instance number. The string will be formed up as 185610696SDavid.Hollister@Sun.COM * "0t<inst>\0" so that mdb_strtoull can parse it properly. 185710696SDavid.Hollister@Sun.COM */ 185810696SDavid.Hollister@Sun.COM #define MAX_INST_STRLEN 8 185910696SDavid.Hollister@Sun.COM 186010696SDavid.Hollister@Sun.COM static int 186111347SRamana.Srikanth@Sun.COM pmcs_dump_tracelog(boolean_t filter, int instance, uint64_t tail_lines, 186211347SRamana.Srikanth@Sun.COM const char *phy_path, uint64_t sas_address) 186310696SDavid.Hollister@Sun.COM { 186410696SDavid.Hollister@Sun.COM pmcs_tbuf_t *tbuf_addr; 186510696SDavid.Hollister@Sun.COM uint_t tbuf_idx; 186610696SDavid.Hollister@Sun.COM pmcs_tbuf_t tbuf; 186710696SDavid.Hollister@Sun.COM boolean_t wrap, elem_filtered; 186810696SDavid.Hollister@Sun.COM uint_t start_idx, elems_to_print, idx, tbuf_num_elems; 186910696SDavid.Hollister@Sun.COM char *bufp; 187010696SDavid.Hollister@Sun.COM char elem_inst[MAX_INST_STRLEN], ei_idx; 187111048SDavid.Hollister@Sun.COM uint64_t sas_addr; 187211048SDavid.Hollister@Sun.COM uint8_t *sas_addressp; 187310696SDavid.Hollister@Sun.COM 187410696SDavid.Hollister@Sun.COM /* Get the address of the first element */ 187510696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_addr, "pmcs_tbuf") == -1) { 187610696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf"); 187710696SDavid.Hollister@Sun.COM return (DCMD_ERR); 187810696SDavid.Hollister@Sun.COM } 187910696SDavid.Hollister@Sun.COM 188010696SDavid.Hollister@Sun.COM /* Get the total number */ 188110696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_num_elems, "pmcs_tbuf_num_elems") == -1) { 188210696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_num_elems"); 188310696SDavid.Hollister@Sun.COM return (DCMD_ERR); 188410696SDavid.Hollister@Sun.COM } 188510696SDavid.Hollister@Sun.COM 188610696SDavid.Hollister@Sun.COM /* Get the current index */ 188710696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_idx, "pmcs_tbuf_idx") == -1) { 188810696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_idx"); 188910696SDavid.Hollister@Sun.COM return (DCMD_ERR); 189010696SDavid.Hollister@Sun.COM } 189110696SDavid.Hollister@Sun.COM 189210696SDavid.Hollister@Sun.COM /* Indicator as to whether the buffer has wrapped */ 189310696SDavid.Hollister@Sun.COM if (mdb_readvar(&wrap, "pmcs_tbuf_wrap") == -1) { 189410696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_wrap"); 189510696SDavid.Hollister@Sun.COM return (DCMD_ERR); 189610696SDavid.Hollister@Sun.COM } 189710696SDavid.Hollister@Sun.COM 189811048SDavid.Hollister@Sun.COM /* 189911048SDavid.Hollister@Sun.COM * On little-endian systems, the SAS address passed in will be 190011048SDavid.Hollister@Sun.COM * byte swapped. Take care of that here. 190111048SDavid.Hollister@Sun.COM */ 190211048SDavid.Hollister@Sun.COM #if defined(_LITTLE_ENDIAN) 190311048SDavid.Hollister@Sun.COM sas_addr = ((sas_address << 56) | 190411048SDavid.Hollister@Sun.COM ((sas_address << 40) & 0xff000000000000ULL) | 190511048SDavid.Hollister@Sun.COM ((sas_address << 24) & 0xff0000000000ULL) | 190611048SDavid.Hollister@Sun.COM ((sas_address << 8) & 0xff00000000ULL) | 190711048SDavid.Hollister@Sun.COM ((sas_address >> 8) & 0xff000000ULL) | 190811048SDavid.Hollister@Sun.COM ((sas_address >> 24) & 0xff0000ULL) | 190911048SDavid.Hollister@Sun.COM ((sas_address >> 40) & 0xff00ULL) | 191011048SDavid.Hollister@Sun.COM (sas_address >> 56)); 191111048SDavid.Hollister@Sun.COM #else 191211048SDavid.Hollister@Sun.COM sas_addr = sas_address; 191311048SDavid.Hollister@Sun.COM #endif 191411048SDavid.Hollister@Sun.COM sas_addressp = (uint8_t *)&sas_addr; 191511048SDavid.Hollister@Sun.COM 191611347SRamana.Srikanth@Sun.COM /* Ensure the tail number isn't greater than the size of the log */ 191711347SRamana.Srikanth@Sun.COM if (tail_lines > tbuf_num_elems) { 191811347SRamana.Srikanth@Sun.COM tail_lines = tbuf_num_elems; 191911347SRamana.Srikanth@Sun.COM } 192011347SRamana.Srikanth@Sun.COM 192110696SDavid.Hollister@Sun.COM /* Figure out where we start and stop */ 192210696SDavid.Hollister@Sun.COM if (wrap) { 192311347SRamana.Srikanth@Sun.COM if (tail_lines) { 192411347SRamana.Srikanth@Sun.COM /* Do we need to wrap backwards? */ 192511347SRamana.Srikanth@Sun.COM if (tail_lines > tbuf_idx) { 192611347SRamana.Srikanth@Sun.COM start_idx = tbuf_num_elems - (tail_lines - 192711347SRamana.Srikanth@Sun.COM tbuf_idx); 192811347SRamana.Srikanth@Sun.COM } else { 192911347SRamana.Srikanth@Sun.COM start_idx = tbuf_idx - tail_lines; 193011347SRamana.Srikanth@Sun.COM } 193111347SRamana.Srikanth@Sun.COM elems_to_print = tail_lines; 193211347SRamana.Srikanth@Sun.COM } else { 193311347SRamana.Srikanth@Sun.COM start_idx = tbuf_idx; 193411347SRamana.Srikanth@Sun.COM elems_to_print = tbuf_num_elems; 193511347SRamana.Srikanth@Sun.COM } 193610696SDavid.Hollister@Sun.COM } else { 193711347SRamana.Srikanth@Sun.COM if (tail_lines > tbuf_idx) { 193811347SRamana.Srikanth@Sun.COM tail_lines = tbuf_idx; 193911347SRamana.Srikanth@Sun.COM } 194011347SRamana.Srikanth@Sun.COM if (tail_lines) { 194111347SRamana.Srikanth@Sun.COM start_idx = tbuf_idx - tail_lines; 194211347SRamana.Srikanth@Sun.COM elems_to_print = tail_lines; 194311347SRamana.Srikanth@Sun.COM } else { 194411347SRamana.Srikanth@Sun.COM start_idx = 0; 194511347SRamana.Srikanth@Sun.COM elems_to_print = tbuf_idx; 194611347SRamana.Srikanth@Sun.COM } 194710696SDavid.Hollister@Sun.COM } 194810696SDavid.Hollister@Sun.COM 194910696SDavid.Hollister@Sun.COM idx = start_idx; 195010696SDavid.Hollister@Sun.COM 195110696SDavid.Hollister@Sun.COM /* Dump the buffer contents */ 195210696SDavid.Hollister@Sun.COM while (elems_to_print != 0) { 195310696SDavid.Hollister@Sun.COM if (MDB_RD(&tbuf, sizeof (pmcs_tbuf_t), (tbuf_addr + idx)) 195410696SDavid.Hollister@Sun.COM == -1) { 195510696SDavid.Hollister@Sun.COM NOREAD(tbuf, (tbuf_addr + idx)); 195610696SDavid.Hollister@Sun.COM return (DCMD_ERR); 195710696SDavid.Hollister@Sun.COM } 195810696SDavid.Hollister@Sun.COM 195911048SDavid.Hollister@Sun.COM /* 196011048SDavid.Hollister@Sun.COM * Check for filtering on HBA instance 196111048SDavid.Hollister@Sun.COM */ 196210696SDavid.Hollister@Sun.COM elem_filtered = B_FALSE; 196310696SDavid.Hollister@Sun.COM 196410696SDavid.Hollister@Sun.COM if (filter) { 196510696SDavid.Hollister@Sun.COM bufp = tbuf.buf; 196610696SDavid.Hollister@Sun.COM /* Skip the driver name */ 196710696SDavid.Hollister@Sun.COM while (*bufp < '0' || *bufp > '9') { 196810696SDavid.Hollister@Sun.COM bufp++; 196910696SDavid.Hollister@Sun.COM } 197010696SDavid.Hollister@Sun.COM 197110696SDavid.Hollister@Sun.COM ei_idx = 0; 197210696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = '0'; 197310696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = 't'; 197410696SDavid.Hollister@Sun.COM while (*bufp != ':' && ei_idx < (MAX_INST_STRLEN - 1)) { 197510696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = *bufp; 197610696SDavid.Hollister@Sun.COM bufp++; 197710696SDavid.Hollister@Sun.COM } 197810696SDavid.Hollister@Sun.COM elem_inst[ei_idx] = 0; 197910696SDavid.Hollister@Sun.COM 198010696SDavid.Hollister@Sun.COM /* Get the instance */ 198110696SDavid.Hollister@Sun.COM if ((int)mdb_strtoull(elem_inst) != instance) { 198210696SDavid.Hollister@Sun.COM elem_filtered = B_TRUE; 198310696SDavid.Hollister@Sun.COM } 198410696SDavid.Hollister@Sun.COM } 198510696SDavid.Hollister@Sun.COM 198611048SDavid.Hollister@Sun.COM if (!elem_filtered && (phy_path || sas_address)) { 198711048SDavid.Hollister@Sun.COM /* 198811048SDavid.Hollister@Sun.COM * This message is not being filtered by HBA instance. 198911048SDavid.Hollister@Sun.COM * Now check to see if we're filtering based on 199011048SDavid.Hollister@Sun.COM * PHY path or SAS address. 199111048SDavid.Hollister@Sun.COM * Filtering is an "OR" operation. So, if any of the 199211048SDavid.Hollister@Sun.COM * criteria matches, this message will be printed. 199311048SDavid.Hollister@Sun.COM */ 199411048SDavid.Hollister@Sun.COM elem_filtered = B_TRUE; 199511048SDavid.Hollister@Sun.COM 199611048SDavid.Hollister@Sun.COM if (phy_path != NULL) { 199711048SDavid.Hollister@Sun.COM if (strncmp(phy_path, tbuf.phy_path, 199811048SDavid.Hollister@Sun.COM PMCS_TBUF_UA_MAX_SIZE) == 0) { 199911048SDavid.Hollister@Sun.COM elem_filtered = B_FALSE; 200011048SDavid.Hollister@Sun.COM } 200111048SDavid.Hollister@Sun.COM } 200211048SDavid.Hollister@Sun.COM if (sas_address != 0) { 200311048SDavid.Hollister@Sun.COM if (memcmp(sas_addressp, tbuf.phy_sas_address, 200411048SDavid.Hollister@Sun.COM 8) == 0) { 200511048SDavid.Hollister@Sun.COM elem_filtered = B_FALSE; 200611048SDavid.Hollister@Sun.COM } 200711048SDavid.Hollister@Sun.COM } 200811048SDavid.Hollister@Sun.COM } 200911048SDavid.Hollister@Sun.COM 201010696SDavid.Hollister@Sun.COM if (!elem_filtered) { 201110696SDavid.Hollister@Sun.COM mdb_printf("%Y.%09ld %s\n", tbuf.timestamp, tbuf.buf); 201210696SDavid.Hollister@Sun.COM } 201310696SDavid.Hollister@Sun.COM 201410696SDavid.Hollister@Sun.COM --elems_to_print; 201510696SDavid.Hollister@Sun.COM if (++idx == tbuf_num_elems) { 201610696SDavid.Hollister@Sun.COM idx = 0; 201710696SDavid.Hollister@Sun.COM } 201810696SDavid.Hollister@Sun.COM } 201910696SDavid.Hollister@Sun.COM 202010696SDavid.Hollister@Sun.COM return (DCMD_OK); 202110696SDavid.Hollister@Sun.COM } 202210696SDavid.Hollister@Sun.COM 202310696SDavid.Hollister@Sun.COM /* 202410696SDavid.Hollister@Sun.COM * Walkers 202510696SDavid.Hollister@Sun.COM */ 202610696SDavid.Hollister@Sun.COM static int 202710696SDavid.Hollister@Sun.COM targets_walk_i(mdb_walk_state_t *wsp) 202810696SDavid.Hollister@Sun.COM { 202910696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 203010696SDavid.Hollister@Sun.COM mdb_warn("Can not perform global walk\n"); 203110696SDavid.Hollister@Sun.COM return (WALK_ERR); 203210696SDavid.Hollister@Sun.COM } 203310696SDavid.Hollister@Sun.COM 203410696SDavid.Hollister@Sun.COM /* 203510696SDavid.Hollister@Sun.COM * Address provided belongs to HBA softstate. Get the targets pointer 203610696SDavid.Hollister@Sun.COM * to begin the walk. 203710696SDavid.Hollister@Sun.COM */ 203810696SDavid.Hollister@Sun.COM if (mdb_vread(&ss, sizeof (pmcs_hw_t), wsp->walk_addr) != 203910696SDavid.Hollister@Sun.COM sizeof (pmcs_hw_t)) { 204010696SDavid.Hollister@Sun.COM mdb_warn("Unable to read HBA softstate\n"); 204110696SDavid.Hollister@Sun.COM return (WALK_ERR); 204210696SDavid.Hollister@Sun.COM } 204310696SDavid.Hollister@Sun.COM 204410696SDavid.Hollister@Sun.COM if (targets == NULL) { 204510696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * ss.max_dev, UM_SLEEP); 204610696SDavid.Hollister@Sun.COM } 204710696SDavid.Hollister@Sun.COM 204810696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * ss.max_dev, ss.targets) == -1) { 204910696SDavid.Hollister@Sun.COM NOREAD(targets, ss.targets); 205010696SDavid.Hollister@Sun.COM return (WALK_ERR); 205110696SDavid.Hollister@Sun.COM } 205210696SDavid.Hollister@Sun.COM 205310696SDavid.Hollister@Sun.COM target_idx = 0; 205410696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(targets[0]); 205510696SDavid.Hollister@Sun.COM wsp->walk_data = mdb_alloc(sizeof (pmcs_xscsi_t), UM_SLEEP); 205610696SDavid.Hollister@Sun.COM 205710696SDavid.Hollister@Sun.COM return (WALK_NEXT); 205810696SDavid.Hollister@Sun.COM } 205910696SDavid.Hollister@Sun.COM 206010696SDavid.Hollister@Sun.COM static int 206110696SDavid.Hollister@Sun.COM targets_walk_s(mdb_walk_state_t *wsp) 206210696SDavid.Hollister@Sun.COM { 206310696SDavid.Hollister@Sun.COM int status; 206410696SDavid.Hollister@Sun.COM 206510696SDavid.Hollister@Sun.COM if (target_idx == ss.max_dev) { 206610696SDavid.Hollister@Sun.COM return (WALK_DONE); 206710696SDavid.Hollister@Sun.COM } 206810696SDavid.Hollister@Sun.COM 206910696SDavid.Hollister@Sun.COM if (mdb_vread(wsp->walk_data, sizeof (pmcs_xscsi_t), 207010696SDavid.Hollister@Sun.COM wsp->walk_addr) == -1) { 207110696SDavid.Hollister@Sun.COM mdb_warn("Failed to read target at %p", (void *)wsp->walk_addr); 207210696SDavid.Hollister@Sun.COM return (WALK_DONE); 207310696SDavid.Hollister@Sun.COM } 207410696SDavid.Hollister@Sun.COM 207510696SDavid.Hollister@Sun.COM status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 207610696SDavid.Hollister@Sun.COM wsp->walk_cbdata); 207710696SDavid.Hollister@Sun.COM 207810696SDavid.Hollister@Sun.COM do { 207910696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(targets[++target_idx]); 208010696SDavid.Hollister@Sun.COM } while ((wsp->walk_addr == NULL) && (target_idx < ss.max_dev)); 208110696SDavid.Hollister@Sun.COM 208210696SDavid.Hollister@Sun.COM if (target_idx == ss.max_dev) { 208310696SDavid.Hollister@Sun.COM return (WALK_DONE); 208410696SDavid.Hollister@Sun.COM } 208510696SDavid.Hollister@Sun.COM 208610696SDavid.Hollister@Sun.COM return (status); 208710696SDavid.Hollister@Sun.COM } 208810696SDavid.Hollister@Sun.COM 208910696SDavid.Hollister@Sun.COM static void 209010696SDavid.Hollister@Sun.COM targets_walk_f(mdb_walk_state_t *wsp) 209110696SDavid.Hollister@Sun.COM { 209210696SDavid.Hollister@Sun.COM mdb_free(wsp->walk_data, sizeof (pmcs_xscsi_t)); 209310696SDavid.Hollister@Sun.COM } 209410696SDavid.Hollister@Sun.COM 209510696SDavid.Hollister@Sun.COM 209610696SDavid.Hollister@Sun.COM static pmcs_phy_t * 209710696SDavid.Hollister@Sun.COM pmcs_next_sibling(pmcs_phy_t *phyp) 209810696SDavid.Hollister@Sun.COM { 209910696SDavid.Hollister@Sun.COM pmcs_phy_t parent; 210010696SDavid.Hollister@Sun.COM 210110696SDavid.Hollister@Sun.COM /* 210210696SDavid.Hollister@Sun.COM * First, if this is a root PHY, there are no more siblings 210310696SDavid.Hollister@Sun.COM */ 210410696SDavid.Hollister@Sun.COM if (phyp->level == 0) { 210510696SDavid.Hollister@Sun.COM return (NULL); 210610696SDavid.Hollister@Sun.COM } 210710696SDavid.Hollister@Sun.COM 210810696SDavid.Hollister@Sun.COM /* 210910696SDavid.Hollister@Sun.COM * Otherwise, next sibling is the parent's sibling 211010696SDavid.Hollister@Sun.COM */ 211110696SDavid.Hollister@Sun.COM while (phyp->level > 0) { 211210696SDavid.Hollister@Sun.COM if (mdb_vread(&parent, sizeof (pmcs_phy_t), 211310696SDavid.Hollister@Sun.COM (uintptr_t)phyp->parent) == -1) { 211410696SDavid.Hollister@Sun.COM mdb_warn("pmcs_next_sibling: Failed to read PHY at %p", 211510696SDavid.Hollister@Sun.COM (void *)phyp->parent); 211610696SDavid.Hollister@Sun.COM return (NULL); 211710696SDavid.Hollister@Sun.COM } 211810696SDavid.Hollister@Sun.COM 211910696SDavid.Hollister@Sun.COM if (parent.sibling != NULL) { 212010696SDavid.Hollister@Sun.COM break; 212110696SDavid.Hollister@Sun.COM } 212210696SDavid.Hollister@Sun.COM 212311898SJesse.Butler@Sun.COM /* 212411898SJesse.Butler@Sun.COM * If this PHY's sibling is NULL and it's a root phy, 212511898SJesse.Butler@Sun.COM * we're done. 212611898SJesse.Butler@Sun.COM */ 212711898SJesse.Butler@Sun.COM if (parent.level == 0) { 212811898SJesse.Butler@Sun.COM return (NULL); 212911898SJesse.Butler@Sun.COM } 213011898SJesse.Butler@Sun.COM 213110696SDavid.Hollister@Sun.COM phyp = phyp->parent; 213210696SDavid.Hollister@Sun.COM } 213310696SDavid.Hollister@Sun.COM 213410696SDavid.Hollister@Sun.COM return (parent.sibling); 213510696SDavid.Hollister@Sun.COM } 213610696SDavid.Hollister@Sun.COM 213710696SDavid.Hollister@Sun.COM static int 213810696SDavid.Hollister@Sun.COM phy_walk_i(mdb_walk_state_t *wsp) 213910696SDavid.Hollister@Sun.COM { 214010696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 214110696SDavid.Hollister@Sun.COM mdb_warn("Can not perform global walk\n"); 214210696SDavid.Hollister@Sun.COM return (WALK_ERR); 214310696SDavid.Hollister@Sun.COM } 214410696SDavid.Hollister@Sun.COM 214510696SDavid.Hollister@Sun.COM /* 214610696SDavid.Hollister@Sun.COM * Address provided belongs to HBA softstate. Get the targets pointer 214710696SDavid.Hollister@Sun.COM * to begin the walk. 214810696SDavid.Hollister@Sun.COM */ 214910696SDavid.Hollister@Sun.COM if (mdb_vread(&ss, sizeof (pmcs_hw_t), wsp->walk_addr) != 215010696SDavid.Hollister@Sun.COM sizeof (pmcs_hw_t)) { 215110696SDavid.Hollister@Sun.COM mdb_warn("Unable to read HBA softstate\n"); 215210696SDavid.Hollister@Sun.COM return (WALK_ERR); 215310696SDavid.Hollister@Sun.COM } 215410696SDavid.Hollister@Sun.COM 215510696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(ss.root_phys); 215610696SDavid.Hollister@Sun.COM wsp->walk_data = mdb_alloc(sizeof (pmcs_phy_t), UM_SLEEP); 215710696SDavid.Hollister@Sun.COM 215810696SDavid.Hollister@Sun.COM return (WALK_NEXT); 215910696SDavid.Hollister@Sun.COM } 216010696SDavid.Hollister@Sun.COM 216110696SDavid.Hollister@Sun.COM static int 216210696SDavid.Hollister@Sun.COM phy_walk_s(mdb_walk_state_t *wsp) 216310696SDavid.Hollister@Sun.COM { 216410696SDavid.Hollister@Sun.COM pmcs_phy_t *phyp, *nphyp; 216510696SDavid.Hollister@Sun.COM int status; 216610696SDavid.Hollister@Sun.COM 216710696SDavid.Hollister@Sun.COM if (mdb_vread(wsp->walk_data, sizeof (pmcs_phy_t), 216810696SDavid.Hollister@Sun.COM wsp->walk_addr) == -1) { 216910696SDavid.Hollister@Sun.COM mdb_warn("phy_walk_s: Failed to read PHY at %p", 217010696SDavid.Hollister@Sun.COM (void *)wsp->walk_addr); 217110696SDavid.Hollister@Sun.COM return (WALK_DONE); 217210696SDavid.Hollister@Sun.COM } 217310696SDavid.Hollister@Sun.COM 217410696SDavid.Hollister@Sun.COM status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 217510696SDavid.Hollister@Sun.COM wsp->walk_cbdata); 217610696SDavid.Hollister@Sun.COM 217710696SDavid.Hollister@Sun.COM phyp = (pmcs_phy_t *)wsp->walk_data; 217810696SDavid.Hollister@Sun.COM if (phyp->children) { 217910696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(phyp->children); 218010696SDavid.Hollister@Sun.COM } else { 218110696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(phyp->sibling); 218210696SDavid.Hollister@Sun.COM } 218310696SDavid.Hollister@Sun.COM 218410696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 218510696SDavid.Hollister@Sun.COM /* 218610696SDavid.Hollister@Sun.COM * We reached the end of this sibling list. Trudge back up 218710696SDavid.Hollister@Sun.COM * to the parent and find the next sibling after the expander 218810696SDavid.Hollister@Sun.COM * we just finished traversing, if there is one. 218910696SDavid.Hollister@Sun.COM */ 219010696SDavid.Hollister@Sun.COM nphyp = pmcs_next_sibling(phyp); 219110696SDavid.Hollister@Sun.COM 219210696SDavid.Hollister@Sun.COM if (nphyp == NULL) { 219310696SDavid.Hollister@Sun.COM return (WALK_DONE); 219410696SDavid.Hollister@Sun.COM } 219510696SDavid.Hollister@Sun.COM 219610696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)nphyp; 219710696SDavid.Hollister@Sun.COM } 219810696SDavid.Hollister@Sun.COM 219910696SDavid.Hollister@Sun.COM return (status); 220010696SDavid.Hollister@Sun.COM } 220110696SDavid.Hollister@Sun.COM 220210696SDavid.Hollister@Sun.COM static void 220310696SDavid.Hollister@Sun.COM phy_walk_f(mdb_walk_state_t *wsp) 220410696SDavid.Hollister@Sun.COM { 220510696SDavid.Hollister@Sun.COM mdb_free(wsp->walk_data, sizeof (pmcs_phy_t)); 220610696SDavid.Hollister@Sun.COM } 220710696SDavid.Hollister@Sun.COM 220810743SDavid.Hollister@Sun.COM static void 220910743SDavid.Hollister@Sun.COM display_matching_work(struct pmcs_hw ss, uintmax_t index, uintmax_t snum, 221010743SDavid.Hollister@Sun.COM uintmax_t tag_type) 221110743SDavid.Hollister@Sun.COM { 221210743SDavid.Hollister@Sun.COM int idx; 221310743SDavid.Hollister@Sun.COM pmcwork_t work, *wp = &work; 221410743SDavid.Hollister@Sun.COM uintptr_t _wp; 221510743SDavid.Hollister@Sun.COM boolean_t printed_header = B_FALSE; 221610743SDavid.Hollister@Sun.COM uint32_t mask, mask_val, match_val; 221710743SDavid.Hollister@Sun.COM char *match_type; 221810743SDavid.Hollister@Sun.COM 221910743SDavid.Hollister@Sun.COM if (index != UINT_MAX) { 222010743SDavid.Hollister@Sun.COM match_type = "index"; 222110743SDavid.Hollister@Sun.COM mask = PMCS_TAG_INDEX_MASK; 222210743SDavid.Hollister@Sun.COM mask_val = index << PMCS_TAG_INDEX_SHIFT; 222310743SDavid.Hollister@Sun.COM match_val = index; 222410743SDavid.Hollister@Sun.COM } else if (snum != UINT_MAX) { 222510743SDavid.Hollister@Sun.COM match_type = "serial number"; 222610743SDavid.Hollister@Sun.COM mask = PMCS_TAG_SERNO_MASK; 222710743SDavid.Hollister@Sun.COM mask_val = snum << PMCS_TAG_SERNO_SHIFT; 222810743SDavid.Hollister@Sun.COM match_val = snum; 222910743SDavid.Hollister@Sun.COM } else { 223010743SDavid.Hollister@Sun.COM switch (tag_type) { 223110743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_NONE: 223210743SDavid.Hollister@Sun.COM match_type = "tag type NONE"; 223310743SDavid.Hollister@Sun.COM break; 223410743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_CBACK: 223510743SDavid.Hollister@Sun.COM match_type = "tag type CBACK"; 223610743SDavid.Hollister@Sun.COM break; 223710743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_WAIT: 223810743SDavid.Hollister@Sun.COM match_type = "tag type WAIT"; 223910743SDavid.Hollister@Sun.COM break; 224010743SDavid.Hollister@Sun.COM } 224110743SDavid.Hollister@Sun.COM mask = PMCS_TAG_TYPE_MASK; 224210743SDavid.Hollister@Sun.COM mask_val = tag_type << PMCS_TAG_TYPE_SHIFT; 224310743SDavid.Hollister@Sun.COM match_val = tag_type; 224410743SDavid.Hollister@Sun.COM } 224510743SDavid.Hollister@Sun.COM 224610743SDavid.Hollister@Sun.COM _wp = (uintptr_t)ss.work; 224710743SDavid.Hollister@Sun.COM 224810743SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.max_cmd; idx++, _wp += sizeof (pmcwork_t)) { 224910743SDavid.Hollister@Sun.COM if (MDB_RD(&work, sizeof (pmcwork_t), _wp) == -1) { 225010743SDavid.Hollister@Sun.COM NOREAD(pmcwork_t, _wp); 225110743SDavid.Hollister@Sun.COM continue; 225210743SDavid.Hollister@Sun.COM } 225310743SDavid.Hollister@Sun.COM 225410743SDavid.Hollister@Sun.COM if ((work.htag & mask) != mask_val) { 225510743SDavid.Hollister@Sun.COM continue; 225610743SDavid.Hollister@Sun.COM } 225710743SDavid.Hollister@Sun.COM 225810743SDavid.Hollister@Sun.COM if (printed_header == B_FALSE) { 225910743SDavid.Hollister@Sun.COM if (tag_type) { 226010743SDavid.Hollister@Sun.COM mdb_printf("\nWork structures matching %s\n\n", 226110743SDavid.Hollister@Sun.COM match_type, match_val); 226210743SDavid.Hollister@Sun.COM } else { 226310743SDavid.Hollister@Sun.COM mdb_printf("\nWork structures matching %s of " 226410743SDavid.Hollister@Sun.COM "0x%x\n\n", match_type, match_val); 226510743SDavid.Hollister@Sun.COM } 226610743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D\n", 226710743SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 226810743SDavid.Hollister@Sun.COM printed_header = B_TRUE; 226910743SDavid.Hollister@Sun.COM } 227010743SDavid.Hollister@Sun.COM 227110743SDavid.Hollister@Sun.COM display_one_work(wp, 0, 0); 227210743SDavid.Hollister@Sun.COM } 227310743SDavid.Hollister@Sun.COM 227410743SDavid.Hollister@Sun.COM if (!printed_header) { 227510743SDavid.Hollister@Sun.COM mdb_printf("No work structure matches found\n"); 227610743SDavid.Hollister@Sun.COM } 227710743SDavid.Hollister@Sun.COM } 227810743SDavid.Hollister@Sun.COM 227910743SDavid.Hollister@Sun.COM static int 228010743SDavid.Hollister@Sun.COM pmcs_tag(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 228110743SDavid.Hollister@Sun.COM { 228210743SDavid.Hollister@Sun.COM struct pmcs_hw ss; 228310743SDavid.Hollister@Sun.COM uintmax_t tag_type = UINT_MAX; 228410743SDavid.Hollister@Sun.COM uintmax_t snum = UINT_MAX; 228510743SDavid.Hollister@Sun.COM uintmax_t index = UINT_MAX; 228610743SDavid.Hollister@Sun.COM int args = 0; 228710743SDavid.Hollister@Sun.COM void *pmcs_state; 228810743SDavid.Hollister@Sun.COM char *state_str; 228910743SDavid.Hollister@Sun.COM struct dev_info dip; 229010743SDavid.Hollister@Sun.COM 229110743SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 229210743SDavid.Hollister@Sun.COM pmcs_state = NULL; 229310743SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 229410743SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 229510743SDavid.Hollister@Sun.COM return (DCMD_ERR); 229610743SDavid.Hollister@Sun.COM } 229710743SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_tag", argc, 229810743SDavid.Hollister@Sun.COM argv, (uintptr_t)pmcs_state) == -1) { 229910743SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed"); 230010743SDavid.Hollister@Sun.COM return (DCMD_ERR); 230110743SDavid.Hollister@Sun.COM } 230210743SDavid.Hollister@Sun.COM return (DCMD_OK); 230310743SDavid.Hollister@Sun.COM } 230410743SDavid.Hollister@Sun.COM 230510743SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 230610743SDavid.Hollister@Sun.COM 'i', MDB_OPT_UINT64, &index, 230710743SDavid.Hollister@Sun.COM 's', MDB_OPT_UINT64, &snum, 230810743SDavid.Hollister@Sun.COM 't', MDB_OPT_UINT64, &tag_type) != argc) 230910743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 231010743SDavid.Hollister@Sun.COM 231110743SDavid.Hollister@Sun.COM /* 231210743SDavid.Hollister@Sun.COM * Count the number of supplied options and make sure they are 231310743SDavid.Hollister@Sun.COM * within appropriate ranges. If they're set to UINT_MAX, that means 231410743SDavid.Hollister@Sun.COM * they were not supplied, in which case reset them to 0. 231510743SDavid.Hollister@Sun.COM */ 231610743SDavid.Hollister@Sun.COM if (index != UINT_MAX) { 231710743SDavid.Hollister@Sun.COM args++; 231810743SDavid.Hollister@Sun.COM if (index > PMCS_TAG_INDEX_MASK) { 231910743SDavid.Hollister@Sun.COM mdb_warn("Index is out of range\n"); 232010743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 232110743SDavid.Hollister@Sun.COM } 232210743SDavid.Hollister@Sun.COM } 232310743SDavid.Hollister@Sun.COM 232410743SDavid.Hollister@Sun.COM if (tag_type != UINT_MAX) { 232510743SDavid.Hollister@Sun.COM args++; 232610743SDavid.Hollister@Sun.COM switch (tag_type) { 232710743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_NONE: 232810743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_CBACK: 232910743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_WAIT: 233010743SDavid.Hollister@Sun.COM break; 233110743SDavid.Hollister@Sun.COM default: 233210743SDavid.Hollister@Sun.COM mdb_warn("Invalid tag type\n"); 233310743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 233410743SDavid.Hollister@Sun.COM } 233510743SDavid.Hollister@Sun.COM } 233610743SDavid.Hollister@Sun.COM 233710743SDavid.Hollister@Sun.COM if (snum != UINT_MAX) { 233810743SDavid.Hollister@Sun.COM args++; 233910743SDavid.Hollister@Sun.COM if (snum > (PMCS_TAG_SERNO_MASK >> PMCS_TAG_SERNO_SHIFT)) { 234010743SDavid.Hollister@Sun.COM mdb_warn("Serial number is out of range\n"); 234110743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 234210743SDavid.Hollister@Sun.COM } 234310743SDavid.Hollister@Sun.COM } 234410743SDavid.Hollister@Sun.COM 234510743SDavid.Hollister@Sun.COM /* 234610743SDavid.Hollister@Sun.COM * Make sure 1 and only 1 option is specified 234710743SDavid.Hollister@Sun.COM */ 234810743SDavid.Hollister@Sun.COM if ((args == 0) || (args > 1)) { 234910743SDavid.Hollister@Sun.COM mdb_warn("Exactly one of -i, -s and -t must be specified\n"); 235010743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 235110743SDavid.Hollister@Sun.COM } 235210743SDavid.Hollister@Sun.COM 235310743SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 235410743SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 235510743SDavid.Hollister@Sun.COM return (DCMD_ERR); 235610743SDavid.Hollister@Sun.COM } 235710743SDavid.Hollister@Sun.COM 235810743SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 235910743SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 236010743SDavid.Hollister@Sun.COM return (DCMD_ERR); 236110743SDavid.Hollister@Sun.COM } 236210743SDavid.Hollister@Sun.COM 236310743SDavid.Hollister@Sun.COM /* processing completed */ 236410743SDavid.Hollister@Sun.COM 236510743SDavid.Hollister@Sun.COM if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) || 236610743SDavid.Hollister@Sun.COM (flags & DCMD_LOOPFIRST)) { 236710743SDavid.Hollister@Sun.COM if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST)) 236810743SDavid.Hollister@Sun.COM mdb_printf("\n"); 236910743SDavid.Hollister@Sun.COM mdb_printf("%16s %9s %4s B C WorkFlags wserno DbgMsk %16s\n", 237010743SDavid.Hollister@Sun.COM "Address", "State", "Inst", "DIP"); 237110743SDavid.Hollister@Sun.COM mdb_printf("=================================" 237210743SDavid.Hollister@Sun.COM "============================================\n"); 237310743SDavid.Hollister@Sun.COM } 237410743SDavid.Hollister@Sun.COM 237510743SDavid.Hollister@Sun.COM switch (ss.state) { 237610743SDavid.Hollister@Sun.COM case STATE_NIL: 237710743SDavid.Hollister@Sun.COM state_str = "Invalid"; 237810743SDavid.Hollister@Sun.COM break; 237910743SDavid.Hollister@Sun.COM case STATE_PROBING: 238010743SDavid.Hollister@Sun.COM state_str = "Probing"; 238110743SDavid.Hollister@Sun.COM break; 238210743SDavid.Hollister@Sun.COM case STATE_RUNNING: 238310743SDavid.Hollister@Sun.COM state_str = "Running"; 238410743SDavid.Hollister@Sun.COM break; 238510743SDavid.Hollister@Sun.COM case STATE_UNPROBING: 238610743SDavid.Hollister@Sun.COM state_str = "Unprobing"; 238710743SDavid.Hollister@Sun.COM break; 238810743SDavid.Hollister@Sun.COM case STATE_DEAD: 238910743SDavid.Hollister@Sun.COM state_str = "Dead"; 239010743SDavid.Hollister@Sun.COM break; 239111692SJesse.Butler@Sun.COM case STATE_IN_RESET: 239211692SJesse.Butler@Sun.COM state_str = "In Reset"; 239311692SJesse.Butler@Sun.COM break; 239410743SDavid.Hollister@Sun.COM } 239510743SDavid.Hollister@Sun.COM 239610743SDavid.Hollister@Sun.COM mdb_printf("%16p %9s %4d %1d %1d 0x%08x 0x%04x 0x%04x %16p\n", addr, 239710743SDavid.Hollister@Sun.COM state_str, dip.devi_instance, ss.blocked, ss.configuring, 239810743SDavid.Hollister@Sun.COM ss.work_flags, ss.wserno, ss.debug_mask, ss.dip); 239910743SDavid.Hollister@Sun.COM mdb_printf("\n"); 240010743SDavid.Hollister@Sun.COM 240110743SDavid.Hollister@Sun.COM mdb_inc_indent(4); 240210743SDavid.Hollister@Sun.COM display_matching_work(ss, index, snum, tag_type); 240310743SDavid.Hollister@Sun.COM mdb_dec_indent(4); 240410743SDavid.Hollister@Sun.COM mdb_printf("\n"); 240510743SDavid.Hollister@Sun.COM 240610743SDavid.Hollister@Sun.COM return (DCMD_OK); 240710743SDavid.Hollister@Sun.COM } 240810743SDavid.Hollister@Sun.COM 240911694SDavid.Hollister@Sun.COM #ifndef _KMDB 241011694SDavid.Hollister@Sun.COM static int 241111694SDavid.Hollister@Sun.COM pmcs_dump_fwlog(struct pmcs_hw *ss, int instance, const char *ofile) 241211694SDavid.Hollister@Sun.COM { 241311694SDavid.Hollister@Sun.COM uint8_t *fwlogp; 241411694SDavid.Hollister@Sun.COM int ofilefd = -1; 241511694SDavid.Hollister@Sun.COM char ofilename[MAXPATHLEN]; 241611694SDavid.Hollister@Sun.COM int rval = DCMD_OK; 241711694SDavid.Hollister@Sun.COM 241811694SDavid.Hollister@Sun.COM if (ss->fwlogp == NULL) { 241911694SDavid.Hollister@Sun.COM mdb_warn("Firmware event log disabled for instance %d", 242011694SDavid.Hollister@Sun.COM instance); 242111694SDavid.Hollister@Sun.COM return (DCMD_OK); 242211694SDavid.Hollister@Sun.COM } 242311694SDavid.Hollister@Sun.COM 242411694SDavid.Hollister@Sun.COM if (snprintf(ofilename, MAXPATHLEN, "%s%d", ofile, instance) > 242511694SDavid.Hollister@Sun.COM MAXPATHLEN) { 242611694SDavid.Hollister@Sun.COM mdb_warn("Output filename is too long for instance %d", 242711694SDavid.Hollister@Sun.COM instance); 242811694SDavid.Hollister@Sun.COM return (DCMD_ERR); 242911694SDavid.Hollister@Sun.COM } 243011694SDavid.Hollister@Sun.COM 243111694SDavid.Hollister@Sun.COM fwlogp = mdb_alloc(PMCS_FWLOG_SIZE, UM_SLEEP); 243211694SDavid.Hollister@Sun.COM 243311694SDavid.Hollister@Sun.COM if (MDB_RD(fwlogp, PMCS_FWLOG_SIZE, ss->fwlogp) == -1) { 243411694SDavid.Hollister@Sun.COM NOREAD(fwlogp, ss->fwlogp); 243511694SDavid.Hollister@Sun.COM rval = DCMD_ERR; 243611694SDavid.Hollister@Sun.COM goto cleanup; 243711694SDavid.Hollister@Sun.COM } 243811694SDavid.Hollister@Sun.COM 243911694SDavid.Hollister@Sun.COM ofilefd = open(ofilename, O_WRONLY | O_CREAT, 244011694SDavid.Hollister@Sun.COM S_IRUSR | S_IRGRP | S_IROTH); 244111694SDavid.Hollister@Sun.COM if (ofilefd < 0) { 244211694SDavid.Hollister@Sun.COM mdb_warn("Unable to open '%s' to dump instance %d event log", 244311694SDavid.Hollister@Sun.COM ofilename, instance); 244411694SDavid.Hollister@Sun.COM rval = DCMD_ERR; 244511694SDavid.Hollister@Sun.COM goto cleanup; 244611694SDavid.Hollister@Sun.COM } 244711694SDavid.Hollister@Sun.COM 244811694SDavid.Hollister@Sun.COM if (write(ofilefd, fwlogp, PMCS_FWLOG_SIZE) != PMCS_FWLOG_SIZE) { 244911694SDavid.Hollister@Sun.COM mdb_warn("Failed to write %d bytes to output file: instance %d", 245011694SDavid.Hollister@Sun.COM PMCS_FWLOG_SIZE, instance); 245111694SDavid.Hollister@Sun.COM rval = DCMD_ERR; 245211694SDavid.Hollister@Sun.COM goto cleanup; 245311694SDavid.Hollister@Sun.COM } 245411694SDavid.Hollister@Sun.COM 245511694SDavid.Hollister@Sun.COM mdb_printf("Event log for instance %d written to %s\n", instance, 245611694SDavid.Hollister@Sun.COM ofilename); 245711694SDavid.Hollister@Sun.COM 245811694SDavid.Hollister@Sun.COM cleanup: 245911694SDavid.Hollister@Sun.COM if (ofilefd >= 0) { 246011694SDavid.Hollister@Sun.COM close(ofilefd); 246111694SDavid.Hollister@Sun.COM } 246211694SDavid.Hollister@Sun.COM mdb_free(fwlogp, PMCS_FWLOG_SIZE); 246311694SDavid.Hollister@Sun.COM return (rval); 246411694SDavid.Hollister@Sun.COM } 246511694SDavid.Hollister@Sun.COM 246611694SDavid.Hollister@Sun.COM static int 246711694SDavid.Hollister@Sun.COM pmcs_fwlog(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 246811694SDavid.Hollister@Sun.COM { 246911694SDavid.Hollister@Sun.COM void *pmcs_state; 247011694SDavid.Hollister@Sun.COM const char *ofile = NULL; 247111694SDavid.Hollister@Sun.COM struct pmcs_hw ss; 247211694SDavid.Hollister@Sun.COM struct dev_info dip; 247311694SDavid.Hollister@Sun.COM 247411694SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 'o', MDB_OPT_STR, &ofile, NULL) != argc) { 247511694SDavid.Hollister@Sun.COM return (DCMD_USAGE); 247611694SDavid.Hollister@Sun.COM } 247711694SDavid.Hollister@Sun.COM 247811694SDavid.Hollister@Sun.COM if (ofile == NULL) { 247911694SDavid.Hollister@Sun.COM mdb_printf("No output file specified\n"); 248011694SDavid.Hollister@Sun.COM return (DCMD_USAGE); 248111694SDavid.Hollister@Sun.COM } 248211694SDavid.Hollister@Sun.COM 248311694SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 248411694SDavid.Hollister@Sun.COM pmcs_state = NULL; 248511694SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 248611694SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 248711694SDavid.Hollister@Sun.COM return (DCMD_ERR); 248811694SDavid.Hollister@Sun.COM } 248911694SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_fwlog", argc, 249011694SDavid.Hollister@Sun.COM argv, (uintptr_t)pmcs_state) == -1) { 249111694SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed for pmcs_log"); 249211694SDavid.Hollister@Sun.COM return (DCMD_ERR); 249311694SDavid.Hollister@Sun.COM } 249411694SDavid.Hollister@Sun.COM return (DCMD_OK); 249511694SDavid.Hollister@Sun.COM } 249611694SDavid.Hollister@Sun.COM 249711694SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 249811694SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 249911694SDavid.Hollister@Sun.COM return (DCMD_ERR); 250011694SDavid.Hollister@Sun.COM } 250111694SDavid.Hollister@Sun.COM 250211694SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 250311694SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 250411694SDavid.Hollister@Sun.COM return (DCMD_ERR); 250511694SDavid.Hollister@Sun.COM } 250611694SDavid.Hollister@Sun.COM 250711694SDavid.Hollister@Sun.COM return (pmcs_dump_fwlog(&ss, dip.devi_instance, ofile)); 250811694SDavid.Hollister@Sun.COM } 250911694SDavid.Hollister@Sun.COM #endif /* _KMDB */ 251011694SDavid.Hollister@Sun.COM 251110696SDavid.Hollister@Sun.COM static int 251211048SDavid.Hollister@Sun.COM pmcs_log(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 251311048SDavid.Hollister@Sun.COM { 251411048SDavid.Hollister@Sun.COM void *pmcs_state; 251511048SDavid.Hollister@Sun.COM struct pmcs_hw ss; 251611048SDavid.Hollister@Sun.COM struct dev_info dip; 251711048SDavid.Hollister@Sun.COM const char *match_phy_path = NULL; 251811347SRamana.Srikanth@Sun.COM uint64_t match_sas_address = 0, tail_lines = 0; 251911048SDavid.Hollister@Sun.COM 252011048SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 252111048SDavid.Hollister@Sun.COM pmcs_state = NULL; 252211048SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 252311048SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 252411048SDavid.Hollister@Sun.COM return (DCMD_ERR); 252511048SDavid.Hollister@Sun.COM } 252611048SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_log", argc, 252711048SDavid.Hollister@Sun.COM argv, (uintptr_t)pmcs_state) == -1) { 252811048SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed for pmcs_log"); 252911048SDavid.Hollister@Sun.COM return (DCMD_ERR); 253011048SDavid.Hollister@Sun.COM } 253111048SDavid.Hollister@Sun.COM return (DCMD_OK); 253211048SDavid.Hollister@Sun.COM } 253311048SDavid.Hollister@Sun.COM 253411048SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 253511347SRamana.Srikanth@Sun.COM 'l', MDB_OPT_UINT64, &tail_lines, 253611048SDavid.Hollister@Sun.COM 'p', MDB_OPT_STR, &match_phy_path, 253711048SDavid.Hollister@Sun.COM 's', MDB_OPT_UINT64, &match_sas_address, 253811048SDavid.Hollister@Sun.COM NULL) != argc) { 253911048SDavid.Hollister@Sun.COM return (DCMD_USAGE); 254011048SDavid.Hollister@Sun.COM } 254111048SDavid.Hollister@Sun.COM 254211048SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 254311048SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 254411048SDavid.Hollister@Sun.COM return (DCMD_ERR); 254511048SDavid.Hollister@Sun.COM } 254611048SDavid.Hollister@Sun.COM 254711048SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 254811048SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 254911048SDavid.Hollister@Sun.COM return (DCMD_ERR); 255011048SDavid.Hollister@Sun.COM } 255111048SDavid.Hollister@Sun.COM 255211048SDavid.Hollister@Sun.COM if (!(flags & DCMD_LOOP)) { 255311048SDavid.Hollister@Sun.COM return (pmcs_dump_tracelog(B_TRUE, dip.devi_instance, 255411347SRamana.Srikanth@Sun.COM tail_lines, match_phy_path, match_sas_address)); 255511048SDavid.Hollister@Sun.COM } else if (flags & DCMD_LOOPFIRST) { 255611347SRamana.Srikanth@Sun.COM return (pmcs_dump_tracelog(B_FALSE, 0, tail_lines, 255711347SRamana.Srikanth@Sun.COM match_phy_path, match_sas_address)); 255811048SDavid.Hollister@Sun.COM } else { 255911048SDavid.Hollister@Sun.COM return (DCMD_OK); 256011048SDavid.Hollister@Sun.COM } 256111048SDavid.Hollister@Sun.COM } 256211048SDavid.Hollister@Sun.COM 256311048SDavid.Hollister@Sun.COM static int 256410696SDavid.Hollister@Sun.COM pmcs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 256510696SDavid.Hollister@Sun.COM { 256611048SDavid.Hollister@Sun.COM struct pmcs_hw ss; 256710696SDavid.Hollister@Sun.COM uint_t verbose = FALSE; 256810696SDavid.Hollister@Sun.COM uint_t phy_info = FALSE; 256910696SDavid.Hollister@Sun.COM uint_t hw_info = FALSE; 257010696SDavid.Hollister@Sun.COM uint_t target_info = FALSE; 257110696SDavid.Hollister@Sun.COM uint_t work_info = FALSE; 257210696SDavid.Hollister@Sun.COM uint_t ic_info = FALSE; 257310696SDavid.Hollister@Sun.COM uint_t iport_info = FALSE; 257410696SDavid.Hollister@Sun.COM uint_t waitqs_info = FALSE; 257510696SDavid.Hollister@Sun.COM uint_t ibq = FALSE; 257610696SDavid.Hollister@Sun.COM uint_t obq = FALSE; 257710696SDavid.Hollister@Sun.COM uint_t tgt_phy_count = FALSE; 257810743SDavid.Hollister@Sun.COM uint_t compq = FALSE; 257911048SDavid.Hollister@Sun.COM uint_t unconfigured = FALSE; 258011334SReed.Liu@Sun.COM uint_t damap_info = FALSE; 258111334SReed.Liu@Sun.COM uint_t dtc_info = FALSE; 258210696SDavid.Hollister@Sun.COM int rv = DCMD_OK; 258310696SDavid.Hollister@Sun.COM void *pmcs_state; 258410696SDavid.Hollister@Sun.COM char *state_str; 258510696SDavid.Hollister@Sun.COM struct dev_info dip; 258611334SReed.Liu@Sun.COM per_iport_setting_t pis; 258710696SDavid.Hollister@Sun.COM 258810696SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 258910696SDavid.Hollister@Sun.COM pmcs_state = NULL; 259010696SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 259110696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 259210696SDavid.Hollister@Sun.COM return (DCMD_ERR); 259310696SDavid.Hollister@Sun.COM } 259410696SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs", argc, argv, 259510696SDavid.Hollister@Sun.COM (uintptr_t)pmcs_state) == -1) { 259610696SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed"); 259710696SDavid.Hollister@Sun.COM return (DCMD_ERR); 259810696SDavid.Hollister@Sun.COM } 259910696SDavid.Hollister@Sun.COM return (DCMD_OK); 260010696SDavid.Hollister@Sun.COM } 260110696SDavid.Hollister@Sun.COM 260210696SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 260310743SDavid.Hollister@Sun.COM 'c', MDB_OPT_SETBITS, TRUE, &compq, 260411334SReed.Liu@Sun.COM 'd', MDB_OPT_SETBITS, TRUE, &dtc_info, 260510696SDavid.Hollister@Sun.COM 'h', MDB_OPT_SETBITS, TRUE, &hw_info, 260610696SDavid.Hollister@Sun.COM 'i', MDB_OPT_SETBITS, TRUE, &ic_info, 260710696SDavid.Hollister@Sun.COM 'I', MDB_OPT_SETBITS, TRUE, &iport_info, 260811334SReed.Liu@Sun.COM 'm', MDB_OPT_SETBITS, TRUE, &damap_info, 260910696SDavid.Hollister@Sun.COM 'p', MDB_OPT_SETBITS, TRUE, &phy_info, 261010696SDavid.Hollister@Sun.COM 'q', MDB_OPT_SETBITS, TRUE, &ibq, 261110696SDavid.Hollister@Sun.COM 'Q', MDB_OPT_SETBITS, TRUE, &obq, 261210696SDavid.Hollister@Sun.COM 't', MDB_OPT_SETBITS, TRUE, &target_info, 261310696SDavid.Hollister@Sun.COM 'T', MDB_OPT_SETBITS, TRUE, &tgt_phy_count, 261411048SDavid.Hollister@Sun.COM 'u', MDB_OPT_SETBITS, TRUE, &unconfigured, 261510696SDavid.Hollister@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose, 261610696SDavid.Hollister@Sun.COM 'w', MDB_OPT_SETBITS, TRUE, &work_info, 261710696SDavid.Hollister@Sun.COM 'W', MDB_OPT_SETBITS, TRUE, &waitqs_info, 261810696SDavid.Hollister@Sun.COM NULL) != argc) 261910696SDavid.Hollister@Sun.COM return (DCMD_USAGE); 262010696SDavid.Hollister@Sun.COM 262111334SReed.Liu@Sun.COM /* 262211334SReed.Liu@Sun.COM * The 'd' and 'm' options implicitly enable the 'I' option 262311334SReed.Liu@Sun.COM */ 262411334SReed.Liu@Sun.COM pis.pis_damap_info = damap_info; 262511334SReed.Liu@Sun.COM pis.pis_dtc_info = dtc_info; 262611334SReed.Liu@Sun.COM if (damap_info || dtc_info) { 262711334SReed.Liu@Sun.COM iport_info = TRUE; 262811334SReed.Liu@Sun.COM } 262911334SReed.Liu@Sun.COM 263010696SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 263110696SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 263210696SDavid.Hollister@Sun.COM return (DCMD_ERR); 263310696SDavid.Hollister@Sun.COM } 263410696SDavid.Hollister@Sun.COM 263510696SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 263610696SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 263710696SDavid.Hollister@Sun.COM return (DCMD_ERR); 263810696SDavid.Hollister@Sun.COM } 263910696SDavid.Hollister@Sun.COM 264010696SDavid.Hollister@Sun.COM /* processing completed */ 264110696SDavid.Hollister@Sun.COM 264210696SDavid.Hollister@Sun.COM if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) || 264310696SDavid.Hollister@Sun.COM (flags & DCMD_LOOPFIRST) || phy_info || target_info || hw_info || 264411048SDavid.Hollister@Sun.COM work_info || waitqs_info || ibq || obq || tgt_phy_count || compq || 264511048SDavid.Hollister@Sun.COM unconfigured) { 264610696SDavid.Hollister@Sun.COM if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST)) 264710696SDavid.Hollister@Sun.COM mdb_printf("\n"); 264810696SDavid.Hollister@Sun.COM mdb_printf("%16s %9s %4s B C WorkFlags wserno DbgMsk %16s\n", 264910696SDavid.Hollister@Sun.COM "Address", "State", "Inst", "DIP"); 265010696SDavid.Hollister@Sun.COM mdb_printf("=================================" 265110696SDavid.Hollister@Sun.COM "============================================\n"); 265210696SDavid.Hollister@Sun.COM } 265310696SDavid.Hollister@Sun.COM 265410696SDavid.Hollister@Sun.COM switch (ss.state) { 265510696SDavid.Hollister@Sun.COM case STATE_NIL: 265610696SDavid.Hollister@Sun.COM state_str = "Invalid"; 265710696SDavid.Hollister@Sun.COM break; 265810696SDavid.Hollister@Sun.COM case STATE_PROBING: 265910696SDavid.Hollister@Sun.COM state_str = "Probing"; 266010696SDavid.Hollister@Sun.COM break; 266110696SDavid.Hollister@Sun.COM case STATE_RUNNING: 266210696SDavid.Hollister@Sun.COM state_str = "Running"; 266310696SDavid.Hollister@Sun.COM break; 266410696SDavid.Hollister@Sun.COM case STATE_UNPROBING: 266510696SDavid.Hollister@Sun.COM state_str = "Unprobing"; 266610696SDavid.Hollister@Sun.COM break; 266710696SDavid.Hollister@Sun.COM case STATE_DEAD: 266810696SDavid.Hollister@Sun.COM state_str = "Dead"; 266910696SDavid.Hollister@Sun.COM break; 267011692SJesse.Butler@Sun.COM case STATE_IN_RESET: 267111692SJesse.Butler@Sun.COM state_str = "In Reset"; 267211692SJesse.Butler@Sun.COM break; 267310696SDavid.Hollister@Sun.COM } 267410696SDavid.Hollister@Sun.COM 267510696SDavid.Hollister@Sun.COM mdb_printf("%16p %9s %4d %1d %1d 0x%08x 0x%04x 0x%04x %16p\n", addr, 267610696SDavid.Hollister@Sun.COM state_str, dip.devi_instance, ss.blocked, ss.configuring, 267710696SDavid.Hollister@Sun.COM ss.work_flags, ss.wserno, ss.debug_mask, ss.dip); 267810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 267910696SDavid.Hollister@Sun.COM 268010696SDavid.Hollister@Sun.COM mdb_inc_indent(4); 268110696SDavid.Hollister@Sun.COM 268210696SDavid.Hollister@Sun.COM if (waitqs_info) 268310696SDavid.Hollister@Sun.COM display_waitqs(ss, verbose); 268410696SDavid.Hollister@Sun.COM 268510696SDavid.Hollister@Sun.COM if (hw_info) 268610696SDavid.Hollister@Sun.COM display_hwinfo(ss, verbose); 268710696SDavid.Hollister@Sun.COM 268810696SDavid.Hollister@Sun.COM if (phy_info || tgt_phy_count) 268910696SDavid.Hollister@Sun.COM display_phys(ss, verbose, NULL, 0, tgt_phy_count); 269010696SDavid.Hollister@Sun.COM 269110696SDavid.Hollister@Sun.COM if (target_info || tgt_phy_count) 269210696SDavid.Hollister@Sun.COM display_targets(ss, verbose, tgt_phy_count); 269310696SDavid.Hollister@Sun.COM 269410696SDavid.Hollister@Sun.COM if (work_info) 269510696SDavid.Hollister@Sun.COM display_work(ss, verbose); 269610696SDavid.Hollister@Sun.COM 269710696SDavid.Hollister@Sun.COM if (ic_info) 269810696SDavid.Hollister@Sun.COM display_ic(ss, verbose); 269910696SDavid.Hollister@Sun.COM 270010696SDavid.Hollister@Sun.COM if (ibq) 270110696SDavid.Hollister@Sun.COM display_inbound_queues(ss, verbose); 270210696SDavid.Hollister@Sun.COM 270310696SDavid.Hollister@Sun.COM if (obq) 270410696SDavid.Hollister@Sun.COM display_outbound_queues(ss, verbose); 270510696SDavid.Hollister@Sun.COM 270610696SDavid.Hollister@Sun.COM if (iport_info) 270711334SReed.Liu@Sun.COM display_iport(ss, addr, verbose, &pis); 270810696SDavid.Hollister@Sun.COM 270910743SDavid.Hollister@Sun.COM if (compq) 271010743SDavid.Hollister@Sun.COM display_completion_queue(ss); 271110743SDavid.Hollister@Sun.COM 271211048SDavid.Hollister@Sun.COM if (unconfigured) 271311048SDavid.Hollister@Sun.COM display_unconfigured_targets(addr); 271411048SDavid.Hollister@Sun.COM 271510696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 271610696SDavid.Hollister@Sun.COM 271710696SDavid.Hollister@Sun.COM return (rv); 271810696SDavid.Hollister@Sun.COM } 271910696SDavid.Hollister@Sun.COM 272010696SDavid.Hollister@Sun.COM void 272110696SDavid.Hollister@Sun.COM pmcs_help() 272210696SDavid.Hollister@Sun.COM { 272310696SDavid.Hollister@Sun.COM mdb_printf("Prints summary information about each pmcs instance.\n" 272410743SDavid.Hollister@Sun.COM " -c: Dump the completion queue\n" 272511334SReed.Liu@Sun.COM " -d: Print per-iport information about device tree children\n" 272610696SDavid.Hollister@Sun.COM " -h: Print more detailed hardware information\n" 272710696SDavid.Hollister@Sun.COM " -i: Print interrupt coalescing information\n" 272810696SDavid.Hollister@Sun.COM " -I: Print information about each iport\n" 272911334SReed.Liu@Sun.COM " -m: Print per-iport information about DAM/damap state\n" 273010696SDavid.Hollister@Sun.COM " -p: Print information about each attached PHY\n" 273110696SDavid.Hollister@Sun.COM " -q: Dump inbound queues\n" 273210696SDavid.Hollister@Sun.COM " -Q: Dump outbound queues\n" 273311048SDavid.Hollister@Sun.COM " -t: Print information about each configured target\n" 273410696SDavid.Hollister@Sun.COM " -T: Print target and PHY count summary\n" 273511048SDavid.Hollister@Sun.COM " -u: Show SAS address of all unconfigured targets\n" 273610696SDavid.Hollister@Sun.COM " -w: Dump work structures\n" 273710696SDavid.Hollister@Sun.COM " -W: List pmcs cmds waiting on various queues\n" 273810696SDavid.Hollister@Sun.COM " -v: Add verbosity to the above options\n"); 273910696SDavid.Hollister@Sun.COM } 274010696SDavid.Hollister@Sun.COM 274110743SDavid.Hollister@Sun.COM void 274211048SDavid.Hollister@Sun.COM pmcs_log_help() 274311048SDavid.Hollister@Sun.COM { 274411048SDavid.Hollister@Sun.COM mdb_printf("Dump the pmcs log buffer, possibly with filtering.\n" 274511347SRamana.Srikanth@Sun.COM " -l TAIL_LINES: Dump the last TAIL_LINES messages\n" 274611048SDavid.Hollister@Sun.COM " -p PHY_PATH: Dump messages matching PHY_PATH\n" 274711048SDavid.Hollister@Sun.COM " -s SAS_ADDRESS: Dump messages matching SAS_ADDRESS\n\n" 274811048SDavid.Hollister@Sun.COM "Where: PHY_PATH can be found with ::pmcs -p (e.g. pp04.18.18.01)\n" 274911048SDavid.Hollister@Sun.COM " SAS_ADDRESS can be found with ::pmcs -t " 275011048SDavid.Hollister@Sun.COM "(e.g. 5000c5000358c221)\n"); 275111048SDavid.Hollister@Sun.COM } 275211048SDavid.Hollister@Sun.COM void 275310743SDavid.Hollister@Sun.COM pmcs_tag_help() 275410743SDavid.Hollister@Sun.COM { 275510743SDavid.Hollister@Sun.COM mdb_printf("Print all work structures by matching the tag.\n" 275610743SDavid.Hollister@Sun.COM " -i index: Match tag index (0x000 - 0xfff)\n" 275710743SDavid.Hollister@Sun.COM " -s serialnumber: Match serial number (0x0000 - 0xffff)\n" 275810743SDavid.Hollister@Sun.COM " -t tagtype: Match tag type [NONE(1), CBACK(2), " 275910743SDavid.Hollister@Sun.COM "WAIT(3)]\n"); 276010743SDavid.Hollister@Sun.COM } 276110743SDavid.Hollister@Sun.COM 276210696SDavid.Hollister@Sun.COM static const mdb_dcmd_t dcmds[] = { 276311334SReed.Liu@Sun.COM { "pmcs", "?[-cdhiImpQqtTuwWv]", "print pmcs information", 276410696SDavid.Hollister@Sun.COM pmcs_dcmd, pmcs_help 276510696SDavid.Hollister@Sun.COM }, 276611048SDavid.Hollister@Sun.COM { "pmcs_log", 276711347SRamana.Srikanth@Sun.COM "?[-p PHY_PATH | -s SAS_ADDRESS | -l TAIL_LINES]", 276811048SDavid.Hollister@Sun.COM "dump pmcs log file", pmcs_log, pmcs_log_help 276911048SDavid.Hollister@Sun.COM }, 277010743SDavid.Hollister@Sun.COM { "pmcs_tag", "?[-t tagtype|-s serialnum|-i index]", 277110743SDavid.Hollister@Sun.COM "Find work structures by tag type, serial number or index", 277210743SDavid.Hollister@Sun.COM pmcs_tag, pmcs_tag_help 277310743SDavid.Hollister@Sun.COM }, 277411694SDavid.Hollister@Sun.COM #ifndef _KMDB 277511694SDavid.Hollister@Sun.COM { "pmcs_fwlog", 277611694SDavid.Hollister@Sun.COM "?-o output_file", 277711694SDavid.Hollister@Sun.COM "dump pmcs firmware event log to output_file", pmcs_fwlog, NULL 277811694SDavid.Hollister@Sun.COM }, 277911694SDavid.Hollister@Sun.COM #endif /* _KMDB */ 278010696SDavid.Hollister@Sun.COM { NULL } 278110696SDavid.Hollister@Sun.COM }; 278210696SDavid.Hollister@Sun.COM 278310696SDavid.Hollister@Sun.COM static const mdb_walker_t walkers[] = { 278410696SDavid.Hollister@Sun.COM { "pmcs_targets", "walk target structures", 278510696SDavid.Hollister@Sun.COM targets_walk_i, targets_walk_s, targets_walk_f }, 278610696SDavid.Hollister@Sun.COM { "pmcs_phys", "walk PHY structures", 278710696SDavid.Hollister@Sun.COM phy_walk_i, phy_walk_s, phy_walk_f }, 278810696SDavid.Hollister@Sun.COM { NULL } 278910696SDavid.Hollister@Sun.COM }; 279010696SDavid.Hollister@Sun.COM 279110696SDavid.Hollister@Sun.COM static const mdb_modinfo_t modinfo = { 279210696SDavid.Hollister@Sun.COM MDB_API_VERSION, dcmds, walkers 279310696SDavid.Hollister@Sun.COM }; 279410696SDavid.Hollister@Sun.COM 279510696SDavid.Hollister@Sun.COM const mdb_modinfo_t * 279610696SDavid.Hollister@Sun.COM _mdb_init(void) 279710696SDavid.Hollister@Sun.COM { 279810696SDavid.Hollister@Sun.COM return (&modinfo); 279910696SDavid.Hollister@Sun.COM } 2800