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 /* 2212060SDavid.Hollister@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 2310696SDavid.Hollister@Sun.COM */ 2410696SDavid.Hollister@Sun.COM 2510696SDavid.Hollister@Sun.COM #include <limits.h> 2610696SDavid.Hollister@Sun.COM #include <sys/mdb_modapi.h> 2711334SReed.Liu@Sun.COM #include <mdb/mdb_ctf.h> 2810696SDavid.Hollister@Sun.COM #include <sys/sysinfo.h> 2911048SDavid.Hollister@Sun.COM #include <sys/byteorder.h> 3011334SReed.Liu@Sun.COM #include <sys/nvpair.h> 3111334SReed.Liu@Sun.COM #include <sys/damap.h> 3210696SDavid.Hollister@Sun.COM #include <sys/scsi/scsi.h> 3310696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs.h> 3411694SDavid.Hollister@Sun.COM #ifndef _KMDB 3511694SDavid.Hollister@Sun.COM #include <sys/types.h> 3611694SDavid.Hollister@Sun.COM #include <sys/stat.h> 3711694SDavid.Hollister@Sun.COM #include <fcntl.h> 3811694SDavid.Hollister@Sun.COM #include <unistd.h> 3911694SDavid.Hollister@Sun.COM #endif /* _KMDB */ 4010696SDavid.Hollister@Sun.COM 4111334SReed.Liu@Sun.COM /* 4211334SReed.Liu@Sun.COM * We need use this to pass the settings when display_iport 4311334SReed.Liu@Sun.COM */ 4411334SReed.Liu@Sun.COM typedef struct per_iport_setting { 4511334SReed.Liu@Sun.COM uint_t pis_damap_info; /* -m: DAM/damap */ 4611334SReed.Liu@Sun.COM uint_t pis_dtc_info; /* -d: device tree children: dev_info/path_info */ 4711334SReed.Liu@Sun.COM } per_iport_setting_t; 4811334SReed.Liu@Sun.COM 4912060SDavid.Hollister@Sun.COM /* 5012060SDavid.Hollister@Sun.COM * This structure is used for sorting work structures by the wserno 5112060SDavid.Hollister@Sun.COM */ 5212060SDavid.Hollister@Sun.COM typedef struct wserno_list { 5312060SDavid.Hollister@Sun.COM int serno; 5412060SDavid.Hollister@Sun.COM int idx; 5512060SDavid.Hollister@Sun.COM struct wserno_list *next; 5612060SDavid.Hollister@Sun.COM struct wserno_list *prev; 5712060SDavid.Hollister@Sun.COM } wserno_list_t; 5812060SDavid.Hollister@Sun.COM 5911334SReed.Liu@Sun.COM #define MDB_RD(a, b, c) mdb_vread(a, b, (uintptr_t)c) 6011334SReed.Liu@Sun.COM #define NOREAD(a, b) mdb_warn("could not read " #a " at 0x%p", b) 6110696SDavid.Hollister@Sun.COM 6210696SDavid.Hollister@Sun.COM static pmcs_hw_t ss; 6310696SDavid.Hollister@Sun.COM static pmcs_xscsi_t **targets = NULL; 6410696SDavid.Hollister@Sun.COM static int target_idx; 6510696SDavid.Hollister@Sun.COM 6610696SDavid.Hollister@Sun.COM static uint32_t sas_phys, sata_phys, exp_phys, num_expanders, empty_phys; 6710696SDavid.Hollister@Sun.COM 6810696SDavid.Hollister@Sun.COM static pmcs_phy_t *pmcs_next_sibling(pmcs_phy_t *phyp); 6910743SDavid.Hollister@Sun.COM static void display_one_work(pmcwork_t *wp, int verbose, int idx); 7010696SDavid.Hollister@Sun.COM 7110696SDavid.Hollister@Sun.COM static void 7210696SDavid.Hollister@Sun.COM print_sas_address(pmcs_phy_t *phy) 7310696SDavid.Hollister@Sun.COM { 7410696SDavid.Hollister@Sun.COM int idx; 7510696SDavid.Hollister@Sun.COM 7610696SDavid.Hollister@Sun.COM for (idx = 0; idx < 8; idx++) { 7710696SDavid.Hollister@Sun.COM mdb_printf("%02x", phy->sas_address[idx]); 7810696SDavid.Hollister@Sun.COM } 7910696SDavid.Hollister@Sun.COM } 8010696SDavid.Hollister@Sun.COM 81*12120SDavid.Hollister@Sun.COM static void 82*12120SDavid.Hollister@Sun.COM pmcs_fwtime_to_systime(struct pmcs_hw ss, uint32_t fw_hi, uint32_t fw_lo, 83*12120SDavid.Hollister@Sun.COM struct timespec *stime) 84*12120SDavid.Hollister@Sun.COM { 85*12120SDavid.Hollister@Sun.COM uint64_t fwtime; 86*12120SDavid.Hollister@Sun.COM time_t secs; 87*12120SDavid.Hollister@Sun.COM long nsecs; 88*12120SDavid.Hollister@Sun.COM boolean_t backward_time = B_FALSE; 89*12120SDavid.Hollister@Sun.COM 90*12120SDavid.Hollister@Sun.COM fwtime = ((uint64_t)fw_hi << 32) | fw_lo; 91*12120SDavid.Hollister@Sun.COM 92*12120SDavid.Hollister@Sun.COM /* 93*12120SDavid.Hollister@Sun.COM * If fwtime < ss.fw_timestamp, then we need to adjust the clock 94*12120SDavid.Hollister@Sun.COM * time backwards from ss.sys_timestamp. Otherwise, the adjustment 95*12120SDavid.Hollister@Sun.COM * goes forward in time 96*12120SDavid.Hollister@Sun.COM */ 97*12120SDavid.Hollister@Sun.COM if (fwtime >= ss.fw_timestamp) { 98*12120SDavid.Hollister@Sun.COM fwtime -= ss.fw_timestamp; 99*12120SDavid.Hollister@Sun.COM } else { 100*12120SDavid.Hollister@Sun.COM fwtime = ss.fw_timestamp - fwtime; 101*12120SDavid.Hollister@Sun.COM backward_time = B_TRUE; 102*12120SDavid.Hollister@Sun.COM } 103*12120SDavid.Hollister@Sun.COM 104*12120SDavid.Hollister@Sun.COM secs = ((time_t)fwtime / NSECS_PER_SEC); 105*12120SDavid.Hollister@Sun.COM nsecs = ((long)fwtime % NSECS_PER_SEC); 106*12120SDavid.Hollister@Sun.COM 107*12120SDavid.Hollister@Sun.COM stime->tv_sec = ss.sys_timestamp.tv_sec; 108*12120SDavid.Hollister@Sun.COM stime->tv_nsec = ss.sys_timestamp.tv_nsec; 109*12120SDavid.Hollister@Sun.COM 110*12120SDavid.Hollister@Sun.COM if (backward_time) { 111*12120SDavid.Hollister@Sun.COM if (stime->tv_nsec < nsecs) { 112*12120SDavid.Hollister@Sun.COM stime->tv_sec--; 113*12120SDavid.Hollister@Sun.COM stime->tv_nsec = stime->tv_nsec + NSECS_PER_SEC - nsecs; 114*12120SDavid.Hollister@Sun.COM } else { 115*12120SDavid.Hollister@Sun.COM stime->tv_nsec -= nsecs; 116*12120SDavid.Hollister@Sun.COM } 117*12120SDavid.Hollister@Sun.COM stime->tv_sec -= secs; 118*12120SDavid.Hollister@Sun.COM } else { 119*12120SDavid.Hollister@Sun.COM if (stime->tv_nsec + nsecs > NSECS_PER_SEC) { 120*12120SDavid.Hollister@Sun.COM stime->tv_sec++; 121*12120SDavid.Hollister@Sun.COM } 122*12120SDavid.Hollister@Sun.COM stime->tv_nsec = (stime->tv_nsec + nsecs) % NSECS_PER_SEC; 123*12120SDavid.Hollister@Sun.COM stime->tv_sec += secs; 124*12120SDavid.Hollister@Sun.COM } 125*12120SDavid.Hollister@Sun.COM } 126*12120SDavid.Hollister@Sun.COM 12710696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 12810696SDavid.Hollister@Sun.COM static void 12910696SDavid.Hollister@Sun.COM display_ic(struct pmcs_hw m, int verbose) 13010696SDavid.Hollister@Sun.COM { 13110696SDavid.Hollister@Sun.COM int msec_per_tick; 13210696SDavid.Hollister@Sun.COM 13310696SDavid.Hollister@Sun.COM if (mdb_readvar(&msec_per_tick, "msec_per_tick") == -1) { 13410696SDavid.Hollister@Sun.COM mdb_warn("can't read msec_per_tick"); 13510696SDavid.Hollister@Sun.COM msec_per_tick = 0; 13610696SDavid.Hollister@Sun.COM } 13710696SDavid.Hollister@Sun.COM 13810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 13910696SDavid.Hollister@Sun.COM mdb_printf("Interrupt coalescing timer info\n"); 14010696SDavid.Hollister@Sun.COM mdb_printf("-------------------------------\n"); 14110696SDavid.Hollister@Sun.COM if (msec_per_tick == 0) { 14210696SDavid.Hollister@Sun.COM mdb_printf("Quantum : ?? ms\n"); 14310696SDavid.Hollister@Sun.COM } else { 14410696SDavid.Hollister@Sun.COM mdb_printf("Quantum : %d ms\n", 14510696SDavid.Hollister@Sun.COM m.io_intr_coal.quantum * msec_per_tick); 14610696SDavid.Hollister@Sun.COM } 14710696SDavid.Hollister@Sun.COM mdb_printf("Timer enabled : "); 14810696SDavid.Hollister@Sun.COM if (m.io_intr_coal.timer_on) { 14910696SDavid.Hollister@Sun.COM mdb_printf("Yes\n"); 15010696SDavid.Hollister@Sun.COM mdb_printf("Coalescing timer value : %d us\n", 15110696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_coal_timer); 15210696SDavid.Hollister@Sun.COM } else { 15310696SDavid.Hollister@Sun.COM mdb_printf("No\n"); 15410696SDavid.Hollister@Sun.COM } 15510696SDavid.Hollister@Sun.COM mdb_printf("Total nsecs between interrupts: %ld\n", 15610696SDavid.Hollister@Sun.COM m.io_intr_coal.nsecs_between_intrs); 15710696SDavid.Hollister@Sun.COM mdb_printf("Time of last I/O interrupt : %ld\n", 15810696SDavid.Hollister@Sun.COM m.io_intr_coal.last_io_comp); 15910696SDavid.Hollister@Sun.COM mdb_printf("Number of I/O interrupts : %d\n", 16010696SDavid.Hollister@Sun.COM m.io_intr_coal.num_intrs); 16110696SDavid.Hollister@Sun.COM mdb_printf("Number of I/O completions : %d\n", 16210696SDavid.Hollister@Sun.COM m.io_intr_coal.num_io_completions); 16310696SDavid.Hollister@Sun.COM mdb_printf("Max I/O completion interrupts : %d\n", 16410696SDavid.Hollister@Sun.COM m.io_intr_coal.max_io_completions); 16510696SDavid.Hollister@Sun.COM mdb_printf("Measured ECHO int latency : %d ns\n", 16610696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_latency); 16710696SDavid.Hollister@Sun.COM mdb_printf("Interrupt threshold : %d\n", 16810696SDavid.Hollister@Sun.COM m.io_intr_coal.intr_threshold); 16910696SDavid.Hollister@Sun.COM } 17010696SDavid.Hollister@Sun.COM 17110696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 17210696SDavid.Hollister@Sun.COM static int 17310696SDavid.Hollister@Sun.COM pmcs_iport_phy_walk_cb(uintptr_t addr, const void *wdata, void *priv) 17410696SDavid.Hollister@Sun.COM { 17510696SDavid.Hollister@Sun.COM struct pmcs_phy phy; 17610696SDavid.Hollister@Sun.COM 17710696SDavid.Hollister@Sun.COM if (mdb_vread(&phy, sizeof (struct pmcs_phy), addr) != 17810696SDavid.Hollister@Sun.COM sizeof (struct pmcs_phy)) { 17910696SDavid.Hollister@Sun.COM return (DCMD_ERR); 18010696SDavid.Hollister@Sun.COM } 18110696SDavid.Hollister@Sun.COM 18210696SDavid.Hollister@Sun.COM mdb_printf("%16p %2d\n", addr, phy.phynum); 18310696SDavid.Hollister@Sun.COM 18410696SDavid.Hollister@Sun.COM return (0); 18510696SDavid.Hollister@Sun.COM } 18610696SDavid.Hollister@Sun.COM 18711334SReed.Liu@Sun.COM static int 18811334SReed.Liu@Sun.COM display_iport_damap(dev_info_t *pdip) 18911334SReed.Liu@Sun.COM { 19011334SReed.Liu@Sun.COM int rval = DCMD_ERR; 19111334SReed.Liu@Sun.COM struct dev_info dip; 19211334SReed.Liu@Sun.COM scsi_hba_tran_t sht; 19311334SReed.Liu@Sun.COM mdb_ctf_id_t istm_ctfid; /* impl_scsi_tgtmap_t ctf_id */ 19411334SReed.Liu@Sun.COM ulong_t tmd_offset = 0; /* tgtmap_dam offset to impl_scsi_tgtmap_t */ 19511334SReed.Liu@Sun.COM uintptr_t dam0; 19611334SReed.Liu@Sun.COM uintptr_t dam1; 19711334SReed.Liu@Sun.COM 19811334SReed.Liu@Sun.COM if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)pdip) != 19911334SReed.Liu@Sun.COM sizeof (struct dev_info)) { 20011334SReed.Liu@Sun.COM return (rval); 20111334SReed.Liu@Sun.COM } 20211334SReed.Liu@Sun.COM 20311334SReed.Liu@Sun.COM if (dip.devi_driver_data == NULL) { 20411334SReed.Liu@Sun.COM return (rval); 20511334SReed.Liu@Sun.COM } 20611334SReed.Liu@Sun.COM 20711334SReed.Liu@Sun.COM if (mdb_vread(&sht, sizeof (scsi_hba_tran_t), 20811334SReed.Liu@Sun.COM (uintptr_t)dip.devi_driver_data) != sizeof (scsi_hba_tran_t)) { 20911334SReed.Liu@Sun.COM return (rval); 21011334SReed.Liu@Sun.COM } 21111334SReed.Liu@Sun.COM 21211334SReed.Liu@Sun.COM if (sht.tran_tgtmap == NULL) { 21311334SReed.Liu@Sun.COM return (rval); 21411334SReed.Liu@Sun.COM } 21511334SReed.Liu@Sun.COM 21611334SReed.Liu@Sun.COM if (mdb_ctf_lookup_by_name("impl_scsi_tgtmap_t", &istm_ctfid) != 0) { 21711334SReed.Liu@Sun.COM return (rval); 21811334SReed.Liu@Sun.COM } 21911334SReed.Liu@Sun.COM 22011334SReed.Liu@Sun.COM if (mdb_ctf_offsetof(istm_ctfid, "tgtmap_dam", &tmd_offset) != 0) { 22111334SReed.Liu@Sun.COM return (rval); 22211334SReed.Liu@Sun.COM } 22311334SReed.Liu@Sun.COM 22411334SReed.Liu@Sun.COM tmd_offset /= NBBY; 22511334SReed.Liu@Sun.COM mdb_vread(&dam0, sizeof (dam0), 22611334SReed.Liu@Sun.COM (uintptr_t)(tmd_offset + (char *)sht.tran_tgtmap)); 22711334SReed.Liu@Sun.COM mdb_vread(&dam1, sizeof (dam1), 22811334SReed.Liu@Sun.COM (uintptr_t)(sizeof (dam0) + tmd_offset + (char *)sht.tran_tgtmap)); 22911334SReed.Liu@Sun.COM 23011334SReed.Liu@Sun.COM if (dam0 != NULL) { 23111334SReed.Liu@Sun.COM rval = mdb_call_dcmd("damap", dam0, DCMD_ADDRSPEC, 0, NULL); 23211334SReed.Liu@Sun.COM mdb_printf("\n"); 23311334SReed.Liu@Sun.COM if (rval != DCMD_OK) { 23411334SReed.Liu@Sun.COM return (rval); 23511334SReed.Liu@Sun.COM } 23611334SReed.Liu@Sun.COM } 23711334SReed.Liu@Sun.COM 23811334SReed.Liu@Sun.COM if (dam1 != NULL) { 23911334SReed.Liu@Sun.COM rval = mdb_call_dcmd("damap", dam1, DCMD_ADDRSPEC, 0, NULL); 24011334SReed.Liu@Sun.COM mdb_printf("\n"); 24111334SReed.Liu@Sun.COM } 24211334SReed.Liu@Sun.COM 24311334SReed.Liu@Sun.COM return (rval); 24411334SReed.Liu@Sun.COM } 24511334SReed.Liu@Sun.COM 24611334SReed.Liu@Sun.COM /* ARGSUSED */ 24711334SReed.Liu@Sun.COM static int 24811334SReed.Liu@Sun.COM display_iport_di_cb(uintptr_t addr, const void *wdata, void *priv) 24911334SReed.Liu@Sun.COM { 25011334SReed.Liu@Sun.COM uint_t *idx = (uint_t *)priv; 25111334SReed.Liu@Sun.COM struct dev_info dip; 25211334SReed.Liu@Sun.COM char devi_name[MAXNAMELEN]; 25311334SReed.Liu@Sun.COM char devi_addr[MAXNAMELEN]; 25411334SReed.Liu@Sun.COM 25511334SReed.Liu@Sun.COM if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)addr) != 25611334SReed.Liu@Sun.COM sizeof (struct dev_info)) { 25711334SReed.Liu@Sun.COM return (DCMD_ERR); 25811334SReed.Liu@Sun.COM } 25911334SReed.Liu@Sun.COM 26011334SReed.Liu@Sun.COM if (mdb_readstr(devi_name, sizeof (devi_name), 26111334SReed.Liu@Sun.COM (uintptr_t)dip.devi_node_name) == -1) { 26211334SReed.Liu@Sun.COM devi_name[0] = '?'; 26311334SReed.Liu@Sun.COM devi_name[1] = '\0'; 26411334SReed.Liu@Sun.COM } 26511334SReed.Liu@Sun.COM 26611334SReed.Liu@Sun.COM if (mdb_readstr(devi_addr, sizeof (devi_addr), 26711334SReed.Liu@Sun.COM (uintptr_t)dip.devi_addr) == -1) { 26811334SReed.Liu@Sun.COM devi_addr[0] = '?'; 26911334SReed.Liu@Sun.COM devi_addr[1] = '\0'; 27011334SReed.Liu@Sun.COM } 27111334SReed.Liu@Sun.COM 27211334SReed.Liu@Sun.COM mdb_printf(" %3d: @%-21s%10s@\t%p::devinfo -s\n", 27311334SReed.Liu@Sun.COM (*idx)++, devi_addr, devi_name, addr); 27411334SReed.Liu@Sun.COM return (DCMD_OK); 27511334SReed.Liu@Sun.COM } 27611334SReed.Liu@Sun.COM 27711334SReed.Liu@Sun.COM /* ARGSUSED */ 27811334SReed.Liu@Sun.COM static int 27911334SReed.Liu@Sun.COM display_iport_pi_cb(uintptr_t addr, const void *wdata, void *priv) 28011334SReed.Liu@Sun.COM { 28111334SReed.Liu@Sun.COM uint_t *idx = (uint_t *)priv; 28211334SReed.Liu@Sun.COM struct mdi_pathinfo mpi; 28311334SReed.Liu@Sun.COM char pi_addr[MAXNAMELEN]; 28411334SReed.Liu@Sun.COM 28511334SReed.Liu@Sun.COM if (mdb_vread(&mpi, sizeof (struct mdi_pathinfo), (uintptr_t)addr) != 28611334SReed.Liu@Sun.COM sizeof (struct mdi_pathinfo)) { 28711334SReed.Liu@Sun.COM return (DCMD_ERR); 28811334SReed.Liu@Sun.COM } 28911334SReed.Liu@Sun.COM 29011334SReed.Liu@Sun.COM if (mdb_readstr(pi_addr, sizeof (pi_addr), 29111334SReed.Liu@Sun.COM (uintptr_t)mpi.pi_addr) == -1) { 29211334SReed.Liu@Sun.COM pi_addr[0] = '?'; 29311334SReed.Liu@Sun.COM pi_addr[1] = '\0'; 29411334SReed.Liu@Sun.COM } 29511334SReed.Liu@Sun.COM 29611334SReed.Liu@Sun.COM mdb_printf(" %3d: @%-21s %p::print struct mdi_pathinfo\n", 29711334SReed.Liu@Sun.COM (*idx)++, pi_addr, addr); 29811334SReed.Liu@Sun.COM return (DCMD_OK); 29911334SReed.Liu@Sun.COM } 30011334SReed.Liu@Sun.COM 30111334SReed.Liu@Sun.COM static int 30211334SReed.Liu@Sun.COM display_iport_dtc(dev_info_t *pdip) 30311334SReed.Liu@Sun.COM { 30411334SReed.Liu@Sun.COM int rval = DCMD_ERR; 30511334SReed.Liu@Sun.COM struct dev_info dip; 30611334SReed.Liu@Sun.COM struct mdi_phci phci; 30711334SReed.Liu@Sun.COM uint_t didx = 1; 30811334SReed.Liu@Sun.COM uint_t pidx = 1; 30911334SReed.Liu@Sun.COM 31011334SReed.Liu@Sun.COM if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)pdip) != 31111334SReed.Liu@Sun.COM sizeof (struct dev_info)) { 31211334SReed.Liu@Sun.COM return (rval); 31311334SReed.Liu@Sun.COM } 31411334SReed.Liu@Sun.COM 31511334SReed.Liu@Sun.COM mdb_printf("Device tree children - dev_info:\n"); 31611334SReed.Liu@Sun.COM if (dip.devi_child == NULL) { 31711334SReed.Liu@Sun.COM mdb_printf("\tdevi_child is NULL, no dev_info\n\n"); 31811334SReed.Liu@Sun.COM goto skip_di; 31911334SReed.Liu@Sun.COM } 32011334SReed.Liu@Sun.COM 32111334SReed.Liu@Sun.COM /* 32211334SReed.Liu@Sun.COM * First, we dump the iport's children dev_info node information. 32311334SReed.Liu@Sun.COM * use existing walker: devinfo_siblings 32411334SReed.Liu@Sun.COM */ 32511334SReed.Liu@Sun.COM mdb_printf("\t#: @unit-address name@\tdrill-down\n"); 32611334SReed.Liu@Sun.COM rval = mdb_pwalk("devinfo_siblings", display_iport_di_cb, 32711334SReed.Liu@Sun.COM (void *)&didx, (uintptr_t)dip.devi_child); 32811334SReed.Liu@Sun.COM mdb_printf("\n"); 32911334SReed.Liu@Sun.COM 33011334SReed.Liu@Sun.COM skip_di: 33111334SReed.Liu@Sun.COM /* 33211334SReed.Liu@Sun.COM * Then we try to dump the iport's path_info node information. 33311334SReed.Liu@Sun.COM * use existing walker: mdipi_phci_list 33411334SReed.Liu@Sun.COM */ 33511334SReed.Liu@Sun.COM mdb_printf("Device tree children - path_info:\n"); 33611334SReed.Liu@Sun.COM if (mdb_vread(&phci, sizeof (struct mdi_phci), 33711334SReed.Liu@Sun.COM (uintptr_t)dip.devi_mdi_xhci) != sizeof (struct mdi_phci)) { 33811334SReed.Liu@Sun.COM mdb_printf("\tdevi_mdi_xhci is NULL, no path_info\n\n"); 33911334SReed.Liu@Sun.COM return (rval); 34011334SReed.Liu@Sun.COM } 34111334SReed.Liu@Sun.COM 34211334SReed.Liu@Sun.COM if (phci.ph_path_head == NULL) { 34311334SReed.Liu@Sun.COM mdb_printf("\tph_path_head is NULL, no path_info\n\n"); 34411334SReed.Liu@Sun.COM return (rval); 34511334SReed.Liu@Sun.COM } 34611334SReed.Liu@Sun.COM 34711334SReed.Liu@Sun.COM mdb_printf("\t#: @unit-address drill-down\n"); 34811334SReed.Liu@Sun.COM rval = mdb_pwalk("mdipi_phci_list", display_iport_pi_cb, 34911334SReed.Liu@Sun.COM (void *)&pidx, (uintptr_t)phci.ph_path_head); 35011334SReed.Liu@Sun.COM mdb_printf("\n"); 35111334SReed.Liu@Sun.COM return (rval); 35211334SReed.Liu@Sun.COM } 35311334SReed.Liu@Sun.COM 35411334SReed.Liu@Sun.COM static void 35511334SReed.Liu@Sun.COM display_iport_more(dev_info_t *dip, per_iport_setting_t *pis) 35611334SReed.Liu@Sun.COM { 35711334SReed.Liu@Sun.COM if (pis->pis_damap_info) { 35811334SReed.Liu@Sun.COM (void) display_iport_damap(dip); 35911334SReed.Liu@Sun.COM } 36011334SReed.Liu@Sun.COM 36111334SReed.Liu@Sun.COM if (pis->pis_dtc_info) { 36211334SReed.Liu@Sun.COM (void) display_iport_dtc(dip); 36311334SReed.Liu@Sun.COM } 36411334SReed.Liu@Sun.COM } 36511334SReed.Liu@Sun.COM 36610696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 36710696SDavid.Hollister@Sun.COM static int 36810696SDavid.Hollister@Sun.COM pmcs_iport_walk_cb(uintptr_t addr, const void *wdata, void *priv) 36910696SDavid.Hollister@Sun.COM { 37010696SDavid.Hollister@Sun.COM struct pmcs_iport iport; 37110696SDavid.Hollister@Sun.COM uintptr_t list_addr; 37210696SDavid.Hollister@Sun.COM char *ua_state; 37310696SDavid.Hollister@Sun.COM char portid[4]; 37410696SDavid.Hollister@Sun.COM char unit_address[34]; 37511334SReed.Liu@Sun.COM per_iport_setting_t *pis = (per_iport_setting_t *)priv; 37610696SDavid.Hollister@Sun.COM 37710696SDavid.Hollister@Sun.COM if (mdb_vread(&iport, sizeof (struct pmcs_iport), addr) != 37810696SDavid.Hollister@Sun.COM sizeof (struct pmcs_iport)) { 37910696SDavid.Hollister@Sun.COM return (DCMD_ERR); 38010696SDavid.Hollister@Sun.COM } 38110696SDavid.Hollister@Sun.COM 38210696SDavid.Hollister@Sun.COM if (mdb_readstr(unit_address, sizeof (unit_address), 38310696SDavid.Hollister@Sun.COM (uintptr_t)(iport.ua)) == -1) { 38410696SDavid.Hollister@Sun.COM strncpy(unit_address, "Unset", sizeof (unit_address)); 38510696SDavid.Hollister@Sun.COM } 38610696SDavid.Hollister@Sun.COM 38710696SDavid.Hollister@Sun.COM if (iport.portid == 0xffff) { 38810696SDavid.Hollister@Sun.COM mdb_snprintf(portid, sizeof (portid), "%s", "-"); 38911347SRamana.Srikanth@Sun.COM } else if (iport.portid == PMCS_IPORT_INVALID_PORT_ID) { 39011347SRamana.Srikanth@Sun.COM mdb_snprintf(portid, sizeof (portid), "%s", "N/A"); 39110696SDavid.Hollister@Sun.COM } else { 39210696SDavid.Hollister@Sun.COM mdb_snprintf(portid, sizeof (portid), "%d", iport.portid); 39310696SDavid.Hollister@Sun.COM } 39410696SDavid.Hollister@Sun.COM 39510696SDavid.Hollister@Sun.COM switch (iport.ua_state) { 39610696SDavid.Hollister@Sun.COM case UA_INACTIVE: 39710696SDavid.Hollister@Sun.COM ua_state = "Inactive"; 39810696SDavid.Hollister@Sun.COM break; 39910696SDavid.Hollister@Sun.COM case UA_PEND_ACTIVATE: 40010696SDavid.Hollister@Sun.COM ua_state = "PendActivate"; 40110696SDavid.Hollister@Sun.COM break; 40210696SDavid.Hollister@Sun.COM case UA_ACTIVE: 40310696SDavid.Hollister@Sun.COM ua_state = "Active"; 40410696SDavid.Hollister@Sun.COM break; 40510696SDavid.Hollister@Sun.COM case UA_PEND_DEACTIVATE: 40610696SDavid.Hollister@Sun.COM ua_state = "PendDeactivate"; 40710696SDavid.Hollister@Sun.COM break; 40810696SDavid.Hollister@Sun.COM default: 40910696SDavid.Hollister@Sun.COM ua_state = "Unknown"; 41010696SDavid.Hollister@Sun.COM } 41110696SDavid.Hollister@Sun.COM 41210696SDavid.Hollister@Sun.COM if (strlen(unit_address) < 3) { 41310696SDavid.Hollister@Sun.COM /* Standard iport unit address */ 41410696SDavid.Hollister@Sun.COM mdb_printf("UA %-16s %16s %8s %8s %16s", "Iport", "UA State", 41510696SDavid.Hollister@Sun.COM "PortID", "NumPhys", "DIP\n"); 41610696SDavid.Hollister@Sun.COM mdb_printf("%2s %16p %16s %8s %8d %16p\n", unit_address, addr, 41710696SDavid.Hollister@Sun.COM ua_state, portid, iport.nphy, iport.dip); 41810696SDavid.Hollister@Sun.COM } else { 41910696SDavid.Hollister@Sun.COM /* Temporary iport unit address */ 42010696SDavid.Hollister@Sun.COM mdb_printf("%-32s %16s %20s %8s %8s %16s", "UA", "Iport", 42110696SDavid.Hollister@Sun.COM "UA State", "PortID", "NumPhys", "DIP\n"); 42210696SDavid.Hollister@Sun.COM mdb_printf("%32s %16p %20s %8s %8d %16p\n", unit_address, addr, 42310696SDavid.Hollister@Sun.COM ua_state, portid, iport.nphy, iport.dip); 42410696SDavid.Hollister@Sun.COM } 42510696SDavid.Hollister@Sun.COM 42610696SDavid.Hollister@Sun.COM if (iport.nphy > 0) { 42710696SDavid.Hollister@Sun.COM mdb_inc_indent(4); 42810696SDavid.Hollister@Sun.COM mdb_printf("%-18s %8s", "Phy", "PhyNum\n"); 42910696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 43010696SDavid.Hollister@Sun.COM list_addr = 43110696SDavid.Hollister@Sun.COM (uintptr_t)(addr + offsetof(struct pmcs_iport, phys)); 43210696SDavid.Hollister@Sun.COM if (mdb_pwalk("list", pmcs_iport_phy_walk_cb, NULL, 43310696SDavid.Hollister@Sun.COM list_addr) == -1) { 43410696SDavid.Hollister@Sun.COM mdb_warn("pmcs iport walk failed"); 43510696SDavid.Hollister@Sun.COM } 43610696SDavid.Hollister@Sun.COM mdb_dec_indent(6); 43710696SDavid.Hollister@Sun.COM mdb_printf("\n"); 43810696SDavid.Hollister@Sun.COM } 43910696SDavid.Hollister@Sun.COM 44011334SReed.Liu@Sun.COM /* 44111334SReed.Liu@Sun.COM * See if we need to show more information based on 'd' or 'm' options 44211334SReed.Liu@Sun.COM */ 44311334SReed.Liu@Sun.COM display_iport_more(iport.dip, pis); 44411334SReed.Liu@Sun.COM 44510696SDavid.Hollister@Sun.COM return (0); 44610696SDavid.Hollister@Sun.COM } 44710696SDavid.Hollister@Sun.COM 44810696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 44910696SDavid.Hollister@Sun.COM static void 45011334SReed.Liu@Sun.COM display_iport(struct pmcs_hw m, uintptr_t addr, int verbose, 45111334SReed.Liu@Sun.COM per_iport_setting_t *pis) 45210696SDavid.Hollister@Sun.COM { 45310696SDavid.Hollister@Sun.COM uintptr_t list_addr; 45410696SDavid.Hollister@Sun.COM 45510696SDavid.Hollister@Sun.COM if (m.iports_attached) { 45610696SDavid.Hollister@Sun.COM mdb_printf("Iport information:\n"); 45710696SDavid.Hollister@Sun.COM mdb_printf("-----------------\n"); 45810696SDavid.Hollister@Sun.COM } else { 45910696SDavid.Hollister@Sun.COM mdb_printf("No Iports found.\n\n"); 46010696SDavid.Hollister@Sun.COM return; 46110696SDavid.Hollister@Sun.COM } 46210696SDavid.Hollister@Sun.COM 46310696SDavid.Hollister@Sun.COM list_addr = (uintptr_t)(addr + offsetof(struct pmcs_hw, iports)); 46410696SDavid.Hollister@Sun.COM 46511334SReed.Liu@Sun.COM if (mdb_pwalk("list", pmcs_iport_walk_cb, pis, list_addr) == -1) { 46610696SDavid.Hollister@Sun.COM mdb_warn("pmcs iport walk failed"); 46710696SDavid.Hollister@Sun.COM } 46810696SDavid.Hollister@Sun.COM 46910696SDavid.Hollister@Sun.COM mdb_printf("\n"); 47010696SDavid.Hollister@Sun.COM } 47110696SDavid.Hollister@Sun.COM 47211048SDavid.Hollister@Sun.COM /* ARGSUSED */ 47311048SDavid.Hollister@Sun.COM static int 47411048SDavid.Hollister@Sun.COM pmcs_utarget_walk_cb(uintptr_t addr, const void *wdata, void *priv) 47511048SDavid.Hollister@Sun.COM { 47611048SDavid.Hollister@Sun.COM pmcs_phy_t phy; 47711048SDavid.Hollister@Sun.COM 47811048SDavid.Hollister@Sun.COM if (mdb_vread(&phy, sizeof (pmcs_phy_t), (uintptr_t)addr) == -1) { 47911048SDavid.Hollister@Sun.COM mdb_warn("pmcs_utarget_walk_cb: Failed to read PHY at %p", 48011048SDavid.Hollister@Sun.COM (void *)addr); 48111048SDavid.Hollister@Sun.COM return (DCMD_ERR); 48211048SDavid.Hollister@Sun.COM } 48311048SDavid.Hollister@Sun.COM 48411048SDavid.Hollister@Sun.COM if (phy.configured && (phy.target == NULL)) { 48511048SDavid.Hollister@Sun.COM mdb_printf("SAS address: "); 48611048SDavid.Hollister@Sun.COM print_sas_address(&phy); 48711048SDavid.Hollister@Sun.COM mdb_printf(" DType: "); 48811048SDavid.Hollister@Sun.COM switch (phy.dtype) { 48911048SDavid.Hollister@Sun.COM case SAS: 49011048SDavid.Hollister@Sun.COM mdb_printf("%4s", "SAS"); 49111048SDavid.Hollister@Sun.COM break; 49211048SDavid.Hollister@Sun.COM case SATA: 49311048SDavid.Hollister@Sun.COM mdb_printf("%4s", "SATA"); 49411048SDavid.Hollister@Sun.COM break; 49511048SDavid.Hollister@Sun.COM case EXPANDER: 49611048SDavid.Hollister@Sun.COM mdb_printf("%4s", "SMP"); 49711048SDavid.Hollister@Sun.COM break; 49811048SDavid.Hollister@Sun.COM default: 49911048SDavid.Hollister@Sun.COM mdb_printf("%4s", "N/A"); 50011048SDavid.Hollister@Sun.COM break; 50111048SDavid.Hollister@Sun.COM } 50211048SDavid.Hollister@Sun.COM mdb_printf(" Path: %s\n", phy.path); 50311048SDavid.Hollister@Sun.COM } 50411048SDavid.Hollister@Sun.COM 50511048SDavid.Hollister@Sun.COM return (0); 50611048SDavid.Hollister@Sun.COM } 50711048SDavid.Hollister@Sun.COM 50811048SDavid.Hollister@Sun.COM static void 50911048SDavid.Hollister@Sun.COM display_unconfigured_targets(uintptr_t addr) 51011048SDavid.Hollister@Sun.COM { 51111048SDavid.Hollister@Sun.COM mdb_printf("Unconfigured target SAS address:\n\n"); 51211048SDavid.Hollister@Sun.COM 51311048SDavid.Hollister@Sun.COM if (mdb_pwalk("pmcs_phys", pmcs_utarget_walk_cb, NULL, addr) == -1) { 51411048SDavid.Hollister@Sun.COM mdb_warn("pmcs phys walk failed"); 51511048SDavid.Hollister@Sun.COM } 51611048SDavid.Hollister@Sun.COM } 51711048SDavid.Hollister@Sun.COM 51810743SDavid.Hollister@Sun.COM static void 51910743SDavid.Hollister@Sun.COM display_completion_queue(struct pmcs_hw ss) 52010743SDavid.Hollister@Sun.COM { 52110743SDavid.Hollister@Sun.COM pmcs_iocomp_cb_t ccb, *ccbp; 52210743SDavid.Hollister@Sun.COM pmcwork_t work; 52310743SDavid.Hollister@Sun.COM 52410743SDavid.Hollister@Sun.COM if (ss.iocomp_cb_head == NULL) { 52510743SDavid.Hollister@Sun.COM mdb_printf("Completion queue is empty.\n"); 52610743SDavid.Hollister@Sun.COM return; 52710743SDavid.Hollister@Sun.COM } 52810743SDavid.Hollister@Sun.COM 52910743SDavid.Hollister@Sun.COM ccbp = ss.iocomp_cb_head; 53010743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D\n", 53110743SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 53210743SDavid.Hollister@Sun.COM 53310743SDavid.Hollister@Sun.COM while (ccbp) { 53410743SDavid.Hollister@Sun.COM if (mdb_vread(&ccb, sizeof (pmcs_iocomp_cb_t), 53510743SDavid.Hollister@Sun.COM (uintptr_t)ccbp) != sizeof (pmcs_iocomp_cb_t)) { 53610743SDavid.Hollister@Sun.COM mdb_warn("Unable to read completion queue entry\n"); 53710743SDavid.Hollister@Sun.COM return; 53810743SDavid.Hollister@Sun.COM } 53910743SDavid.Hollister@Sun.COM 54010743SDavid.Hollister@Sun.COM if (mdb_vread(&work, sizeof (pmcwork_t), (uintptr_t)ccb.pwrk) 54110743SDavid.Hollister@Sun.COM != sizeof (pmcwork_t)) { 54210743SDavid.Hollister@Sun.COM mdb_warn("Unable to read work structure\n"); 54310743SDavid.Hollister@Sun.COM return; 54410743SDavid.Hollister@Sun.COM } 54510743SDavid.Hollister@Sun.COM 54610743SDavid.Hollister@Sun.COM /* 54710743SDavid.Hollister@Sun.COM * Only print the work structure if it's still active. If 54810743SDavid.Hollister@Sun.COM * it's not, it's been completed since we started looking at 54910743SDavid.Hollister@Sun.COM * it. 55010743SDavid.Hollister@Sun.COM */ 55110743SDavid.Hollister@Sun.COM if (work.state != PMCS_WORK_STATE_NIL) { 55210743SDavid.Hollister@Sun.COM display_one_work(&work, 0, 0); 55310743SDavid.Hollister@Sun.COM } 55410743SDavid.Hollister@Sun.COM ccbp = ccb.next; 55510743SDavid.Hollister@Sun.COM } 55610743SDavid.Hollister@Sun.COM } 55710743SDavid.Hollister@Sun.COM 558*12120SDavid.Hollister@Sun.COM static void 559*12120SDavid.Hollister@Sun.COM display_event_log(struct pmcs_hw ss) 560*12120SDavid.Hollister@Sun.COM { 561*12120SDavid.Hollister@Sun.COM pmcs_fw_event_hdr_t fwhdr; 562*12120SDavid.Hollister@Sun.COM char *header_id, *entry, *fwlogp; 563*12120SDavid.Hollister@Sun.COM uint32_t total_size = PMCS_FWLOG_SIZE, log_size, index, *swapp, sidx; 564*12120SDavid.Hollister@Sun.COM pmcs_fw_event_entry_t *fw_entryp; 565*12120SDavid.Hollister@Sun.COM struct timespec systime; 566*12120SDavid.Hollister@Sun.COM 567*12120SDavid.Hollister@Sun.COM if (ss.fwlogp == NULL) { 568*12120SDavid.Hollister@Sun.COM mdb_printf("There is no firmware event log.\n"); 569*12120SDavid.Hollister@Sun.COM return; 570*12120SDavid.Hollister@Sun.COM } 571*12120SDavid.Hollister@Sun.COM 572*12120SDavid.Hollister@Sun.COM fwlogp = (char *)ss.fwlogp; 573*12120SDavid.Hollister@Sun.COM 574*12120SDavid.Hollister@Sun.COM while (total_size != 0) { 575*12120SDavid.Hollister@Sun.COM if (mdb_vread(&fwhdr, sizeof (pmcs_fw_event_hdr_t), 576*12120SDavid.Hollister@Sun.COM (uintptr_t)fwlogp) != sizeof (pmcs_fw_event_hdr_t)) { 577*12120SDavid.Hollister@Sun.COM mdb_warn("Unable to read firmware event log header\n"); 578*12120SDavid.Hollister@Sun.COM return; 579*12120SDavid.Hollister@Sun.COM } 580*12120SDavid.Hollister@Sun.COM 581*12120SDavid.Hollister@Sun.COM /* 582*12120SDavid.Hollister@Sun.COM * Firmware event log is little-endian 583*12120SDavid.Hollister@Sun.COM */ 584*12120SDavid.Hollister@Sun.COM swapp = (uint32_t *)&fwhdr; 585*12120SDavid.Hollister@Sun.COM for (sidx = 0; sidx < (sizeof (pmcs_fw_event_hdr_t) / 586*12120SDavid.Hollister@Sun.COM sizeof (uint32_t)); sidx++) { 587*12120SDavid.Hollister@Sun.COM *swapp = LE_32(*swapp); 588*12120SDavid.Hollister@Sun.COM swapp++; 589*12120SDavid.Hollister@Sun.COM } 590*12120SDavid.Hollister@Sun.COM 591*12120SDavid.Hollister@Sun.COM if (fwhdr.fw_el_signature == PMCS_FWLOG_AAP1_SIG) { 592*12120SDavid.Hollister@Sun.COM header_id = "AAP1"; 593*12120SDavid.Hollister@Sun.COM } else if (fwhdr.fw_el_signature == PMCS_FWLOG_IOP_SIG) { 594*12120SDavid.Hollister@Sun.COM header_id = "IOP"; 595*12120SDavid.Hollister@Sun.COM } else { 596*12120SDavid.Hollister@Sun.COM mdb_warn("Invalid firmware event log signature\n"); 597*12120SDavid.Hollister@Sun.COM return; 598*12120SDavid.Hollister@Sun.COM } 599*12120SDavid.Hollister@Sun.COM 600*12120SDavid.Hollister@Sun.COM mdb_printf("Event Log: %s\n", header_id); 601*12120SDavid.Hollister@Sun.COM mdb_printf("Oldest entry: %d\n", fwhdr.fw_el_oldest_idx); 602*12120SDavid.Hollister@Sun.COM mdb_printf("Latest entry: %d\n", fwhdr.fw_el_latest_idx); 603*12120SDavid.Hollister@Sun.COM 604*12120SDavid.Hollister@Sun.COM entry = mdb_alloc(fwhdr.fw_el_entry_size, UM_SLEEP); 605*12120SDavid.Hollister@Sun.COM fw_entryp = (pmcs_fw_event_entry_t *)((void *)entry); 606*12120SDavid.Hollister@Sun.COM total_size -= sizeof (pmcs_fw_event_hdr_t); 607*12120SDavid.Hollister@Sun.COM log_size = fwhdr.fw_el_buf_size; 608*12120SDavid.Hollister@Sun.COM fwlogp += fwhdr.fw_el_entry_start_offset; 609*12120SDavid.Hollister@Sun.COM swapp = (uint32_t *)((void *)entry); 610*12120SDavid.Hollister@Sun.COM index = 0; 611*12120SDavid.Hollister@Sun.COM 612*12120SDavid.Hollister@Sun.COM mdb_printf("%8s %16s %32s %8s %3s %8s %8s %8s %8s", 613*12120SDavid.Hollister@Sun.COM "Index", "Timestamp", "Time", "Seq Num", "Sev", "Word 0", 614*12120SDavid.Hollister@Sun.COM "Word 1", "Word 2", "Word 3"); 615*12120SDavid.Hollister@Sun.COM mdb_printf("\n"); 616*12120SDavid.Hollister@Sun.COM 617*12120SDavid.Hollister@Sun.COM while (log_size != 0) { 618*12120SDavid.Hollister@Sun.COM if (mdb_vread(entry, fwhdr.fw_el_entry_size, 619*12120SDavid.Hollister@Sun.COM (uintptr_t)fwlogp) != fwhdr.fw_el_entry_size) { 620*12120SDavid.Hollister@Sun.COM mdb_warn("Unable to read event log entry\n"); 621*12120SDavid.Hollister@Sun.COM goto bail_out; 622*12120SDavid.Hollister@Sun.COM } 623*12120SDavid.Hollister@Sun.COM 624*12120SDavid.Hollister@Sun.COM for (sidx = 0; sidx < (fwhdr.fw_el_entry_size / 625*12120SDavid.Hollister@Sun.COM sizeof (uint32_t)); sidx++) { 626*12120SDavid.Hollister@Sun.COM *(swapp + sidx) = LE_32(*(swapp + sidx)); 627*12120SDavid.Hollister@Sun.COM } 628*12120SDavid.Hollister@Sun.COM 629*12120SDavid.Hollister@Sun.COM if (fw_entryp->ts_upper || fw_entryp->ts_lower) { 630*12120SDavid.Hollister@Sun.COM pmcs_fwtime_to_systime(ss, fw_entryp->ts_upper, 631*12120SDavid.Hollister@Sun.COM fw_entryp->ts_lower, &systime); 632*12120SDavid.Hollister@Sun.COM mdb_printf("%8d %08x%08x [%Y.%09ld] %8d %3d " 633*12120SDavid.Hollister@Sun.COM "%08x %08x %08x %08x\n", index, 634*12120SDavid.Hollister@Sun.COM fw_entryp->ts_upper, fw_entryp->ts_lower, 635*12120SDavid.Hollister@Sun.COM systime, fw_entryp->seq_num, 636*12120SDavid.Hollister@Sun.COM fw_entryp->severity, fw_entryp->logw0, 637*12120SDavid.Hollister@Sun.COM fw_entryp->logw1, fw_entryp->logw2, 638*12120SDavid.Hollister@Sun.COM fw_entryp->logw3); 639*12120SDavid.Hollister@Sun.COM } 640*12120SDavid.Hollister@Sun.COM 641*12120SDavid.Hollister@Sun.COM fwlogp += fwhdr.fw_el_entry_size; 642*12120SDavid.Hollister@Sun.COM total_size -= fwhdr.fw_el_entry_size; 643*12120SDavid.Hollister@Sun.COM log_size -= fwhdr.fw_el_entry_size; 644*12120SDavid.Hollister@Sun.COM index++; 645*12120SDavid.Hollister@Sun.COM } 646*12120SDavid.Hollister@Sun.COM 647*12120SDavid.Hollister@Sun.COM mdb_printf("\n"); 648*12120SDavid.Hollister@Sun.COM } 649*12120SDavid.Hollister@Sun.COM 650*12120SDavid.Hollister@Sun.COM bail_out: 651*12120SDavid.Hollister@Sun.COM mdb_free(entry, fwhdr.fw_el_entry_size); 652*12120SDavid.Hollister@Sun.COM } 653*12120SDavid.Hollister@Sun.COM 65410696SDavid.Hollister@Sun.COM /*ARGSUSED*/ 65510696SDavid.Hollister@Sun.COM static void 65610696SDavid.Hollister@Sun.COM display_hwinfo(struct pmcs_hw m, int verbose) 65710696SDavid.Hollister@Sun.COM { 65810696SDavid.Hollister@Sun.COM struct pmcs_hw *mp = &m; 65910696SDavid.Hollister@Sun.COM char *fwsupport; 66010696SDavid.Hollister@Sun.COM 66110696SDavid.Hollister@Sun.COM switch (PMCS_FW_TYPE(mp)) { 66210696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_RELEASED: 66310696SDavid.Hollister@Sun.COM fwsupport = "Released"; 66410696SDavid.Hollister@Sun.COM break; 66510696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_DEVELOPMENT: 66610696SDavid.Hollister@Sun.COM fwsupport = "Development"; 66710696SDavid.Hollister@Sun.COM break; 66810696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_ALPHA: 66910696SDavid.Hollister@Sun.COM fwsupport = "Alpha"; 67010696SDavid.Hollister@Sun.COM break; 67110696SDavid.Hollister@Sun.COM case PMCS_FW_TYPE_BETA: 67210696SDavid.Hollister@Sun.COM fwsupport = "Beta"; 67310696SDavid.Hollister@Sun.COM break; 67410696SDavid.Hollister@Sun.COM default: 67510696SDavid.Hollister@Sun.COM fwsupport = "Special"; 67610696SDavid.Hollister@Sun.COM break; 67710696SDavid.Hollister@Sun.COM } 67810696SDavid.Hollister@Sun.COM 67910696SDavid.Hollister@Sun.COM mdb_printf("\nHardware information:\n"); 68010696SDavid.Hollister@Sun.COM mdb_printf("---------------------\n"); 68110696SDavid.Hollister@Sun.COM 68210696SDavid.Hollister@Sun.COM mdb_printf("Chip revision: %c\n", 'A' + m.chiprev); 68310696SDavid.Hollister@Sun.COM mdb_printf("SAS WWID: %"PRIx64"\n", m.sas_wwns[0]); 68410696SDavid.Hollister@Sun.COM mdb_printf("Firmware version: %x.%x.%x (%s)\n", 68510696SDavid.Hollister@Sun.COM PMCS_FW_MAJOR(mp), PMCS_FW_MINOR(mp), PMCS_FW_MICRO(mp), 68610696SDavid.Hollister@Sun.COM fwsupport); 68711980SDavid.Hollister@Sun.COM mdb_printf("ILA version: %08x\n", m.ila_ver); 68811980SDavid.Hollister@Sun.COM mdb_printf("Active f/w img: %c\n", (m.fw_active_img) ? 'A' : 'B'); 68910696SDavid.Hollister@Sun.COM 69010696SDavid.Hollister@Sun.COM mdb_printf("Number of PHYs: %d\n", m.nphy); 69110696SDavid.Hollister@Sun.COM mdb_printf("Maximum commands: %d\n", m.max_cmd); 69210696SDavid.Hollister@Sun.COM mdb_printf("Maximum devices: %d\n", m.max_dev); 69310696SDavid.Hollister@Sun.COM mdb_printf("I/O queue depth: %d\n", m.ioq_depth); 69412060SDavid.Hollister@Sun.COM mdb_printf("Open retry intvl: %d usecs\n", m.open_retry_interval); 69510696SDavid.Hollister@Sun.COM if (m.fwlog == 0) { 69610696SDavid.Hollister@Sun.COM mdb_printf("Firmware logging: Disabled\n"); 69710696SDavid.Hollister@Sun.COM } else { 69810696SDavid.Hollister@Sun.COM mdb_printf("Firmware logging: Enabled (%d)\n", m.fwlog); 69910696SDavid.Hollister@Sun.COM } 70011980SDavid.Hollister@Sun.COM if (m.fwlog_file == 0) { 70111980SDavid.Hollister@Sun.COM mdb_printf("Firmware logfile: Not configured\n"); 70211980SDavid.Hollister@Sun.COM } else { 70311980SDavid.Hollister@Sun.COM mdb_printf("Firmware logfile: Configured\n"); 70411980SDavid.Hollister@Sun.COM mdb_inc_indent(2); 70511980SDavid.Hollister@Sun.COM mdb_printf("AAP1 log file: %s\n", m.fwlogfile_aap1); 70611980SDavid.Hollister@Sun.COM mdb_printf("IOP logfile: %s\n", m.fwlogfile_iop); 70711980SDavid.Hollister@Sun.COM mdb_dec_indent(2); 70811980SDavid.Hollister@Sun.COM } 70910696SDavid.Hollister@Sun.COM } 71010696SDavid.Hollister@Sun.COM 71110696SDavid.Hollister@Sun.COM static void 71210696SDavid.Hollister@Sun.COM display_targets(struct pmcs_hw m, int verbose, int totals_only) 71310696SDavid.Hollister@Sun.COM { 71410696SDavid.Hollister@Sun.COM char *dtype; 71510696SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 71610696SDavid.Hollister@Sun.COM pmcs_phy_t phy; 71710696SDavid.Hollister@Sun.COM uint16_t max_dev, idx; 71810696SDavid.Hollister@Sun.COM uint32_t sas_targets = 0, smp_targets = 0, sata_targets = 0; 71910696SDavid.Hollister@Sun.COM 72010696SDavid.Hollister@Sun.COM max_dev = m.max_dev; 72110696SDavid.Hollister@Sun.COM 72210696SDavid.Hollister@Sun.COM if (targets == NULL) { 72310696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * max_dev, UM_SLEEP); 72410696SDavid.Hollister@Sun.COM } 72510696SDavid.Hollister@Sun.COM 72610696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * max_dev, m.targets) == -1) { 72710696SDavid.Hollister@Sun.COM NOREAD(targets, m.targets); 72810696SDavid.Hollister@Sun.COM return; 72910696SDavid.Hollister@Sun.COM } 73010696SDavid.Hollister@Sun.COM 73110696SDavid.Hollister@Sun.COM if (!totals_only) { 73210696SDavid.Hollister@Sun.COM mdb_printf("\nTarget information:\n"); 73310696SDavid.Hollister@Sun.COM mdb_printf("---------------------------------------\n"); 73411347SRamana.Srikanth@Sun.COM mdb_printf("VTGT %-16s %-16s %-5s %4s %6s %s", "SAS Address", 73511347SRamana.Srikanth@Sun.COM "PHY Address", "DType", "Actv", "OnChip", "DS"); 73610696SDavid.Hollister@Sun.COM mdb_printf("\n"); 73710696SDavid.Hollister@Sun.COM } 73810696SDavid.Hollister@Sun.COM 73910696SDavid.Hollister@Sun.COM for (idx = 0; idx < max_dev; idx++) { 74010696SDavid.Hollister@Sun.COM if (targets[idx] == NULL) { 74110696SDavid.Hollister@Sun.COM continue; 74210696SDavid.Hollister@Sun.COM } 74310696SDavid.Hollister@Sun.COM 74410696SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), targets[idx]) == -1) { 74510696SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, targets[idx]); 74610696SDavid.Hollister@Sun.COM continue; 74710696SDavid.Hollister@Sun.COM } 74810696SDavid.Hollister@Sun.COM 74910696SDavid.Hollister@Sun.COM /* 75010755SJesse.Butler@Sun.COM * It has to be new or assigned to be of interest. 75110696SDavid.Hollister@Sun.COM */ 75210755SJesse.Butler@Sun.COM if (xs.new == 0 && xs.assigned == 0) { 75310696SDavid.Hollister@Sun.COM continue; 75410696SDavid.Hollister@Sun.COM } 75510696SDavid.Hollister@Sun.COM 75610696SDavid.Hollister@Sun.COM switch (xs.dtype) { 75710696SDavid.Hollister@Sun.COM case NOTHING: 75810696SDavid.Hollister@Sun.COM dtype = "None"; 75910696SDavid.Hollister@Sun.COM break; 76010696SDavid.Hollister@Sun.COM case SATA: 76110696SDavid.Hollister@Sun.COM dtype = "SATA"; 76210696SDavid.Hollister@Sun.COM sata_targets++; 76310696SDavid.Hollister@Sun.COM break; 76410696SDavid.Hollister@Sun.COM case SAS: 76510696SDavid.Hollister@Sun.COM dtype = "SAS"; 76610696SDavid.Hollister@Sun.COM sas_targets++; 76710696SDavid.Hollister@Sun.COM break; 76810696SDavid.Hollister@Sun.COM case EXPANDER: 76910696SDavid.Hollister@Sun.COM dtype = "SMP"; 77010696SDavid.Hollister@Sun.COM smp_targets++; 77110696SDavid.Hollister@Sun.COM break; 77210696SDavid.Hollister@Sun.COM } 77310696SDavid.Hollister@Sun.COM 77410696SDavid.Hollister@Sun.COM if (totals_only) { 77510696SDavid.Hollister@Sun.COM continue; 77610696SDavid.Hollister@Sun.COM } 77710696SDavid.Hollister@Sun.COM 77810696SDavid.Hollister@Sun.COM if (xs.phy) { 77910696SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), xs.phy) == -1) { 78010696SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, xs.phy); 78110696SDavid.Hollister@Sun.COM continue; 78210696SDavid.Hollister@Sun.COM } 78310696SDavid.Hollister@Sun.COM mdb_printf("%4d ", idx); 78410696SDavid.Hollister@Sun.COM print_sas_address(&phy); 78510696SDavid.Hollister@Sun.COM mdb_printf(" %16p", xs.phy); 78610696SDavid.Hollister@Sun.COM } else { 78710696SDavid.Hollister@Sun.COM mdb_printf("%4d %16s", idx, "<no phy avail>"); 78810696SDavid.Hollister@Sun.COM } 78910696SDavid.Hollister@Sun.COM mdb_printf(" %5s", dtype); 79011347SRamana.Srikanth@Sun.COM mdb_printf(" %4d", xs.actv_pkts); 79111347SRamana.Srikanth@Sun.COM mdb_printf(" %6d", xs.actv_cnt); 79210696SDavid.Hollister@Sun.COM mdb_printf(" %2d", xs.dev_state); 79310696SDavid.Hollister@Sun.COM 79410696SDavid.Hollister@Sun.COM if (verbose) { 79510696SDavid.Hollister@Sun.COM if (xs.new) { 79610696SDavid.Hollister@Sun.COM mdb_printf(" new"); 79710755SJesse.Butler@Sun.COM } 79810755SJesse.Butler@Sun.COM if (xs.assigned) { 79910696SDavid.Hollister@Sun.COM mdb_printf(" assigned"); 80010696SDavid.Hollister@Sun.COM } 80110696SDavid.Hollister@Sun.COM if (xs.draining) { 80210696SDavid.Hollister@Sun.COM mdb_printf(" draining"); 80310696SDavid.Hollister@Sun.COM } 80410696SDavid.Hollister@Sun.COM if (xs.reset_wait) { 80510696SDavid.Hollister@Sun.COM mdb_printf(" reset_wait"); 80610696SDavid.Hollister@Sun.COM } 80710696SDavid.Hollister@Sun.COM if (xs.resetting) { 80810696SDavid.Hollister@Sun.COM mdb_printf(" resetting"); 80910696SDavid.Hollister@Sun.COM } 81010696SDavid.Hollister@Sun.COM if (xs.recover_wait) { 81110696SDavid.Hollister@Sun.COM mdb_printf(" recover_wait"); 81210696SDavid.Hollister@Sun.COM } 81310696SDavid.Hollister@Sun.COM if (xs.recovering) { 81410696SDavid.Hollister@Sun.COM mdb_printf(" recovering"); 81510696SDavid.Hollister@Sun.COM } 81610696SDavid.Hollister@Sun.COM if (xs.event_recovery) { 81710696SDavid.Hollister@Sun.COM mdb_printf(" event recovery"); 81810696SDavid.Hollister@Sun.COM } 81910696SDavid.Hollister@Sun.COM if (xs.special_running) { 82010696SDavid.Hollister@Sun.COM mdb_printf(" special_active"); 82110696SDavid.Hollister@Sun.COM } 82210696SDavid.Hollister@Sun.COM if (xs.ncq) { 82310696SDavid.Hollister@Sun.COM mdb_printf(" ncq_tagmap=0x%x qdepth=%d", 82410696SDavid.Hollister@Sun.COM xs.tagmap, xs.qdepth); 82510696SDavid.Hollister@Sun.COM } else if (xs.pio) { 82610696SDavid.Hollister@Sun.COM mdb_printf(" pio"); 82710696SDavid.Hollister@Sun.COM } 82810696SDavid.Hollister@Sun.COM } 82910696SDavid.Hollister@Sun.COM 83010696SDavid.Hollister@Sun.COM mdb_printf("\n"); 83110696SDavid.Hollister@Sun.COM } 83210696SDavid.Hollister@Sun.COM 83310696SDavid.Hollister@Sun.COM if (!totals_only) { 83410696SDavid.Hollister@Sun.COM mdb_printf("\n"); 83510696SDavid.Hollister@Sun.COM } 83610696SDavid.Hollister@Sun.COM 83710696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP)\n", 83810696SDavid.Hollister@Sun.COM "Configured targets:", (sas_targets + sata_targets + smp_targets), 83910696SDavid.Hollister@Sun.COM sas_targets, sata_targets, smp_targets); 84010696SDavid.Hollister@Sun.COM } 84110696SDavid.Hollister@Sun.COM 84210743SDavid.Hollister@Sun.COM static char * 84310743SDavid.Hollister@Sun.COM work_state_to_string(uint32_t state) 84410743SDavid.Hollister@Sun.COM { 84510743SDavid.Hollister@Sun.COM char *state_string; 84610743SDavid.Hollister@Sun.COM 84710743SDavid.Hollister@Sun.COM switch (state) { 84810743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_NIL: 84910743SDavid.Hollister@Sun.COM state_string = "Free"; 85010743SDavid.Hollister@Sun.COM break; 85110743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_READY: 85210743SDavid.Hollister@Sun.COM state_string = "Ready"; 85310743SDavid.Hollister@Sun.COM break; 85410743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_ONCHIP: 85510743SDavid.Hollister@Sun.COM state_string = "On Chip"; 85610743SDavid.Hollister@Sun.COM break; 85710743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_INTR: 85810743SDavid.Hollister@Sun.COM state_string = "In Intr"; 85910743SDavid.Hollister@Sun.COM break; 86010743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_IOCOMPQ: 86110743SDavid.Hollister@Sun.COM state_string = "I/O Comp"; 86210743SDavid.Hollister@Sun.COM break; 86310743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_ABORTED: 86410743SDavid.Hollister@Sun.COM state_string = "I/O Aborted"; 86510743SDavid.Hollister@Sun.COM break; 86610743SDavid.Hollister@Sun.COM case PMCS_WORK_STATE_TIMED_OUT: 86710743SDavid.Hollister@Sun.COM state_string = "I/O Timed Out"; 86810743SDavid.Hollister@Sun.COM break; 86910743SDavid.Hollister@Sun.COM default: 87010743SDavid.Hollister@Sun.COM state_string = "INVALID"; 87110743SDavid.Hollister@Sun.COM break; 87210743SDavid.Hollister@Sun.COM } 87310743SDavid.Hollister@Sun.COM 87410743SDavid.Hollister@Sun.COM return (state_string); 87510743SDavid.Hollister@Sun.COM } 87610743SDavid.Hollister@Sun.COM 87710743SDavid.Hollister@Sun.COM static void 87810743SDavid.Hollister@Sun.COM display_one_work(pmcwork_t *wp, int verbose, int idx) 87910743SDavid.Hollister@Sun.COM { 88010743SDavid.Hollister@Sun.COM char *state, *last_state; 88110743SDavid.Hollister@Sun.COM char *path; 88210743SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 88310743SDavid.Hollister@Sun.COM pmcs_phy_t phy; 88410743SDavid.Hollister@Sun.COM int tgt; 88510743SDavid.Hollister@Sun.COM 88610743SDavid.Hollister@Sun.COM state = work_state_to_string(wp->state); 88710743SDavid.Hollister@Sun.COM last_state = work_state_to_string(wp->last_state); 88810743SDavid.Hollister@Sun.COM 88910743SDavid.Hollister@Sun.COM if (wp->ssp_event && wp->ssp_event != 0xffffffff) { 89010743SDavid.Hollister@Sun.COM mdb_printf("SSP event 0x%x", wp->ssp_event); 89110743SDavid.Hollister@Sun.COM } 89210743SDavid.Hollister@Sun.COM 89310743SDavid.Hollister@Sun.COM tgt = -1; 89410743SDavid.Hollister@Sun.COM if (wp->xp) { 89510743SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), wp->xp) == -1) { 89610743SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, wp->xp); 89710743SDavid.Hollister@Sun.COM } else { 89810743SDavid.Hollister@Sun.COM tgt = xs.target_num; 89910743SDavid.Hollister@Sun.COM } 90010743SDavid.Hollister@Sun.COM } 90110743SDavid.Hollister@Sun.COM if (wp->phy) { 90210743SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), wp->phy) == -1) { 90310743SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, wp->phy); 90410743SDavid.Hollister@Sun.COM } 90510743SDavid.Hollister@Sun.COM path = phy.path; 90610743SDavid.Hollister@Sun.COM } else { 90710743SDavid.Hollister@Sun.COM path = "N/A"; 90810743SDavid.Hollister@Sun.COM } 90910743SDavid.Hollister@Sun.COM 91010743SDavid.Hollister@Sun.COM if (verbose) { 91110743SDavid.Hollister@Sun.COM mdb_printf("%4d ", idx); 91210743SDavid.Hollister@Sun.COM } 91310743SDavid.Hollister@Sun.COM if (tgt == -1) { 91410743SDavid.Hollister@Sun.COM mdb_printf("%08x %10s %20s N/A %8u %1d %1d ", 91510743SDavid.Hollister@Sun.COM wp->htag, state, path, wp->timer, 91610743SDavid.Hollister@Sun.COM wp->onwire, wp->dead); 91710743SDavid.Hollister@Sun.COM } else { 91810743SDavid.Hollister@Sun.COM mdb_printf("%08x %10s %20s %8d %8u %1d %1d ", 91910743SDavid.Hollister@Sun.COM wp->htag, state, path, tgt, wp->timer, 92010743SDavid.Hollister@Sun.COM wp->onwire, wp->dead); 92110743SDavid.Hollister@Sun.COM } 92210743SDavid.Hollister@Sun.COM if (verbose) { 92311601SDavid.Hollister@Sun.COM mdb_printf("%08x %10s 0x%016p 0x%016p 0x%016p\n", 92411601SDavid.Hollister@Sun.COM wp->last_htag, last_state, wp->last_phy, wp->last_xp, 92511601SDavid.Hollister@Sun.COM wp->last_arg); 92610743SDavid.Hollister@Sun.COM } else { 92710743SDavid.Hollister@Sun.COM mdb_printf("\n"); 92810743SDavid.Hollister@Sun.COM } 92910743SDavid.Hollister@Sun.COM } 93010743SDavid.Hollister@Sun.COM 93110696SDavid.Hollister@Sun.COM static void 93212060SDavid.Hollister@Sun.COM display_work(struct pmcs_hw m, int verbose, int wserno) 93310696SDavid.Hollister@Sun.COM { 93410696SDavid.Hollister@Sun.COM int idx; 93510743SDavid.Hollister@Sun.COM boolean_t header_printed = B_FALSE; 93612060SDavid.Hollister@Sun.COM pmcwork_t *wp; 93712060SDavid.Hollister@Sun.COM wserno_list_t *sernop, *sp, *newsp, *sphead = NULL; 93810696SDavid.Hollister@Sun.COM uintptr_t _wp; 93912060SDavid.Hollister@Sun.COM int serno; 94012060SDavid.Hollister@Sun.COM 94112060SDavid.Hollister@Sun.COM wp = mdb_alloc(sizeof (pmcwork_t) * m.max_cmd, UM_SLEEP); 94212060SDavid.Hollister@Sun.COM _wp = (uintptr_t)m.work; 94312060SDavid.Hollister@Sun.COM sernop = mdb_alloc(sizeof (wserno_list_t) * m.max_cmd, UM_SLEEP); 94412060SDavid.Hollister@Sun.COM bzero(sernop, sizeof (wserno_list_t) * m.max_cmd); 94510696SDavid.Hollister@Sun.COM 94610696SDavid.Hollister@Sun.COM mdb_printf("\nActive Work structure information:\n"); 94710696SDavid.Hollister@Sun.COM mdb_printf("----------------------------------\n"); 94810696SDavid.Hollister@Sun.COM 94912060SDavid.Hollister@Sun.COM /* 95012060SDavid.Hollister@Sun.COM * Read in all the work structures 95112060SDavid.Hollister@Sun.COM */ 95210696SDavid.Hollister@Sun.COM for (idx = 0; idx < m.max_cmd; idx++, _wp += sizeof (pmcwork_t)) { 95312060SDavid.Hollister@Sun.COM if (MDB_RD(wp + idx, sizeof (pmcwork_t), _wp) == -1) { 95410696SDavid.Hollister@Sun.COM NOREAD(pmcwork_t, _wp); 95510696SDavid.Hollister@Sun.COM continue; 95610696SDavid.Hollister@Sun.COM } 95712060SDavid.Hollister@Sun.COM } 95810743SDavid.Hollister@Sun.COM 95912060SDavid.Hollister@Sun.COM /* 96012060SDavid.Hollister@Sun.COM * Sort by serial number? 96112060SDavid.Hollister@Sun.COM */ 96212060SDavid.Hollister@Sun.COM if (wserno) { 96312060SDavid.Hollister@Sun.COM for (idx = 0; idx < m.max_cmd; idx++) { 96412060SDavid.Hollister@Sun.COM if ((wp + idx)->htag == 0) { 96512060SDavid.Hollister@Sun.COM serno = PMCS_TAG_SERNO((wp + idx)->last_htag); 96612060SDavid.Hollister@Sun.COM } else { 96712060SDavid.Hollister@Sun.COM serno = PMCS_TAG_SERNO((wp + idx)->htag); 96812060SDavid.Hollister@Sun.COM } 96912060SDavid.Hollister@Sun.COM 97012060SDavid.Hollister@Sun.COM /* Start at the beginning of the list */ 97112060SDavid.Hollister@Sun.COM sp = sphead; 97212060SDavid.Hollister@Sun.COM newsp = sernop + idx; 97312060SDavid.Hollister@Sun.COM /* If this is the first entry, just add it */ 97412060SDavid.Hollister@Sun.COM if (sphead == NULL) { 97512060SDavid.Hollister@Sun.COM sphead = sernop; 97612060SDavid.Hollister@Sun.COM sphead->serno = serno; 97712060SDavid.Hollister@Sun.COM sphead->idx = idx; 97812060SDavid.Hollister@Sun.COM sphead->next = NULL; 97912060SDavid.Hollister@Sun.COM sphead->prev = NULL; 98012060SDavid.Hollister@Sun.COM continue; 98112060SDavid.Hollister@Sun.COM } 98212060SDavid.Hollister@Sun.COM 98312060SDavid.Hollister@Sun.COM newsp->serno = serno; 98412060SDavid.Hollister@Sun.COM newsp->idx = idx; 98512060SDavid.Hollister@Sun.COM 98612060SDavid.Hollister@Sun.COM /* Find out where in the list this goes */ 98712060SDavid.Hollister@Sun.COM while (sp) { 98812060SDavid.Hollister@Sun.COM /* This item goes before sp */ 98912060SDavid.Hollister@Sun.COM if (serno < sp->serno) { 99012060SDavid.Hollister@Sun.COM newsp->next = sp; 99112060SDavid.Hollister@Sun.COM newsp->prev = sp->prev; 99212060SDavid.Hollister@Sun.COM if (newsp->prev == NULL) { 99312060SDavid.Hollister@Sun.COM sphead = newsp; 99412060SDavid.Hollister@Sun.COM } else { 99512060SDavid.Hollister@Sun.COM newsp->prev->next = newsp; 99612060SDavid.Hollister@Sun.COM } 99712060SDavid.Hollister@Sun.COM sp->prev = newsp; 99812060SDavid.Hollister@Sun.COM break; 99912060SDavid.Hollister@Sun.COM } 100012060SDavid.Hollister@Sun.COM 100112060SDavid.Hollister@Sun.COM /* 100212060SDavid.Hollister@Sun.COM * If sp->next is NULL, this entry goes at the 100312060SDavid.Hollister@Sun.COM * end of the list 100412060SDavid.Hollister@Sun.COM */ 100512060SDavid.Hollister@Sun.COM if (sp->next == NULL) { 100612060SDavid.Hollister@Sun.COM sp->next = newsp; 100712060SDavid.Hollister@Sun.COM newsp->next = NULL; 100812060SDavid.Hollister@Sun.COM newsp->prev = sp; 100912060SDavid.Hollister@Sun.COM break; 101012060SDavid.Hollister@Sun.COM } 101112060SDavid.Hollister@Sun.COM 101212060SDavid.Hollister@Sun.COM sp = sp->next; 101312060SDavid.Hollister@Sun.COM } 101412060SDavid.Hollister@Sun.COM } 101512060SDavid.Hollister@Sun.COM 101612060SDavid.Hollister@Sun.COM /* 101712060SDavid.Hollister@Sun.COM * Now print the sorted list 101812060SDavid.Hollister@Sun.COM */ 101912060SDavid.Hollister@Sun.COM mdb_printf(" Idx %8s %10s %20s %8s %8s O D ", 102012060SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 102112060SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %18s %18s %18s\n", "LastHTAG", 102212060SDavid.Hollister@Sun.COM "LastState", "LastPHY", "LastTgt", "LastArg"); 102312060SDavid.Hollister@Sun.COM 102412060SDavid.Hollister@Sun.COM sp = sphead; 102512060SDavid.Hollister@Sun.COM while (sp) { 102612060SDavid.Hollister@Sun.COM display_one_work(wp + sp->idx, 1, sp->idx); 102712060SDavid.Hollister@Sun.COM sp = sp->next; 102812060SDavid.Hollister@Sun.COM } 102912060SDavid.Hollister@Sun.COM 103012060SDavid.Hollister@Sun.COM goto out; 103112060SDavid.Hollister@Sun.COM } 103212060SDavid.Hollister@Sun.COM 103312060SDavid.Hollister@Sun.COM /* 103412060SDavid.Hollister@Sun.COM * Now print the list, sorted by index 103512060SDavid.Hollister@Sun.COM */ 103612060SDavid.Hollister@Sun.COM for (idx = 0; idx < m.max_cmd; idx++) { 103712060SDavid.Hollister@Sun.COM if (!verbose && ((wp + idx)->htag == PMCS_TAG_TYPE_FREE)) { 103810696SDavid.Hollister@Sun.COM continue; 103910696SDavid.Hollister@Sun.COM } 104010743SDavid.Hollister@Sun.COM 104110743SDavid.Hollister@Sun.COM if (header_printed == B_FALSE) { 104210743SDavid.Hollister@Sun.COM if (verbose) { 104310743SDavid.Hollister@Sun.COM mdb_printf("%4s ", "Idx"); 104410743SDavid.Hollister@Sun.COM } 104510743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D ", 104610696SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 104710743SDavid.Hollister@Sun.COM if (verbose) { 104811601SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %18s %18s %18s\n", 104911601SDavid.Hollister@Sun.COM "LastHTAG", "LastState", "LastPHY", 105011601SDavid.Hollister@Sun.COM "LastTgt", "LastArg"); 105110743SDavid.Hollister@Sun.COM } else { 105210743SDavid.Hollister@Sun.COM mdb_printf("\n"); 105310743SDavid.Hollister@Sun.COM } 105410743SDavid.Hollister@Sun.COM header_printed = B_TRUE; 105510696SDavid.Hollister@Sun.COM } 105610743SDavid.Hollister@Sun.COM 105712060SDavid.Hollister@Sun.COM display_one_work(wp + idx, verbose, idx); 105810696SDavid.Hollister@Sun.COM } 105912060SDavid.Hollister@Sun.COM 106012060SDavid.Hollister@Sun.COM out: 106112060SDavid.Hollister@Sun.COM mdb_free(wp, sizeof (pmcwork_t) * m.max_cmd); 106212060SDavid.Hollister@Sun.COM mdb_free(sernop, sizeof (wserno_list_t) * m.max_cmd); 106310696SDavid.Hollister@Sun.COM } 106410696SDavid.Hollister@Sun.COM 106510696SDavid.Hollister@Sun.COM static void 106610743SDavid.Hollister@Sun.COM print_spcmd(pmcs_cmd_t *sp, void *kaddr, int printhdr, int verbose) 106710696SDavid.Hollister@Sun.COM { 106810743SDavid.Hollister@Sun.COM int cdb_size, idx; 106910743SDavid.Hollister@Sun.COM struct scsi_pkt pkt; 107010743SDavid.Hollister@Sun.COM uchar_t cdb[256]; 107110743SDavid.Hollister@Sun.COM 107210696SDavid.Hollister@Sun.COM if (printhdr) { 107310743SDavid.Hollister@Sun.COM if (verbose) { 107410743SDavid.Hollister@Sun.COM mdb_printf("%16s %16s %16s %8s %s CDB\n", "Command", 107510743SDavid.Hollister@Sun.COM "SCSA pkt", "DMA Chunks", "HTAG", "SATL Tag"); 107610743SDavid.Hollister@Sun.COM } else { 107710743SDavid.Hollister@Sun.COM mdb_printf("%16s %16s %16s %8s %s\n", "Command", 107810743SDavid.Hollister@Sun.COM "SCSA pkt", "DMA Chunks", "HTAG", "SATL Tag"); 107910743SDavid.Hollister@Sun.COM } 108010696SDavid.Hollister@Sun.COM } 108110743SDavid.Hollister@Sun.COM 108210743SDavid.Hollister@Sun.COM mdb_printf("%16p %16p %16p %08x %08x ", 108310696SDavid.Hollister@Sun.COM kaddr, sp->cmd_pkt, sp->cmd_clist, sp->cmd_tag, sp->cmd_satltag); 108410743SDavid.Hollister@Sun.COM 108510743SDavid.Hollister@Sun.COM /* 108610743SDavid.Hollister@Sun.COM * If we're printing verbose, dump the CDB as well. 108710743SDavid.Hollister@Sun.COM */ 108810743SDavid.Hollister@Sun.COM if (verbose) { 108910743SDavid.Hollister@Sun.COM if (sp->cmd_pkt) { 109010743SDavid.Hollister@Sun.COM if (mdb_vread(&pkt, sizeof (struct scsi_pkt), 109110743SDavid.Hollister@Sun.COM (uintptr_t)sp->cmd_pkt) != 109210743SDavid.Hollister@Sun.COM sizeof (struct scsi_pkt)) { 109310743SDavid.Hollister@Sun.COM mdb_warn("Unable to read SCSI pkt\n"); 109410743SDavid.Hollister@Sun.COM return; 109510743SDavid.Hollister@Sun.COM } 109610743SDavid.Hollister@Sun.COM cdb_size = pkt.pkt_cdblen; 109710743SDavid.Hollister@Sun.COM if (mdb_vread(&cdb[0], cdb_size, 109810743SDavid.Hollister@Sun.COM (uintptr_t)pkt.pkt_cdbp) != cdb_size) { 109910743SDavid.Hollister@Sun.COM mdb_warn("Unable to read CDB\n"); 110010743SDavid.Hollister@Sun.COM return; 110110743SDavid.Hollister@Sun.COM } 110210743SDavid.Hollister@Sun.COM 110310743SDavid.Hollister@Sun.COM for (idx = 0; idx < cdb_size; idx++) { 110410743SDavid.Hollister@Sun.COM mdb_printf("%02x ", cdb[idx]); 110510743SDavid.Hollister@Sun.COM } 110610743SDavid.Hollister@Sun.COM } else { 110710743SDavid.Hollister@Sun.COM mdb_printf("N/A"); 110810743SDavid.Hollister@Sun.COM } 110910743SDavid.Hollister@Sun.COM 111010743SDavid.Hollister@Sun.COM mdb_printf("\n"); 111110743SDavid.Hollister@Sun.COM } else { 111210743SDavid.Hollister@Sun.COM mdb_printf("\n"); 111310743SDavid.Hollister@Sun.COM } 111410696SDavid.Hollister@Sun.COM } 111510696SDavid.Hollister@Sun.COM 111610696SDavid.Hollister@Sun.COM /*ARGSUSED1*/ 111710696SDavid.Hollister@Sun.COM static void 111810696SDavid.Hollister@Sun.COM display_waitqs(struct pmcs_hw m, int verbose) 111910696SDavid.Hollister@Sun.COM { 112010696SDavid.Hollister@Sun.COM pmcs_cmd_t *sp, s; 112110696SDavid.Hollister@Sun.COM pmcs_xscsi_t xs; 112210696SDavid.Hollister@Sun.COM int first, i; 112310696SDavid.Hollister@Sun.COM int max_dev = m.max_dev; 112410696SDavid.Hollister@Sun.COM 112510696SDavid.Hollister@Sun.COM sp = m.dq.stqh_first; 112610696SDavid.Hollister@Sun.COM first = 1; 112710696SDavid.Hollister@Sun.COM while (sp) { 112810696SDavid.Hollister@Sun.COM if (first) { 112910696SDavid.Hollister@Sun.COM mdb_printf("\nDead Command Queue:\n"); 113010696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 113110696SDavid.Hollister@Sun.COM } 113210696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 113310696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 113410696SDavid.Hollister@Sun.COM break; 113510696SDavid.Hollister@Sun.COM } 113610743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 113710696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 113810696SDavid.Hollister@Sun.COM first = 0; 113910696SDavid.Hollister@Sun.COM } 114010696SDavid.Hollister@Sun.COM 114110696SDavid.Hollister@Sun.COM sp = m.cq.stqh_first; 114210696SDavid.Hollister@Sun.COM first = 1; 114310696SDavid.Hollister@Sun.COM while (sp) { 114410696SDavid.Hollister@Sun.COM if (first) { 114510696SDavid.Hollister@Sun.COM mdb_printf("\nCompletion Command Queue:\n"); 114610696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 114710696SDavid.Hollister@Sun.COM } 114810696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 114910696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 115010696SDavid.Hollister@Sun.COM break; 115110696SDavid.Hollister@Sun.COM } 115210743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 115310696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 115410696SDavid.Hollister@Sun.COM first = 0; 115510696SDavid.Hollister@Sun.COM } 115610696SDavid.Hollister@Sun.COM 115710696SDavid.Hollister@Sun.COM 115810696SDavid.Hollister@Sun.COM if (targets == NULL) { 115910696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * max_dev, UM_SLEEP); 116010696SDavid.Hollister@Sun.COM } 116110696SDavid.Hollister@Sun.COM 116210696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * max_dev, m.targets) == -1) { 116310696SDavid.Hollister@Sun.COM NOREAD(targets, m.targets); 116410696SDavid.Hollister@Sun.COM return; 116510696SDavid.Hollister@Sun.COM } 116610696SDavid.Hollister@Sun.COM 116710696SDavid.Hollister@Sun.COM for (i = 0; i < max_dev; i++) { 116810696SDavid.Hollister@Sun.COM if (targets[i] == NULL) { 116910696SDavid.Hollister@Sun.COM continue; 117010696SDavid.Hollister@Sun.COM } 117110696SDavid.Hollister@Sun.COM if (MDB_RD(&xs, sizeof (xs), targets[i]) == -1) { 117210696SDavid.Hollister@Sun.COM NOREAD(pmcs_xscsi_t, targets[i]); 117310696SDavid.Hollister@Sun.COM continue; 117410696SDavid.Hollister@Sun.COM } 117510696SDavid.Hollister@Sun.COM sp = xs.wq.stqh_first; 117610696SDavid.Hollister@Sun.COM first = 1; 117710696SDavid.Hollister@Sun.COM while (sp) { 117810696SDavid.Hollister@Sun.COM if (first) { 117910696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Wait Queue:\n", 118010696SDavid.Hollister@Sun.COM xs.target_num); 118110696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 118210696SDavid.Hollister@Sun.COM } 118310696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 118410696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 118510696SDavid.Hollister@Sun.COM break; 118610696SDavid.Hollister@Sun.COM } 118710743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 118810696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 118910696SDavid.Hollister@Sun.COM first = 0; 119010696SDavid.Hollister@Sun.COM } 119110696SDavid.Hollister@Sun.COM sp = xs.aq.stqh_first; 119210696SDavid.Hollister@Sun.COM first = 1; 119310696SDavid.Hollister@Sun.COM while (sp) { 119410696SDavid.Hollister@Sun.COM if (first) { 119510696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Active Queue:\n", 119610696SDavid.Hollister@Sun.COM xs.target_num); 119710696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 119810696SDavid.Hollister@Sun.COM } 119910696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 120010696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 120110696SDavid.Hollister@Sun.COM break; 120210696SDavid.Hollister@Sun.COM } 120310743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 120410696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 120510696SDavid.Hollister@Sun.COM first = 0; 120610696SDavid.Hollister@Sun.COM } 120710696SDavid.Hollister@Sun.COM sp = xs.sq.stqh_first; 120810696SDavid.Hollister@Sun.COM first = 1; 120910696SDavid.Hollister@Sun.COM while (sp) { 121010696SDavid.Hollister@Sun.COM if (first) { 121110696SDavid.Hollister@Sun.COM mdb_printf("\nTarget %u Special Queue:\n", 121210696SDavid.Hollister@Sun.COM xs.target_num); 121310696SDavid.Hollister@Sun.COM mdb_printf("---------------------------\n"); 121410696SDavid.Hollister@Sun.COM } 121510696SDavid.Hollister@Sun.COM if (MDB_RD(&s, sizeof (s), sp) == -1) { 121610696SDavid.Hollister@Sun.COM NOREAD(pmcs_cmd_t, sp); 121710696SDavid.Hollister@Sun.COM break; 121810696SDavid.Hollister@Sun.COM } 121910743SDavid.Hollister@Sun.COM print_spcmd(&s, sp, first, verbose); 122010696SDavid.Hollister@Sun.COM sp = s.cmd_next.stqe_next; 122110696SDavid.Hollister@Sun.COM first = 0; 122210696SDavid.Hollister@Sun.COM } 122310696SDavid.Hollister@Sun.COM } 122410696SDavid.Hollister@Sun.COM } 122510696SDavid.Hollister@Sun.COM 122610696SDavid.Hollister@Sun.COM static char * 122710696SDavid.Hollister@Sun.COM ibq_type(int qnum) 122810696SDavid.Hollister@Sun.COM { 122910696SDavid.Hollister@Sun.COM if (qnum < 0 || qnum >= PMCS_NIQ) { 123010696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 123110696SDavid.Hollister@Sun.COM } 123210696SDavid.Hollister@Sun.COM 123310696SDavid.Hollister@Sun.COM if (qnum < PMCS_IQ_OTHER) { 123410696SDavid.Hollister@Sun.COM return ("I/O"); 123510696SDavid.Hollister@Sun.COM } 123610696SDavid.Hollister@Sun.COM 123710696SDavid.Hollister@Sun.COM return ("Other"); 123810696SDavid.Hollister@Sun.COM } 123910696SDavid.Hollister@Sun.COM 124010696SDavid.Hollister@Sun.COM static char * 124110696SDavid.Hollister@Sun.COM obq_type(int qnum) 124210696SDavid.Hollister@Sun.COM { 124310696SDavid.Hollister@Sun.COM switch (qnum) { 124410696SDavid.Hollister@Sun.COM case PMCS_OQ_IODONE: 124510696SDavid.Hollister@Sun.COM return ("I/O"); 124610696SDavid.Hollister@Sun.COM break; 124710696SDavid.Hollister@Sun.COM case PMCS_OQ_GENERAL: 124810696SDavid.Hollister@Sun.COM return ("General"); 124910696SDavid.Hollister@Sun.COM break; 125010696SDavid.Hollister@Sun.COM case PMCS_OQ_EVENTS: 125110696SDavid.Hollister@Sun.COM return ("Events"); 125210696SDavid.Hollister@Sun.COM break; 125310696SDavid.Hollister@Sun.COM default: 125410696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 125510696SDavid.Hollister@Sun.COM } 125610696SDavid.Hollister@Sun.COM } 125710696SDavid.Hollister@Sun.COM 125810696SDavid.Hollister@Sun.COM static char * 125910696SDavid.Hollister@Sun.COM iomb_cat(uint32_t cat) 126010696SDavid.Hollister@Sun.COM { 126110696SDavid.Hollister@Sun.COM switch (cat) { 126210696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_NET: 126310696SDavid.Hollister@Sun.COM return ("NET"); 126410696SDavid.Hollister@Sun.COM break; 126510696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_FC: 126610696SDavid.Hollister@Sun.COM return ("FC"); 126710696SDavid.Hollister@Sun.COM break; 126810696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_SAS: 126910696SDavid.Hollister@Sun.COM return ("SAS"); 127010696SDavid.Hollister@Sun.COM break; 127110696SDavid.Hollister@Sun.COM case PMCS_IOMB_CAT_SCSI: 127210696SDavid.Hollister@Sun.COM return ("SCSI"); 127310696SDavid.Hollister@Sun.COM break; 127410696SDavid.Hollister@Sun.COM default: 127510696SDavid.Hollister@Sun.COM return ("???"); 127610696SDavid.Hollister@Sun.COM } 127710696SDavid.Hollister@Sun.COM } 127810696SDavid.Hollister@Sun.COM 127910696SDavid.Hollister@Sun.COM static char * 128011601SDavid.Hollister@Sun.COM iomb_event(uint8_t event) 128111601SDavid.Hollister@Sun.COM { 128211601SDavid.Hollister@Sun.COM switch (event) { 128311601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_STOP_STATUS: 128411601SDavid.Hollister@Sun.COM return ("PHY STOP"); 128511601SDavid.Hollister@Sun.COM break; 128611601SDavid.Hollister@Sun.COM case IOP_EVENT_SAS_PHY_UP: 128711601SDavid.Hollister@Sun.COM return ("PHY UP"); 128811601SDavid.Hollister@Sun.COM break; 128911601SDavid.Hollister@Sun.COM case IOP_EVENT_SATA_PHY_UP: 129011601SDavid.Hollister@Sun.COM return ("SATA PHY UP"); 129111601SDavid.Hollister@Sun.COM break; 129211601SDavid.Hollister@Sun.COM case IOP_EVENT_SATA_SPINUP_HOLD: 129311601SDavid.Hollister@Sun.COM return ("SATA SPINUP HOLD"); 129411601SDavid.Hollister@Sun.COM break; 129511601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_DOWN: 129611601SDavid.Hollister@Sun.COM return ("PHY DOWN"); 129711601SDavid.Hollister@Sun.COM break; 129811601SDavid.Hollister@Sun.COM case IOP_EVENT_BROADCAST_CHANGE: 129911601SDavid.Hollister@Sun.COM return ("BROADCAST CHANGE"); 130011601SDavid.Hollister@Sun.COM break; 130111601SDavid.Hollister@Sun.COM case IOP_EVENT_BROADCAST_SES: 130211601SDavid.Hollister@Sun.COM return ("BROADCAST SES"); 130311601SDavid.Hollister@Sun.COM break; 130411601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_INBOUND_CRC: 130511601SDavid.Hollister@Sun.COM return ("INBOUND CRC ERROR"); 130611601SDavid.Hollister@Sun.COM break; 130711601SDavid.Hollister@Sun.COM case IOP_EVENT_HARD_RESET_RECEIVED: 130811601SDavid.Hollister@Sun.COM return ("HARD RESET"); 130911601SDavid.Hollister@Sun.COM break; 131011601SDavid.Hollister@Sun.COM case IOP_EVENT_EVENT_ID_FRAME_TIMO: 131111601SDavid.Hollister@Sun.COM return ("IDENTIFY FRAME TIMEOUT"); 131211601SDavid.Hollister@Sun.COM break; 131311601SDavid.Hollister@Sun.COM case IOP_EVENT_BROADCAST_EXP: 131411601SDavid.Hollister@Sun.COM return ("BROADCAST EXPANDER"); 131511601SDavid.Hollister@Sun.COM break; 131611601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_START_STATUS: 131711601SDavid.Hollister@Sun.COM return ("PHY START"); 131811601SDavid.Hollister@Sun.COM break; 131911601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_INVALID_DWORD: 132011601SDavid.Hollister@Sun.COM return ("INVALID DWORD"); 132111601SDavid.Hollister@Sun.COM break; 132211601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_DISPARITY_ERROR: 132311601SDavid.Hollister@Sun.COM return ("DISPARITY ERROR"); 132411601SDavid.Hollister@Sun.COM break; 132511601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_CODE_VIOLATION: 132611601SDavid.Hollister@Sun.COM return ("CODE VIOLATION"); 132711601SDavid.Hollister@Sun.COM break; 132811601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_LOSS_OF_DWORD_SYN: 132911601SDavid.Hollister@Sun.COM return ("LOSS OF DWORD SYNC"); 133011601SDavid.Hollister@Sun.COM break; 133111601SDavid.Hollister@Sun.COM case IOP_EVENT_PHY_ERR_PHY_RESET_FAILD: 133211601SDavid.Hollister@Sun.COM return ("PHY RESET FAILED"); 133311601SDavid.Hollister@Sun.COM break; 133411601SDavid.Hollister@Sun.COM case IOP_EVENT_PORT_RECOVERY_TIMER_TMO: 133511601SDavid.Hollister@Sun.COM return ("PORT RECOVERY TIMEOUT"); 133611601SDavid.Hollister@Sun.COM break; 133711601SDavid.Hollister@Sun.COM case IOP_EVENT_PORT_RECOVER: 133811601SDavid.Hollister@Sun.COM return ("PORT RECOVERY"); 133911601SDavid.Hollister@Sun.COM break; 134011601SDavid.Hollister@Sun.COM case IOP_EVENT_PORT_RESET_TIMER_TMO: 134111601SDavid.Hollister@Sun.COM return ("PORT RESET TIMEOUT"); 134211601SDavid.Hollister@Sun.COM break; 134311601SDavid.Hollister@Sun.COM case IOP_EVENT_PORT_RESET_COMPLETE: 134411601SDavid.Hollister@Sun.COM return ("PORT RESET COMPLETE"); 134511601SDavid.Hollister@Sun.COM break; 134611601SDavid.Hollister@Sun.COM case IOP_EVENT_BROADCAST_ASYNC_EVENT: 134711601SDavid.Hollister@Sun.COM return ("BROADCAST ASYNC"); 134811601SDavid.Hollister@Sun.COM break; 134911601SDavid.Hollister@Sun.COM case IOP_EVENT_IT_NEXUS_LOSS: 135011601SDavid.Hollister@Sun.COM return ("I/T NEXUS LOSS"); 135111601SDavid.Hollister@Sun.COM break; 135211601SDavid.Hollister@Sun.COM default: 135311601SDavid.Hollister@Sun.COM return ("Unknown Event"); 135411601SDavid.Hollister@Sun.COM } 135511601SDavid.Hollister@Sun.COM } 135611601SDavid.Hollister@Sun.COM 135711601SDavid.Hollister@Sun.COM static char * 135810696SDavid.Hollister@Sun.COM inbound_iomb_opcode(uint32_t opcode) 135910696SDavid.Hollister@Sun.COM { 136010696SDavid.Hollister@Sun.COM switch (opcode) { 136110696SDavid.Hollister@Sun.COM case PMCIN_ECHO: 136210696SDavid.Hollister@Sun.COM return ("ECHO"); 136310696SDavid.Hollister@Sun.COM break; 136410696SDavid.Hollister@Sun.COM case PMCIN_GET_INFO: 136510696SDavid.Hollister@Sun.COM return ("GET_INFO"); 136610696SDavid.Hollister@Sun.COM break; 136710696SDavid.Hollister@Sun.COM case PMCIN_GET_VPD: 136810696SDavid.Hollister@Sun.COM return ("GET_VPD"); 136910696SDavid.Hollister@Sun.COM break; 137010696SDavid.Hollister@Sun.COM case PMCIN_PHY_START: 137110696SDavid.Hollister@Sun.COM return ("PHY_START"); 137210696SDavid.Hollister@Sun.COM break; 137310696SDavid.Hollister@Sun.COM case PMCIN_PHY_STOP: 137410696SDavid.Hollister@Sun.COM return ("PHY_STOP"); 137510696SDavid.Hollister@Sun.COM break; 137610696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_IO_START: 137710696SDavid.Hollister@Sun.COM return ("INI_IO_START"); 137810696SDavid.Hollister@Sun.COM break; 137910696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_TM_START: 138010696SDavid.Hollister@Sun.COM return ("INI_TM_START"); 138110696SDavid.Hollister@Sun.COM break; 138210696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EXT_IO_START: 138310696SDavid.Hollister@Sun.COM return ("INI_EXT_IO_START"); 138410696SDavid.Hollister@Sun.COM break; 138510696SDavid.Hollister@Sun.COM case PMCIN_DEVICE_HANDLE_ACCEPT: 138610696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_ACCEPT"); 138710696SDavid.Hollister@Sun.COM break; 138810696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_IO_START: 138910696SDavid.Hollister@Sun.COM return ("TGT_IO_START"); 139010696SDavid.Hollister@Sun.COM break; 139110696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_RESPONSE_START: 139210696SDavid.Hollister@Sun.COM return ("TGT_RESPONSE_START"); 139310696SDavid.Hollister@Sun.COM break; 139410696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EDC_EXT_IO_START: 139510696SDavid.Hollister@Sun.COM return ("INI_EDC_EXT_IO_START"); 139610696SDavid.Hollister@Sun.COM break; 139710696SDavid.Hollister@Sun.COM case PMCIN_SSP_INI_EDC_EXT_IO_START1: 139810696SDavid.Hollister@Sun.COM return ("INI_EDC_EXT_IO_START1"); 139910696SDavid.Hollister@Sun.COM break; 140010696SDavid.Hollister@Sun.COM case PMCIN_SSP_TGT_EDC_IO_START: 140110696SDavid.Hollister@Sun.COM return ("TGT_EDC_IO_START"); 140210696SDavid.Hollister@Sun.COM break; 140310696SDavid.Hollister@Sun.COM case PMCIN_SSP_ABORT: 140410696SDavid.Hollister@Sun.COM return ("SSP_ABORT"); 140510696SDavid.Hollister@Sun.COM break; 140610696SDavid.Hollister@Sun.COM case PMCIN_DEREGISTER_DEVICE_HANDLE: 140710696SDavid.Hollister@Sun.COM return ("DEREGISTER_DEVICE_HANDLE"); 140810696SDavid.Hollister@Sun.COM break; 140910696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_HANDLE: 141010696SDavid.Hollister@Sun.COM return ("GET_DEVICE_HANDLE"); 141110696SDavid.Hollister@Sun.COM break; 141210696SDavid.Hollister@Sun.COM case PMCIN_SMP_REQUEST: 141310696SDavid.Hollister@Sun.COM return ("SMP_REQUEST"); 141410696SDavid.Hollister@Sun.COM break; 141510696SDavid.Hollister@Sun.COM case PMCIN_SMP_RESPONSE: 141610696SDavid.Hollister@Sun.COM return ("SMP_RESPONSE"); 141710696SDavid.Hollister@Sun.COM break; 141810696SDavid.Hollister@Sun.COM case PMCIN_SMP_ABORT: 141910696SDavid.Hollister@Sun.COM return ("SMP_ABORT"); 142010696SDavid.Hollister@Sun.COM break; 142110696SDavid.Hollister@Sun.COM case PMCIN_ASSISTED_DISCOVERY: 142210696SDavid.Hollister@Sun.COM return ("ASSISTED_DISCOVERY"); 142310696SDavid.Hollister@Sun.COM break; 142410696SDavid.Hollister@Sun.COM case PMCIN_REGISTER_DEVICE: 142510696SDavid.Hollister@Sun.COM return ("REGISTER_DEVICE"); 142610696SDavid.Hollister@Sun.COM break; 142710696SDavid.Hollister@Sun.COM case PMCIN_SATA_HOST_IO_START: 142810696SDavid.Hollister@Sun.COM return ("SATA_HOST_IO_START"); 142910696SDavid.Hollister@Sun.COM break; 143010696SDavid.Hollister@Sun.COM case PMCIN_SATA_ABORT: 143110696SDavid.Hollister@Sun.COM return ("SATA_ABORT"); 143210696SDavid.Hollister@Sun.COM break; 143310696SDavid.Hollister@Sun.COM case PMCIN_LOCAL_PHY_CONTROL: 143410696SDavid.Hollister@Sun.COM return ("LOCAL_PHY_CONTROL"); 143510696SDavid.Hollister@Sun.COM break; 143610696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_INFO: 143710696SDavid.Hollister@Sun.COM return ("GET_DEVICE_INFO"); 143810696SDavid.Hollister@Sun.COM break; 143910696SDavid.Hollister@Sun.COM case PMCIN_TWI: 144010696SDavid.Hollister@Sun.COM return ("TWI"); 144110696SDavid.Hollister@Sun.COM break; 144210696SDavid.Hollister@Sun.COM case PMCIN_FW_FLASH_UPDATE: 144310696SDavid.Hollister@Sun.COM return ("FW_FLASH_UPDATE"); 144410696SDavid.Hollister@Sun.COM break; 144510696SDavid.Hollister@Sun.COM case PMCIN_SET_VPD: 144610696SDavid.Hollister@Sun.COM return ("SET_VPD"); 144710696SDavid.Hollister@Sun.COM break; 144810696SDavid.Hollister@Sun.COM case PMCIN_GPIO: 144910696SDavid.Hollister@Sun.COM return ("GPIO"); 145010696SDavid.Hollister@Sun.COM break; 145110696SDavid.Hollister@Sun.COM case PMCIN_SAS_DIAG_MODE_START_END: 145210696SDavid.Hollister@Sun.COM return ("SAS_DIAG_MODE_START_END"); 145310696SDavid.Hollister@Sun.COM break; 145410696SDavid.Hollister@Sun.COM case PMCIN_SAS_DIAG_EXECUTE: 145510696SDavid.Hollister@Sun.COM return ("SAS_DIAG_EXECUTE"); 145610696SDavid.Hollister@Sun.COM break; 145710696SDavid.Hollister@Sun.COM case PMCIN_SAW_HW_EVENT_ACK: 145810696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT_ACK"); 145910696SDavid.Hollister@Sun.COM break; 146010696SDavid.Hollister@Sun.COM case PMCIN_GET_TIME_STAMP: 146110696SDavid.Hollister@Sun.COM return ("GET_TIME_STAMP"); 146210696SDavid.Hollister@Sun.COM break; 146310696SDavid.Hollister@Sun.COM case PMCIN_PORT_CONTROL: 146410696SDavid.Hollister@Sun.COM return ("PORT_CONTROL"); 146510696SDavid.Hollister@Sun.COM break; 146610696SDavid.Hollister@Sun.COM case PMCIN_GET_NVMD_DATA: 146710696SDavid.Hollister@Sun.COM return ("GET_NVMD_DATA"); 146810696SDavid.Hollister@Sun.COM break; 146910696SDavid.Hollister@Sun.COM case PMCIN_SET_NVMD_DATA: 147010696SDavid.Hollister@Sun.COM return ("SET_NVMD_DATA"); 147110696SDavid.Hollister@Sun.COM break; 147210696SDavid.Hollister@Sun.COM case PMCIN_SET_DEVICE_STATE: 147310696SDavid.Hollister@Sun.COM return ("SET_DEVICE_STATE"); 147410696SDavid.Hollister@Sun.COM break; 147510696SDavid.Hollister@Sun.COM case PMCIN_GET_DEVICE_STATE: 147610696SDavid.Hollister@Sun.COM return ("GET_DEVICE_STATE"); 147710696SDavid.Hollister@Sun.COM break; 147810696SDavid.Hollister@Sun.COM default: 147910696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 148010696SDavid.Hollister@Sun.COM break; 148110696SDavid.Hollister@Sun.COM } 148210696SDavid.Hollister@Sun.COM } 148310696SDavid.Hollister@Sun.COM 148410696SDavid.Hollister@Sun.COM static char * 148510696SDavid.Hollister@Sun.COM outbound_iomb_opcode(uint32_t opcode) 148610696SDavid.Hollister@Sun.COM { 148710696SDavid.Hollister@Sun.COM switch (opcode) { 148810696SDavid.Hollister@Sun.COM case PMCOUT_ECHO: 148910696SDavid.Hollister@Sun.COM return ("ECHO"); 149010696SDavid.Hollister@Sun.COM break; 149110696SDavid.Hollister@Sun.COM case PMCOUT_GET_INFO: 149210696SDavid.Hollister@Sun.COM return ("GET_INFO"); 149310696SDavid.Hollister@Sun.COM break; 149410696SDavid.Hollister@Sun.COM case PMCOUT_GET_VPD: 149510696SDavid.Hollister@Sun.COM return ("GET_VPD"); 149610696SDavid.Hollister@Sun.COM break; 149710696SDavid.Hollister@Sun.COM case PMCOUT_SAS_HW_EVENT: 149810696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT"); 149910696SDavid.Hollister@Sun.COM break; 150010696SDavid.Hollister@Sun.COM case PMCOUT_SSP_COMPLETION: 150110696SDavid.Hollister@Sun.COM return ("SSP_COMPLETION"); 150210696SDavid.Hollister@Sun.COM break; 150310696SDavid.Hollister@Sun.COM case PMCOUT_SMP_COMPLETION: 150410696SDavid.Hollister@Sun.COM return ("SMP_COMPLETION"); 150510696SDavid.Hollister@Sun.COM break; 150610696SDavid.Hollister@Sun.COM case PMCOUT_LOCAL_PHY_CONTROL: 150710696SDavid.Hollister@Sun.COM return ("LOCAL_PHY_CONTROL"); 150810696SDavid.Hollister@Sun.COM break; 150910696SDavid.Hollister@Sun.COM case PMCOUT_SAS_ASSISTED_DISCOVERY_EVENT: 151010696SDavid.Hollister@Sun.COM return ("SAS_ASSISTED_DISCOVERY_SENT"); 151110696SDavid.Hollister@Sun.COM break; 151210696SDavid.Hollister@Sun.COM case PMCOUT_SATA_ASSISTED_DISCOVERY_EVENT: 151310696SDavid.Hollister@Sun.COM return ("SATA_ASSISTED_DISCOVERY_SENT"); 151410696SDavid.Hollister@Sun.COM break; 151510696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_REGISTRATION: 151610696SDavid.Hollister@Sun.COM return ("DEVICE_REGISTRATION"); 151710696SDavid.Hollister@Sun.COM break; 151810696SDavid.Hollister@Sun.COM case PMCOUT_DEREGISTER_DEVICE_HANDLE: 151910696SDavid.Hollister@Sun.COM return ("DEREGISTER_DEVICE_HANDLE"); 152010696SDavid.Hollister@Sun.COM break; 152110696SDavid.Hollister@Sun.COM case PMCOUT_GET_DEVICE_HANDLE: 152210696SDavid.Hollister@Sun.COM return ("GET_DEVICE_HANDLE"); 152310696SDavid.Hollister@Sun.COM break; 152410696SDavid.Hollister@Sun.COM case PMCOUT_SATA_COMPLETION: 152510696SDavid.Hollister@Sun.COM return ("SATA_COMPLETION"); 152610696SDavid.Hollister@Sun.COM break; 152710696SDavid.Hollister@Sun.COM case PMCOUT_SATA_EVENT: 152810696SDavid.Hollister@Sun.COM return ("SATA_EVENT"); 152910696SDavid.Hollister@Sun.COM break; 153010696SDavid.Hollister@Sun.COM case PMCOUT_SSP_EVENT: 153110696SDavid.Hollister@Sun.COM return ("SSP_EVENT"); 153210696SDavid.Hollister@Sun.COM break; 153310696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_HANDLE_ARRIVED: 153410696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_ARRIVED"); 153510696SDavid.Hollister@Sun.COM break; 153610696SDavid.Hollister@Sun.COM case PMCOUT_SMP_REQUEST_RECEIVED: 153710696SDavid.Hollister@Sun.COM return ("SMP_REQUEST_RECEIVED"); 153810696SDavid.Hollister@Sun.COM break; 153910696SDavid.Hollister@Sun.COM case PMCOUT_SSP_REQUEST_RECEIVED: 154010696SDavid.Hollister@Sun.COM return ("SSP_REQUEST_RECEIVED"); 154110696SDavid.Hollister@Sun.COM break; 154210696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_INFO: 154310696SDavid.Hollister@Sun.COM return ("DEVICE_INFO"); 154410696SDavid.Hollister@Sun.COM break; 154510696SDavid.Hollister@Sun.COM case PMCOUT_FW_FLASH_UPDATE: 154610696SDavid.Hollister@Sun.COM return ("FW_FLASH_UPDATE"); 154710696SDavid.Hollister@Sun.COM break; 154810696SDavid.Hollister@Sun.COM case PMCOUT_SET_VPD: 154910696SDavid.Hollister@Sun.COM return ("SET_VPD"); 155010696SDavid.Hollister@Sun.COM break; 155110696SDavid.Hollister@Sun.COM case PMCOUT_GPIO: 155210696SDavid.Hollister@Sun.COM return ("GPIO"); 155310696SDavid.Hollister@Sun.COM break; 155410696SDavid.Hollister@Sun.COM case PMCOUT_GPIO_EVENT: 155510696SDavid.Hollister@Sun.COM return ("GPIO_EVENT"); 155610696SDavid.Hollister@Sun.COM break; 155710696SDavid.Hollister@Sun.COM case PMCOUT_GENERAL_EVENT: 155810696SDavid.Hollister@Sun.COM return ("GENERAL_EVENT"); 155910696SDavid.Hollister@Sun.COM break; 156010696SDavid.Hollister@Sun.COM case PMCOUT_TWI: 156110696SDavid.Hollister@Sun.COM return ("TWI"); 156210696SDavid.Hollister@Sun.COM break; 156310696SDavid.Hollister@Sun.COM case PMCOUT_SSP_ABORT: 156410696SDavid.Hollister@Sun.COM return ("SSP_ABORT"); 156510696SDavid.Hollister@Sun.COM break; 156610696SDavid.Hollister@Sun.COM case PMCOUT_SATA_ABORT: 156710696SDavid.Hollister@Sun.COM return ("SATA_ABORT"); 156810696SDavid.Hollister@Sun.COM break; 156910696SDavid.Hollister@Sun.COM case PMCOUT_SAS_DIAG_MODE_START_END: 157010696SDavid.Hollister@Sun.COM return ("SAS_DIAG_MODE_START_END"); 157110696SDavid.Hollister@Sun.COM break; 157210696SDavid.Hollister@Sun.COM case PMCOUT_SAS_DIAG_EXECUTE: 157310696SDavid.Hollister@Sun.COM return ("SAS_DIAG_EXECUTE"); 157410696SDavid.Hollister@Sun.COM break; 157510696SDavid.Hollister@Sun.COM case PMCOUT_GET_TIME_STAMP: 157610696SDavid.Hollister@Sun.COM return ("GET_TIME_STAMP"); 157710696SDavid.Hollister@Sun.COM break; 157810696SDavid.Hollister@Sun.COM case PMCOUT_SAS_HW_EVENT_ACK_ACK: 157910696SDavid.Hollister@Sun.COM return ("SAS_HW_EVENT_ACK_ACK"); 158010696SDavid.Hollister@Sun.COM break; 158110696SDavid.Hollister@Sun.COM case PMCOUT_PORT_CONTROL: 158210696SDavid.Hollister@Sun.COM return ("PORT_CONTROL"); 158310696SDavid.Hollister@Sun.COM break; 158410696SDavid.Hollister@Sun.COM case PMCOUT_SKIP_ENTRIES: 158510696SDavid.Hollister@Sun.COM return ("SKIP_ENTRIES"); 158610696SDavid.Hollister@Sun.COM break; 158710696SDavid.Hollister@Sun.COM case PMCOUT_SMP_ABORT: 158810696SDavid.Hollister@Sun.COM return ("SMP_ABORT"); 158910696SDavid.Hollister@Sun.COM break; 159010696SDavid.Hollister@Sun.COM case PMCOUT_GET_NVMD_DATA: 159110696SDavid.Hollister@Sun.COM return ("GET_NVMD_DATA"); 159210696SDavid.Hollister@Sun.COM break; 159310696SDavid.Hollister@Sun.COM case PMCOUT_SET_NVMD_DATA: 159410696SDavid.Hollister@Sun.COM return ("SET_NVMD_DATA"); 159510696SDavid.Hollister@Sun.COM break; 159610696SDavid.Hollister@Sun.COM case PMCOUT_DEVICE_HANDLE_REMOVED: 159710696SDavid.Hollister@Sun.COM return ("DEVICE_HANDLE_REMOVED"); 159810696SDavid.Hollister@Sun.COM break; 159910696SDavid.Hollister@Sun.COM case PMCOUT_SET_DEVICE_STATE: 160010696SDavid.Hollister@Sun.COM return ("SET_DEVICE_STATE"); 160110696SDavid.Hollister@Sun.COM break; 160210696SDavid.Hollister@Sun.COM case PMCOUT_GET_DEVICE_STATE: 160310696SDavid.Hollister@Sun.COM return ("GET_DEVICE_STATE"); 160410696SDavid.Hollister@Sun.COM break; 160510696SDavid.Hollister@Sun.COM case PMCOUT_SET_DEVICE_INFO: 160610696SDavid.Hollister@Sun.COM return ("SET_DEVICE_INFO"); 160710696SDavid.Hollister@Sun.COM break; 160810696SDavid.Hollister@Sun.COM default: 160910696SDavid.Hollister@Sun.COM return ("UNKNOWN"); 161010696SDavid.Hollister@Sun.COM break; 161110696SDavid.Hollister@Sun.COM } 161210696SDavid.Hollister@Sun.COM } 161310696SDavid.Hollister@Sun.COM 161410696SDavid.Hollister@Sun.COM static void 161510696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(uint32_t *qentryp, int idx) 161610696SDavid.Hollister@Sun.COM { 161710696SDavid.Hollister@Sun.COM int qeidx; 161810696SDavid.Hollister@Sun.COM uint32_t word0 = LE_32(*qentryp); 161911601SDavid.Hollister@Sun.COM uint32_t word1 = LE_32(*(qentryp + 1)); 162011601SDavid.Hollister@Sun.COM uint8_t iop_event; 162110696SDavid.Hollister@Sun.COM 162210696SDavid.Hollister@Sun.COM mdb_printf("Entry #%02d\n", idx); 162310696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 162410696SDavid.Hollister@Sun.COM 162510696SDavid.Hollister@Sun.COM mdb_printf("Header: 0x%08x (", word0); 162610696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_VALID) { 162710696SDavid.Hollister@Sun.COM mdb_printf("VALID, "); 162810696SDavid.Hollister@Sun.COM } 162910696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_HIPRI) { 163010696SDavid.Hollister@Sun.COM mdb_printf("HIPRI, "); 163110696SDavid.Hollister@Sun.COM } 163210696SDavid.Hollister@Sun.COM mdb_printf("OBID=%d, ", 163310696SDavid.Hollister@Sun.COM (word0 & PMCS_IOMB_OBID_MASK) >> PMCS_IOMB_OBID_SHIFT); 163410696SDavid.Hollister@Sun.COM mdb_printf("CAT=%s, ", 163510696SDavid.Hollister@Sun.COM iomb_cat((word0 & PMCS_IOMB_CAT_MASK) >> PMCS_IOMB_CAT_SHIFT)); 163610696SDavid.Hollister@Sun.COM mdb_printf("OPCODE=%s", 163710696SDavid.Hollister@Sun.COM outbound_iomb_opcode(word0 & PMCS_IOMB_OPCODE_MASK)); 163811601SDavid.Hollister@Sun.COM if ((word0 & PMCS_IOMB_OPCODE_MASK) == PMCOUT_SAS_HW_EVENT) { 163911601SDavid.Hollister@Sun.COM iop_event = IOP_EVENT_EVENT(word1); 164011601SDavid.Hollister@Sun.COM mdb_printf(" <%s>", iomb_event(iop_event)); 164111601SDavid.Hollister@Sun.COM } 164210696SDavid.Hollister@Sun.COM mdb_printf(")\n"); 164310696SDavid.Hollister@Sun.COM 164410696SDavid.Hollister@Sun.COM mdb_printf("Remaining Payload:\n"); 164510696SDavid.Hollister@Sun.COM 164610696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 164710696SDavid.Hollister@Sun.COM for (qeidx = 1; qeidx < (PMCS_QENTRY_SIZE / 4); qeidx++) { 164810696SDavid.Hollister@Sun.COM mdb_printf("%08x ", LE_32(*(qentryp + qeidx))); 164910696SDavid.Hollister@Sun.COM } 165010696SDavid.Hollister@Sun.COM mdb_printf("\n"); 165110696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 165210696SDavid.Hollister@Sun.COM } 165310696SDavid.Hollister@Sun.COM 165410696SDavid.Hollister@Sun.COM static void 165510696SDavid.Hollister@Sun.COM display_outbound_queues(struct pmcs_hw ss, uint_t verbose) 165610696SDavid.Hollister@Sun.COM { 165710696SDavid.Hollister@Sun.COM int idx, qidx; 165810696SDavid.Hollister@Sun.COM uintptr_t obqp; 165910696SDavid.Hollister@Sun.COM uint32_t *cip; 166010696SDavid.Hollister@Sun.COM uint32_t *qentryp = mdb_alloc(PMCS_QENTRY_SIZE, UM_SLEEP); 166110696SDavid.Hollister@Sun.COM uint32_t last_consumed, oqpi; 166210696SDavid.Hollister@Sun.COM 166310696SDavid.Hollister@Sun.COM mdb_printf("\n"); 166410696SDavid.Hollister@Sun.COM mdb_printf("Outbound Queues\n"); 166510696SDavid.Hollister@Sun.COM mdb_printf("---------------\n"); 166610696SDavid.Hollister@Sun.COM 166710696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 166810696SDavid.Hollister@Sun.COM 166910696SDavid.Hollister@Sun.COM for (qidx = 0; qidx < PMCS_NOQ; qidx++) { 167010696SDavid.Hollister@Sun.COM obqp = (uintptr_t)ss.oqp[qidx]; 167110696SDavid.Hollister@Sun.COM 167210696SDavid.Hollister@Sun.COM if (obqp == NULL) { 167310696SDavid.Hollister@Sun.COM mdb_printf("No outbound queue ptr for queue #%d\n", 167410696SDavid.Hollister@Sun.COM qidx); 167510696SDavid.Hollister@Sun.COM continue; 167610696SDavid.Hollister@Sun.COM } 167710696SDavid.Hollister@Sun.COM 167810696SDavid.Hollister@Sun.COM mdb_printf("Outbound Queue #%d (Queue Type = %s)\n", qidx, 167910696SDavid.Hollister@Sun.COM obq_type(qidx)); 168010696SDavid.Hollister@Sun.COM /* 168110696SDavid.Hollister@Sun.COM * Chip is the producer, so read the actual producer index 168210696SDavid.Hollister@Sun.COM * and not the driver's version 168310696SDavid.Hollister@Sun.COM */ 168410696SDavid.Hollister@Sun.COM cip = (uint32_t *)((void *)ss.cip); 168510696SDavid.Hollister@Sun.COM if (MDB_RD(&oqpi, 4, cip + OQPI_BASE_OFFSET + 168610696SDavid.Hollister@Sun.COM (qidx * 4)) == -1) { 168710696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read oqpi\n"); 168810696SDavid.Hollister@Sun.COM break; 168910696SDavid.Hollister@Sun.COM } 169010696SDavid.Hollister@Sun.COM 169110696SDavid.Hollister@Sun.COM mdb_printf("Producer index: %d Consumer index: %d\n\n", 169210696SDavid.Hollister@Sun.COM LE_32(oqpi), ss.oqci[qidx]); 169310696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 169410696SDavid.Hollister@Sun.COM 169510696SDavid.Hollister@Sun.COM if (ss.oqci[qidx] == 0) { 169610696SDavid.Hollister@Sun.COM last_consumed = ss.ioq_depth - 1; 169710696SDavid.Hollister@Sun.COM } else { 169810696SDavid.Hollister@Sun.COM last_consumed = ss.oqci[qidx] - 1; 169910696SDavid.Hollister@Sun.COM } 170010696SDavid.Hollister@Sun.COM 170110696SDavid.Hollister@Sun.COM 170210696SDavid.Hollister@Sun.COM if (!verbose) { 170310696SDavid.Hollister@Sun.COM mdb_printf("Last processed entry:\n"); 170410696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 170510696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * last_consumed))) 170610696SDavid.Hollister@Sun.COM == -1) { 170710696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 170810696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * 170910696SDavid.Hollister@Sun.COM last_consumed))); 171010696SDavid.Hollister@Sun.COM break; 171110696SDavid.Hollister@Sun.COM } 171210696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(qentryp, last_consumed); 171310696SDavid.Hollister@Sun.COM mdb_printf("\n"); 171410696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 171510696SDavid.Hollister@Sun.COM continue; 171610696SDavid.Hollister@Sun.COM } 171710696SDavid.Hollister@Sun.COM 171810696SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.ioq_depth; idx++) { 171910696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 172010696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * idx))) == -1) { 172110696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 172210696SDavid.Hollister@Sun.COM (obqp + (PMCS_QENTRY_SIZE * idx))); 172310696SDavid.Hollister@Sun.COM break; 172410696SDavid.Hollister@Sun.COM } 172510696SDavid.Hollister@Sun.COM dump_one_qentry_outbound(qentryp, idx); 172610696SDavid.Hollister@Sun.COM } 172710696SDavid.Hollister@Sun.COM 172810696SDavid.Hollister@Sun.COM mdb_printf("\n"); 172910696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 173010696SDavid.Hollister@Sun.COM } 173110696SDavid.Hollister@Sun.COM 173210696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 173310696SDavid.Hollister@Sun.COM mdb_free(qentryp, PMCS_QENTRY_SIZE); 173410696SDavid.Hollister@Sun.COM } 173510696SDavid.Hollister@Sun.COM 173610696SDavid.Hollister@Sun.COM static void 173710696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(uint32_t *qentryp, int idx) 173810696SDavid.Hollister@Sun.COM { 173910696SDavid.Hollister@Sun.COM int qeidx; 174010696SDavid.Hollister@Sun.COM uint32_t word0 = LE_32(*qentryp); 174110696SDavid.Hollister@Sun.COM 174210696SDavid.Hollister@Sun.COM mdb_printf("Entry #%02d\n", idx); 174310696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 174410696SDavid.Hollister@Sun.COM 174510696SDavid.Hollister@Sun.COM mdb_printf("Header: 0x%08x (", word0); 174610696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_VALID) { 174710696SDavid.Hollister@Sun.COM mdb_printf("VALID, "); 174810696SDavid.Hollister@Sun.COM } 174910696SDavid.Hollister@Sun.COM if (word0 & PMCS_IOMB_HIPRI) { 175010696SDavid.Hollister@Sun.COM mdb_printf("HIPRI, "); 175110696SDavid.Hollister@Sun.COM } 175210696SDavid.Hollister@Sun.COM mdb_printf("OBID=%d, ", 175310696SDavid.Hollister@Sun.COM (word0 & PMCS_IOMB_OBID_MASK) >> PMCS_IOMB_OBID_SHIFT); 175410696SDavid.Hollister@Sun.COM mdb_printf("CAT=%s, ", 175510696SDavid.Hollister@Sun.COM iomb_cat((word0 & PMCS_IOMB_CAT_MASK) >> PMCS_IOMB_CAT_SHIFT)); 175610696SDavid.Hollister@Sun.COM mdb_printf("OPCODE=%s", 175710696SDavid.Hollister@Sun.COM inbound_iomb_opcode(word0 & PMCS_IOMB_OPCODE_MASK)); 175810696SDavid.Hollister@Sun.COM mdb_printf(")\n"); 175910696SDavid.Hollister@Sun.COM 176010696SDavid.Hollister@Sun.COM mdb_printf("HTAG: 0x%08x\n", LE_32(*(qentryp + 1))); 176110696SDavid.Hollister@Sun.COM mdb_printf("Remaining Payload:\n"); 176210696SDavid.Hollister@Sun.COM 176310696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 176410696SDavid.Hollister@Sun.COM for (qeidx = 2; qeidx < (PMCS_QENTRY_SIZE / 4); qeidx++) { 176510696SDavid.Hollister@Sun.COM mdb_printf("%08x ", LE_32(*(qentryp + qeidx))); 176610696SDavid.Hollister@Sun.COM } 176710696SDavid.Hollister@Sun.COM mdb_printf("\n"); 176810696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 176910696SDavid.Hollister@Sun.COM } 177010696SDavid.Hollister@Sun.COM 177110696SDavid.Hollister@Sun.COM static void 177210696SDavid.Hollister@Sun.COM display_inbound_queues(struct pmcs_hw ss, uint_t verbose) 177310696SDavid.Hollister@Sun.COM { 177410696SDavid.Hollister@Sun.COM int idx, qidx, iqci, last_consumed; 177510696SDavid.Hollister@Sun.COM uintptr_t ibqp; 177610696SDavid.Hollister@Sun.COM uint32_t *qentryp = mdb_alloc(PMCS_QENTRY_SIZE, UM_SLEEP); 177710696SDavid.Hollister@Sun.COM uint32_t *cip; 177810696SDavid.Hollister@Sun.COM 177910696SDavid.Hollister@Sun.COM mdb_printf("\n"); 178010696SDavid.Hollister@Sun.COM mdb_printf("Inbound Queues\n"); 178110696SDavid.Hollister@Sun.COM mdb_printf("--------------\n"); 178210696SDavid.Hollister@Sun.COM 178310696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 178410696SDavid.Hollister@Sun.COM 178510696SDavid.Hollister@Sun.COM for (qidx = 0; qidx < PMCS_NIQ; qidx++) { 178610696SDavid.Hollister@Sun.COM ibqp = (uintptr_t)ss.iqp[qidx]; 178710696SDavid.Hollister@Sun.COM 178810696SDavid.Hollister@Sun.COM if (ibqp == NULL) { 178910696SDavid.Hollister@Sun.COM mdb_printf("No inbound queue ptr for queue #%d\n", 179010696SDavid.Hollister@Sun.COM qidx); 179110696SDavid.Hollister@Sun.COM continue; 179210696SDavid.Hollister@Sun.COM } 179310696SDavid.Hollister@Sun.COM 179410696SDavid.Hollister@Sun.COM mdb_printf("Inbound Queue #%d (Queue Type = %s)\n", qidx, 179510696SDavid.Hollister@Sun.COM ibq_type(qidx)); 179610696SDavid.Hollister@Sun.COM 179710696SDavid.Hollister@Sun.COM cip = (uint32_t *)((void *)ss.cip); 179810696SDavid.Hollister@Sun.COM if (MDB_RD(&iqci, 4, cip + (qidx * 4)) == -1) { 179910696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read iqci\n"); 180010696SDavid.Hollister@Sun.COM break; 180110696SDavid.Hollister@Sun.COM } 180210696SDavid.Hollister@Sun.COM iqci = LE_32(iqci); 180310696SDavid.Hollister@Sun.COM 180410696SDavid.Hollister@Sun.COM mdb_printf("Producer index: %d Consumer index: %d\n\n", 180510696SDavid.Hollister@Sun.COM ss.shadow_iqpi[qidx], iqci); 180610696SDavid.Hollister@Sun.COM mdb_inc_indent(2); 180710696SDavid.Hollister@Sun.COM 180810696SDavid.Hollister@Sun.COM if (iqci == 0) { 180910696SDavid.Hollister@Sun.COM last_consumed = ss.ioq_depth - 1; 181010696SDavid.Hollister@Sun.COM } else { 181110696SDavid.Hollister@Sun.COM last_consumed = iqci - 1; 181210696SDavid.Hollister@Sun.COM } 181310696SDavid.Hollister@Sun.COM 181410696SDavid.Hollister@Sun.COM if (!verbose) { 181510696SDavid.Hollister@Sun.COM mdb_printf("Last processed entry:\n"); 181610696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 181710696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * last_consumed))) 181810696SDavid.Hollister@Sun.COM == -1) { 181910696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 182010696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * 182110696SDavid.Hollister@Sun.COM last_consumed))); 182210696SDavid.Hollister@Sun.COM break; 182310696SDavid.Hollister@Sun.COM } 182410696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(qentryp, last_consumed); 182510696SDavid.Hollister@Sun.COM mdb_printf("\n"); 182610696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 182710696SDavid.Hollister@Sun.COM continue; 182810696SDavid.Hollister@Sun.COM } 182910696SDavid.Hollister@Sun.COM 183010696SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.ioq_depth; idx++) { 183110696SDavid.Hollister@Sun.COM if (MDB_RD(qentryp, PMCS_QENTRY_SIZE, 183210696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * idx))) == -1) { 183310696SDavid.Hollister@Sun.COM mdb_warn("Couldn't read queue entry at 0x%p\n", 183410696SDavid.Hollister@Sun.COM (ibqp + (PMCS_QENTRY_SIZE * idx))); 183510696SDavid.Hollister@Sun.COM break; 183610696SDavid.Hollister@Sun.COM } 183710696SDavid.Hollister@Sun.COM dump_one_qentry_inbound(qentryp, idx); 183810696SDavid.Hollister@Sun.COM } 183910696SDavid.Hollister@Sun.COM 184010696SDavid.Hollister@Sun.COM mdb_printf("\n"); 184110696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 184210696SDavid.Hollister@Sun.COM } 184310696SDavid.Hollister@Sun.COM 184410696SDavid.Hollister@Sun.COM mdb_dec_indent(2); 184510696SDavid.Hollister@Sun.COM mdb_free(qentryp, PMCS_QENTRY_SIZE); 184610696SDavid.Hollister@Sun.COM } 184710696SDavid.Hollister@Sun.COM 184811601SDavid.Hollister@Sun.COM /* 184911601SDavid.Hollister@Sun.COM * phy is our copy of the PHY structure. phyp is the pointer to the actual 185011601SDavid.Hollister@Sun.COM * kernel PHY data structure 185111601SDavid.Hollister@Sun.COM */ 185210696SDavid.Hollister@Sun.COM static void 185311601SDavid.Hollister@Sun.COM display_phy(struct pmcs_phy phy, struct pmcs_phy *phyp, int verbose, 185411601SDavid.Hollister@Sun.COM int totals_only) 185510696SDavid.Hollister@Sun.COM { 185610696SDavid.Hollister@Sun.COM char *dtype, *speed; 185710696SDavid.Hollister@Sun.COM char *yes = "Yes"; 185810696SDavid.Hollister@Sun.COM char *no = "No"; 185910696SDavid.Hollister@Sun.COM char *cfgd = no; 186010696SDavid.Hollister@Sun.COM char *apend = no; 186110696SDavid.Hollister@Sun.COM char *asent = no; 186210696SDavid.Hollister@Sun.COM char *dead = no; 186310696SDavid.Hollister@Sun.COM char *changed = no; 186411601SDavid.Hollister@Sun.COM char route_attr, route_method; 186510696SDavid.Hollister@Sun.COM 186610696SDavid.Hollister@Sun.COM switch (phy.dtype) { 186710696SDavid.Hollister@Sun.COM case NOTHING: 186810696SDavid.Hollister@Sun.COM dtype = "None"; 186910696SDavid.Hollister@Sun.COM break; 187010696SDavid.Hollister@Sun.COM case SATA: 187110696SDavid.Hollister@Sun.COM dtype = "SATA"; 187210696SDavid.Hollister@Sun.COM if (phy.configured) { 187310696SDavid.Hollister@Sun.COM ++sata_phys; 187410696SDavid.Hollister@Sun.COM } 187510696SDavid.Hollister@Sun.COM break; 187610696SDavid.Hollister@Sun.COM case SAS: 187710696SDavid.Hollister@Sun.COM dtype = "SAS"; 187810696SDavid.Hollister@Sun.COM if (phy.configured) { 187910696SDavid.Hollister@Sun.COM ++sas_phys; 188010696SDavid.Hollister@Sun.COM } 188110696SDavid.Hollister@Sun.COM break; 188210696SDavid.Hollister@Sun.COM case EXPANDER: 188310696SDavid.Hollister@Sun.COM dtype = "EXP"; 188410696SDavid.Hollister@Sun.COM if (phy.configured) { 188510696SDavid.Hollister@Sun.COM ++exp_phys; 188610696SDavid.Hollister@Sun.COM } 188710696SDavid.Hollister@Sun.COM break; 188810696SDavid.Hollister@Sun.COM } 188910696SDavid.Hollister@Sun.COM 189010696SDavid.Hollister@Sun.COM if (phy.dtype == NOTHING) { 189110696SDavid.Hollister@Sun.COM empty_phys++; 189210696SDavid.Hollister@Sun.COM } else if ((phy.dtype == EXPANDER) && phy.configured) { 189310696SDavid.Hollister@Sun.COM num_expanders++; 189410696SDavid.Hollister@Sun.COM } 189510696SDavid.Hollister@Sun.COM 189610696SDavid.Hollister@Sun.COM if (totals_only) { 189710696SDavid.Hollister@Sun.COM return; 189810696SDavid.Hollister@Sun.COM } 189910696SDavid.Hollister@Sun.COM 190010696SDavid.Hollister@Sun.COM switch (phy.link_rate) { 190110696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_1_5GBIT: 190210696SDavid.Hollister@Sun.COM speed = "1.5Gb/s"; 190310696SDavid.Hollister@Sun.COM break; 190410696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_3GBIT: 190510696SDavid.Hollister@Sun.COM speed = "3 Gb/s"; 190610696SDavid.Hollister@Sun.COM break; 190710696SDavid.Hollister@Sun.COM case SAS_LINK_RATE_6GBIT: 190810696SDavid.Hollister@Sun.COM speed = "6 Gb/s"; 190910696SDavid.Hollister@Sun.COM break; 191010696SDavid.Hollister@Sun.COM default: 191110696SDavid.Hollister@Sun.COM speed = "N/A"; 191210696SDavid.Hollister@Sun.COM break; 191310696SDavid.Hollister@Sun.COM } 191410696SDavid.Hollister@Sun.COM 191510696SDavid.Hollister@Sun.COM if ((phy.dtype != NOTHING) || verbose) { 191610696SDavid.Hollister@Sun.COM print_sas_address(&phy); 191710696SDavid.Hollister@Sun.COM 191810696SDavid.Hollister@Sun.COM if (phy.device_id != PMCS_INVALID_DEVICE_ID) { 191910696SDavid.Hollister@Sun.COM mdb_printf(" %3d %4d %6s %4s ", 192010696SDavid.Hollister@Sun.COM phy.device_id, phy.phynum, speed, dtype); 192110696SDavid.Hollister@Sun.COM } else { 192210696SDavid.Hollister@Sun.COM mdb_printf(" N/A %4d %6s %4s ", 192310696SDavid.Hollister@Sun.COM phy.phynum, speed, dtype); 192410696SDavid.Hollister@Sun.COM } 192510696SDavid.Hollister@Sun.COM 192610696SDavid.Hollister@Sun.COM if (verbose) { 192710696SDavid.Hollister@Sun.COM if (phy.abort_sent) { 192810696SDavid.Hollister@Sun.COM asent = yes; 192910696SDavid.Hollister@Sun.COM } 193010696SDavid.Hollister@Sun.COM if (phy.abort_pending) { 193110696SDavid.Hollister@Sun.COM apend = yes; 193210696SDavid.Hollister@Sun.COM } 193310696SDavid.Hollister@Sun.COM if (phy.configured) { 193410696SDavid.Hollister@Sun.COM cfgd = yes; 193510696SDavid.Hollister@Sun.COM } 193610696SDavid.Hollister@Sun.COM if (phy.dead) { 193710696SDavid.Hollister@Sun.COM dead = yes; 193810696SDavid.Hollister@Sun.COM } 193910696SDavid.Hollister@Sun.COM if (phy.changed) { 194010696SDavid.Hollister@Sun.COM changed = yes; 194110696SDavid.Hollister@Sun.COM } 194210696SDavid.Hollister@Sun.COM 194311601SDavid.Hollister@Sun.COM switch (phy.routing_attr) { 194411601SDavid.Hollister@Sun.COM case SMP_ROUTING_DIRECT: 194511601SDavid.Hollister@Sun.COM route_attr = 'D'; 194611601SDavid.Hollister@Sun.COM break; 194711601SDavid.Hollister@Sun.COM case SMP_ROUTING_SUBTRACTIVE: 194811601SDavid.Hollister@Sun.COM route_attr = 'S'; 194911601SDavid.Hollister@Sun.COM break; 195011601SDavid.Hollister@Sun.COM case SMP_ROUTING_TABLE: 195111601SDavid.Hollister@Sun.COM route_attr = 'T'; 195211601SDavid.Hollister@Sun.COM break; 195311601SDavid.Hollister@Sun.COM default: 195411601SDavid.Hollister@Sun.COM route_attr = '?'; 195511601SDavid.Hollister@Sun.COM break; 195611601SDavid.Hollister@Sun.COM } 195711601SDavid.Hollister@Sun.COM 195811601SDavid.Hollister@Sun.COM switch (phy.routing_method) { 195911601SDavid.Hollister@Sun.COM case SMP_ROUTING_DIRECT: 196011601SDavid.Hollister@Sun.COM route_method = 'D'; 196111601SDavid.Hollister@Sun.COM break; 196211601SDavid.Hollister@Sun.COM case SMP_ROUTING_SUBTRACTIVE: 196311601SDavid.Hollister@Sun.COM route_method = 'S'; 196411601SDavid.Hollister@Sun.COM break; 196511601SDavid.Hollister@Sun.COM case SMP_ROUTING_TABLE: 196611601SDavid.Hollister@Sun.COM route_method = 'T'; 196711601SDavid.Hollister@Sun.COM break; 196811601SDavid.Hollister@Sun.COM default: 196911601SDavid.Hollister@Sun.COM route_attr = '?'; 197011601SDavid.Hollister@Sun.COM break; 197111601SDavid.Hollister@Sun.COM } 197211601SDavid.Hollister@Sun.COM 197311601SDavid.Hollister@Sun.COM mdb_printf("%-4s %-4s %-4s %-4s %-4s %3d %3c/%1c %3d " 197411601SDavid.Hollister@Sun.COM "%1d 0x%p ", cfgd, apend, asent, changed, dead, 197511601SDavid.Hollister@Sun.COM phy.ref_count, route_attr, route_method, 197611601SDavid.Hollister@Sun.COM phy.enum_attempts, phy.reenumerate, phy.phy_lock); 197710696SDavid.Hollister@Sun.COM } 197810696SDavid.Hollister@Sun.COM 197910696SDavid.Hollister@Sun.COM mdb_printf("Path: %s\n", phy.path); 198011601SDavid.Hollister@Sun.COM 198111601SDavid.Hollister@Sun.COM /* 198211601SDavid.Hollister@Sun.COM * In verbose mode, on the next line print the drill down 198311601SDavid.Hollister@Sun.COM * info to see either the DISCOVER response or the REPORT 198411601SDavid.Hollister@Sun.COM * GENERAL response depending on the PHY's dtype 198511601SDavid.Hollister@Sun.COM */ 198611601SDavid.Hollister@Sun.COM if (verbose) { 198711601SDavid.Hollister@Sun.COM uintptr_t tphyp = (uintptr_t)phyp; 198811601SDavid.Hollister@Sun.COM 198911601SDavid.Hollister@Sun.COM mdb_inc_indent(4); 199011601SDavid.Hollister@Sun.COM switch (phy.dtype) { 199111601SDavid.Hollister@Sun.COM case EXPANDER: 199211601SDavid.Hollister@Sun.COM if (!phy.configured) { 199311601SDavid.Hollister@Sun.COM break; 199411601SDavid.Hollister@Sun.COM } 199511601SDavid.Hollister@Sun.COM mdb_printf("REPORT GENERAL response: %p::" 199611601SDavid.Hollister@Sun.COM "print smp_report_general_resp_t\n", 199711601SDavid.Hollister@Sun.COM (tphyp + offsetof(struct pmcs_phy, 199811601SDavid.Hollister@Sun.COM rg_resp))); 199911601SDavid.Hollister@Sun.COM break; 200011601SDavid.Hollister@Sun.COM case SAS: 200111601SDavid.Hollister@Sun.COM case SATA: 200211601SDavid.Hollister@Sun.COM mdb_printf("DISCOVER response: %p::" 200311601SDavid.Hollister@Sun.COM "print smp_discover_resp_t\n", 200411601SDavid.Hollister@Sun.COM (tphyp + offsetof(struct pmcs_phy, 200511601SDavid.Hollister@Sun.COM disc_resp))); 200611601SDavid.Hollister@Sun.COM break; 200711601SDavid.Hollister@Sun.COM default: 200811601SDavid.Hollister@Sun.COM break; 200911601SDavid.Hollister@Sun.COM } 201011601SDavid.Hollister@Sun.COM mdb_dec_indent(4); 201111601SDavid.Hollister@Sun.COM } 201210696SDavid.Hollister@Sun.COM } 201310696SDavid.Hollister@Sun.COM } 201410696SDavid.Hollister@Sun.COM 201510696SDavid.Hollister@Sun.COM static void 201610696SDavid.Hollister@Sun.COM display_phys(struct pmcs_hw ss, int verbose, struct pmcs_phy *parent, int level, 201710696SDavid.Hollister@Sun.COM int totals_only) 201810696SDavid.Hollister@Sun.COM { 201910696SDavid.Hollister@Sun.COM pmcs_phy_t phy; 202010696SDavid.Hollister@Sun.COM pmcs_phy_t *pphy = parent; 202110696SDavid.Hollister@Sun.COM 202210696SDavid.Hollister@Sun.COM mdb_inc_indent(3); 202310696SDavid.Hollister@Sun.COM 202410696SDavid.Hollister@Sun.COM if (parent == NULL) { 202510696SDavid.Hollister@Sun.COM pphy = (pmcs_phy_t *)ss.root_phys; 202610696SDavid.Hollister@Sun.COM } else { 202710696SDavid.Hollister@Sun.COM pphy = (pmcs_phy_t *)parent; 202810696SDavid.Hollister@Sun.COM } 202910696SDavid.Hollister@Sun.COM 203010696SDavid.Hollister@Sun.COM if (level == 0) { 203110696SDavid.Hollister@Sun.COM sas_phys = 0; 203210696SDavid.Hollister@Sun.COM sata_phys = 0; 203310696SDavid.Hollister@Sun.COM exp_phys = 0; 203410696SDavid.Hollister@Sun.COM num_expanders = 0; 203510696SDavid.Hollister@Sun.COM empty_phys = 0; 203610696SDavid.Hollister@Sun.COM } 203710696SDavid.Hollister@Sun.COM 203810696SDavid.Hollister@Sun.COM if (!totals_only) { 203910696SDavid.Hollister@Sun.COM if (level == 0) { 204010696SDavid.Hollister@Sun.COM mdb_printf("PHY information\n"); 204110696SDavid.Hollister@Sun.COM } 204210696SDavid.Hollister@Sun.COM mdb_printf("--------\n"); 204310696SDavid.Hollister@Sun.COM mdb_printf("Level %2d\n", level); 204410696SDavid.Hollister@Sun.COM mdb_printf("--------\n"); 204510696SDavid.Hollister@Sun.COM mdb_printf("SAS Address Hdl Phy# Speed Type "); 204610696SDavid.Hollister@Sun.COM 204710696SDavid.Hollister@Sun.COM if (verbose) { 204811601SDavid.Hollister@Sun.COM mdb_printf("Cfgd AbtP AbtS Chgd Dead Ref RtA/M Enm R " 204911601SDavid.Hollister@Sun.COM "Lock\n"); 205010696SDavid.Hollister@Sun.COM } else { 205110696SDavid.Hollister@Sun.COM mdb_printf("\n"); 205210696SDavid.Hollister@Sun.COM } 205310696SDavid.Hollister@Sun.COM } 205410696SDavid.Hollister@Sun.COM 205510696SDavid.Hollister@Sun.COM while (pphy) { 205610696SDavid.Hollister@Sun.COM if (MDB_RD(&phy, sizeof (phy), (uintptr_t)pphy) == -1) { 205710696SDavid.Hollister@Sun.COM NOREAD(pmcs_phy_t, phy); 205810696SDavid.Hollister@Sun.COM break; 205910696SDavid.Hollister@Sun.COM } 206010696SDavid.Hollister@Sun.COM 206111601SDavid.Hollister@Sun.COM display_phy(phy, pphy, verbose, totals_only); 206210696SDavid.Hollister@Sun.COM 206310696SDavid.Hollister@Sun.COM if (phy.children) { 206410696SDavid.Hollister@Sun.COM display_phys(ss, verbose, phy.children, level + 1, 206510696SDavid.Hollister@Sun.COM totals_only); 206610696SDavid.Hollister@Sun.COM if (!totals_only) { 206710696SDavid.Hollister@Sun.COM mdb_printf("\n"); 206810696SDavid.Hollister@Sun.COM } 206910696SDavid.Hollister@Sun.COM } 207010696SDavid.Hollister@Sun.COM 207110696SDavid.Hollister@Sun.COM pphy = phy.sibling; 207210696SDavid.Hollister@Sun.COM } 207310696SDavid.Hollister@Sun.COM 207410696SDavid.Hollister@Sun.COM mdb_dec_indent(3); 207510696SDavid.Hollister@Sun.COM 207610696SDavid.Hollister@Sun.COM if (level == 0) { 207710696SDavid.Hollister@Sun.COM if (verbose) { 207810696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP) " 207910696SDavid.Hollister@Sun.COM "(+%d subsidiary + %d empty)\n", "Occupied PHYs:", 208010696SDavid.Hollister@Sun.COM (sas_phys + sata_phys + num_expanders), 208110696SDavid.Hollister@Sun.COM sas_phys, sata_phys, num_expanders, 208210696SDavid.Hollister@Sun.COM (exp_phys - num_expanders), empty_phys); 208310696SDavid.Hollister@Sun.COM } else { 208410696SDavid.Hollister@Sun.COM mdb_printf("%19s %d (%d SAS + %d SATA + %d SMP)\n", 208510696SDavid.Hollister@Sun.COM "Occupied PHYs:", 208610696SDavid.Hollister@Sun.COM (sas_phys + sata_phys + num_expanders), 208710696SDavid.Hollister@Sun.COM sas_phys, sata_phys, num_expanders); 208810696SDavid.Hollister@Sun.COM } 208910696SDavid.Hollister@Sun.COM } 209010696SDavid.Hollister@Sun.COM } 209110696SDavid.Hollister@Sun.COM 209210696SDavid.Hollister@Sun.COM /* 209311048SDavid.Hollister@Sun.COM * filter is used to indicate whether we are filtering log messages based 209411048SDavid.Hollister@Sun.COM * on "instance". The other filtering (based on options) depends on the 209511048SDavid.Hollister@Sun.COM * values that are passed in for "sas_addr" and "phy_path". 209611048SDavid.Hollister@Sun.COM * 209710696SDavid.Hollister@Sun.COM * MAX_INST_STRLEN is the largest string size from which we will attempt 209810696SDavid.Hollister@Sun.COM * to convert to an instance number. The string will be formed up as 209910696SDavid.Hollister@Sun.COM * "0t<inst>\0" so that mdb_strtoull can parse it properly. 210010696SDavid.Hollister@Sun.COM */ 210110696SDavid.Hollister@Sun.COM #define MAX_INST_STRLEN 8 210210696SDavid.Hollister@Sun.COM 210310696SDavid.Hollister@Sun.COM static int 210411347SRamana.Srikanth@Sun.COM pmcs_dump_tracelog(boolean_t filter, int instance, uint64_t tail_lines, 2105*12120SDavid.Hollister@Sun.COM const char *phy_path, uint64_t sas_address, uint64_t verbose) 210610696SDavid.Hollister@Sun.COM { 210710696SDavid.Hollister@Sun.COM pmcs_tbuf_t *tbuf_addr; 210810696SDavid.Hollister@Sun.COM uint_t tbuf_idx; 210910696SDavid.Hollister@Sun.COM pmcs_tbuf_t tbuf; 211010696SDavid.Hollister@Sun.COM boolean_t wrap, elem_filtered; 211110696SDavid.Hollister@Sun.COM uint_t start_idx, elems_to_print, idx, tbuf_num_elems; 211210696SDavid.Hollister@Sun.COM char *bufp; 211310696SDavid.Hollister@Sun.COM char elem_inst[MAX_INST_STRLEN], ei_idx; 211411048SDavid.Hollister@Sun.COM uint64_t sas_addr; 211511048SDavid.Hollister@Sun.COM uint8_t *sas_addressp; 211610696SDavid.Hollister@Sun.COM 211710696SDavid.Hollister@Sun.COM /* Get the address of the first element */ 211810696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_addr, "pmcs_tbuf") == -1) { 211910696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf"); 212010696SDavid.Hollister@Sun.COM return (DCMD_ERR); 212110696SDavid.Hollister@Sun.COM } 212210696SDavid.Hollister@Sun.COM 212310696SDavid.Hollister@Sun.COM /* Get the total number */ 212410696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_num_elems, "pmcs_tbuf_num_elems") == -1) { 212510696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_num_elems"); 212610696SDavid.Hollister@Sun.COM return (DCMD_ERR); 212710696SDavid.Hollister@Sun.COM } 212810696SDavid.Hollister@Sun.COM 212910696SDavid.Hollister@Sun.COM /* Get the current index */ 213010696SDavid.Hollister@Sun.COM if (mdb_readvar(&tbuf_idx, "pmcs_tbuf_idx") == -1) { 213110696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_idx"); 213210696SDavid.Hollister@Sun.COM return (DCMD_ERR); 213310696SDavid.Hollister@Sun.COM } 213410696SDavid.Hollister@Sun.COM 213510696SDavid.Hollister@Sun.COM /* Indicator as to whether the buffer has wrapped */ 213610696SDavid.Hollister@Sun.COM if (mdb_readvar(&wrap, "pmcs_tbuf_wrap") == -1) { 213710696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_tbuf_wrap"); 213810696SDavid.Hollister@Sun.COM return (DCMD_ERR); 213910696SDavid.Hollister@Sun.COM } 214010696SDavid.Hollister@Sun.COM 214111048SDavid.Hollister@Sun.COM /* 214211048SDavid.Hollister@Sun.COM * On little-endian systems, the SAS address passed in will be 214311048SDavid.Hollister@Sun.COM * byte swapped. Take care of that here. 214411048SDavid.Hollister@Sun.COM */ 214511048SDavid.Hollister@Sun.COM #if defined(_LITTLE_ENDIAN) 214611048SDavid.Hollister@Sun.COM sas_addr = ((sas_address << 56) | 214711048SDavid.Hollister@Sun.COM ((sas_address << 40) & 0xff000000000000ULL) | 214811048SDavid.Hollister@Sun.COM ((sas_address << 24) & 0xff0000000000ULL) | 214911048SDavid.Hollister@Sun.COM ((sas_address << 8) & 0xff00000000ULL) | 215011048SDavid.Hollister@Sun.COM ((sas_address >> 8) & 0xff000000ULL) | 215111048SDavid.Hollister@Sun.COM ((sas_address >> 24) & 0xff0000ULL) | 215211048SDavid.Hollister@Sun.COM ((sas_address >> 40) & 0xff00ULL) | 215311048SDavid.Hollister@Sun.COM (sas_address >> 56)); 215411048SDavid.Hollister@Sun.COM #else 215511048SDavid.Hollister@Sun.COM sas_addr = sas_address; 215611048SDavid.Hollister@Sun.COM #endif 215711048SDavid.Hollister@Sun.COM sas_addressp = (uint8_t *)&sas_addr; 215811048SDavid.Hollister@Sun.COM 215911347SRamana.Srikanth@Sun.COM /* Ensure the tail number isn't greater than the size of the log */ 216011347SRamana.Srikanth@Sun.COM if (tail_lines > tbuf_num_elems) { 216111347SRamana.Srikanth@Sun.COM tail_lines = tbuf_num_elems; 216211347SRamana.Srikanth@Sun.COM } 216311347SRamana.Srikanth@Sun.COM 216410696SDavid.Hollister@Sun.COM /* Figure out where we start and stop */ 216510696SDavid.Hollister@Sun.COM if (wrap) { 216611347SRamana.Srikanth@Sun.COM if (tail_lines) { 216711347SRamana.Srikanth@Sun.COM /* Do we need to wrap backwards? */ 216811347SRamana.Srikanth@Sun.COM if (tail_lines > tbuf_idx) { 216911347SRamana.Srikanth@Sun.COM start_idx = tbuf_num_elems - (tail_lines - 217011347SRamana.Srikanth@Sun.COM tbuf_idx); 217111347SRamana.Srikanth@Sun.COM } else { 217211347SRamana.Srikanth@Sun.COM start_idx = tbuf_idx - tail_lines; 217311347SRamana.Srikanth@Sun.COM } 217411347SRamana.Srikanth@Sun.COM elems_to_print = tail_lines; 217511347SRamana.Srikanth@Sun.COM } else { 217611347SRamana.Srikanth@Sun.COM start_idx = tbuf_idx; 217711347SRamana.Srikanth@Sun.COM elems_to_print = tbuf_num_elems; 217811347SRamana.Srikanth@Sun.COM } 217910696SDavid.Hollister@Sun.COM } else { 218011347SRamana.Srikanth@Sun.COM if (tail_lines > tbuf_idx) { 218111347SRamana.Srikanth@Sun.COM tail_lines = tbuf_idx; 218211347SRamana.Srikanth@Sun.COM } 218311347SRamana.Srikanth@Sun.COM if (tail_lines) { 218411347SRamana.Srikanth@Sun.COM start_idx = tbuf_idx - tail_lines; 218511347SRamana.Srikanth@Sun.COM elems_to_print = tail_lines; 218611347SRamana.Srikanth@Sun.COM } else { 218711347SRamana.Srikanth@Sun.COM start_idx = 0; 218811347SRamana.Srikanth@Sun.COM elems_to_print = tbuf_idx; 218911347SRamana.Srikanth@Sun.COM } 219010696SDavid.Hollister@Sun.COM } 219110696SDavid.Hollister@Sun.COM 219210696SDavid.Hollister@Sun.COM idx = start_idx; 219310696SDavid.Hollister@Sun.COM 219410696SDavid.Hollister@Sun.COM /* Dump the buffer contents */ 219510696SDavid.Hollister@Sun.COM while (elems_to_print != 0) { 219610696SDavid.Hollister@Sun.COM if (MDB_RD(&tbuf, sizeof (pmcs_tbuf_t), (tbuf_addr + idx)) 219710696SDavid.Hollister@Sun.COM == -1) { 219810696SDavid.Hollister@Sun.COM NOREAD(tbuf, (tbuf_addr + idx)); 219910696SDavid.Hollister@Sun.COM return (DCMD_ERR); 220010696SDavid.Hollister@Sun.COM } 220110696SDavid.Hollister@Sun.COM 220211048SDavid.Hollister@Sun.COM /* 220311048SDavid.Hollister@Sun.COM * Check for filtering on HBA instance 220411048SDavid.Hollister@Sun.COM */ 220510696SDavid.Hollister@Sun.COM elem_filtered = B_FALSE; 220610696SDavid.Hollister@Sun.COM 220710696SDavid.Hollister@Sun.COM if (filter) { 220810696SDavid.Hollister@Sun.COM bufp = tbuf.buf; 220910696SDavid.Hollister@Sun.COM /* Skip the driver name */ 221010696SDavid.Hollister@Sun.COM while (*bufp < '0' || *bufp > '9') { 221110696SDavid.Hollister@Sun.COM bufp++; 221210696SDavid.Hollister@Sun.COM } 221310696SDavid.Hollister@Sun.COM 221410696SDavid.Hollister@Sun.COM ei_idx = 0; 221510696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = '0'; 221610696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = 't'; 221710696SDavid.Hollister@Sun.COM while (*bufp != ':' && ei_idx < (MAX_INST_STRLEN - 1)) { 221810696SDavid.Hollister@Sun.COM elem_inst[ei_idx++] = *bufp; 221910696SDavid.Hollister@Sun.COM bufp++; 222010696SDavid.Hollister@Sun.COM } 222110696SDavid.Hollister@Sun.COM elem_inst[ei_idx] = 0; 222210696SDavid.Hollister@Sun.COM 222310696SDavid.Hollister@Sun.COM /* Get the instance */ 222410696SDavid.Hollister@Sun.COM if ((int)mdb_strtoull(elem_inst) != instance) { 222510696SDavid.Hollister@Sun.COM elem_filtered = B_TRUE; 222610696SDavid.Hollister@Sun.COM } 222710696SDavid.Hollister@Sun.COM } 222810696SDavid.Hollister@Sun.COM 222911048SDavid.Hollister@Sun.COM if (!elem_filtered && (phy_path || sas_address)) { 223011048SDavid.Hollister@Sun.COM /* 223111048SDavid.Hollister@Sun.COM * This message is not being filtered by HBA instance. 223211048SDavid.Hollister@Sun.COM * Now check to see if we're filtering based on 223311048SDavid.Hollister@Sun.COM * PHY path or SAS address. 223411048SDavid.Hollister@Sun.COM * Filtering is an "OR" operation. So, if any of the 223511048SDavid.Hollister@Sun.COM * criteria matches, this message will be printed. 223611048SDavid.Hollister@Sun.COM */ 223711048SDavid.Hollister@Sun.COM elem_filtered = B_TRUE; 223811048SDavid.Hollister@Sun.COM 223911048SDavid.Hollister@Sun.COM if (phy_path != NULL) { 224011048SDavid.Hollister@Sun.COM if (strncmp(phy_path, tbuf.phy_path, 224111048SDavid.Hollister@Sun.COM PMCS_TBUF_UA_MAX_SIZE) == 0) { 224211048SDavid.Hollister@Sun.COM elem_filtered = B_FALSE; 224311048SDavid.Hollister@Sun.COM } 224411048SDavid.Hollister@Sun.COM } 224511048SDavid.Hollister@Sun.COM if (sas_address != 0) { 224611048SDavid.Hollister@Sun.COM if (memcmp(sas_addressp, tbuf.phy_sas_address, 224711048SDavid.Hollister@Sun.COM 8) == 0) { 224811048SDavid.Hollister@Sun.COM elem_filtered = B_FALSE; 224911048SDavid.Hollister@Sun.COM } 225011048SDavid.Hollister@Sun.COM } 225111048SDavid.Hollister@Sun.COM } 225211048SDavid.Hollister@Sun.COM 225310696SDavid.Hollister@Sun.COM if (!elem_filtered) { 2254*12120SDavid.Hollister@Sun.COM /* 2255*12120SDavid.Hollister@Sun.COM * If the -v flag was given, print the firmware 2256*12120SDavid.Hollister@Sun.COM * timestamp along with the clock time 2257*12120SDavid.Hollister@Sun.COM */ 2258*12120SDavid.Hollister@Sun.COM mdb_printf("%Y.%09ld ", tbuf.timestamp); 2259*12120SDavid.Hollister@Sun.COM if (verbose) { 2260*12120SDavid.Hollister@Sun.COM mdb_printf("(0x%" PRIx64 ") ", 2261*12120SDavid.Hollister@Sun.COM tbuf.fw_timestamp); 2262*12120SDavid.Hollister@Sun.COM } 2263*12120SDavid.Hollister@Sun.COM mdb_printf("%s\n", tbuf.buf); 226410696SDavid.Hollister@Sun.COM } 226510696SDavid.Hollister@Sun.COM 226610696SDavid.Hollister@Sun.COM --elems_to_print; 226710696SDavid.Hollister@Sun.COM if (++idx == tbuf_num_elems) { 226810696SDavid.Hollister@Sun.COM idx = 0; 226910696SDavid.Hollister@Sun.COM } 227010696SDavid.Hollister@Sun.COM } 227110696SDavid.Hollister@Sun.COM 227210696SDavid.Hollister@Sun.COM return (DCMD_OK); 227310696SDavid.Hollister@Sun.COM } 227410696SDavid.Hollister@Sun.COM 227510696SDavid.Hollister@Sun.COM /* 227610696SDavid.Hollister@Sun.COM * Walkers 227710696SDavid.Hollister@Sun.COM */ 227810696SDavid.Hollister@Sun.COM static int 227910696SDavid.Hollister@Sun.COM targets_walk_i(mdb_walk_state_t *wsp) 228010696SDavid.Hollister@Sun.COM { 228110696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 228210696SDavid.Hollister@Sun.COM mdb_warn("Can not perform global walk\n"); 228310696SDavid.Hollister@Sun.COM return (WALK_ERR); 228410696SDavid.Hollister@Sun.COM } 228510696SDavid.Hollister@Sun.COM 228610696SDavid.Hollister@Sun.COM /* 228710696SDavid.Hollister@Sun.COM * Address provided belongs to HBA softstate. Get the targets pointer 228810696SDavid.Hollister@Sun.COM * to begin the walk. 228910696SDavid.Hollister@Sun.COM */ 229010696SDavid.Hollister@Sun.COM if (mdb_vread(&ss, sizeof (pmcs_hw_t), wsp->walk_addr) != 229110696SDavid.Hollister@Sun.COM sizeof (pmcs_hw_t)) { 229210696SDavid.Hollister@Sun.COM mdb_warn("Unable to read HBA softstate\n"); 229310696SDavid.Hollister@Sun.COM return (WALK_ERR); 229410696SDavid.Hollister@Sun.COM } 229510696SDavid.Hollister@Sun.COM 229610696SDavid.Hollister@Sun.COM if (targets == NULL) { 229710696SDavid.Hollister@Sun.COM targets = mdb_alloc(sizeof (targets) * ss.max_dev, UM_SLEEP); 229810696SDavid.Hollister@Sun.COM } 229910696SDavid.Hollister@Sun.COM 230010696SDavid.Hollister@Sun.COM if (MDB_RD(targets, sizeof (targets) * ss.max_dev, ss.targets) == -1) { 230110696SDavid.Hollister@Sun.COM NOREAD(targets, ss.targets); 230210696SDavid.Hollister@Sun.COM return (WALK_ERR); 230310696SDavid.Hollister@Sun.COM } 230410696SDavid.Hollister@Sun.COM 230510696SDavid.Hollister@Sun.COM target_idx = 0; 230610696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(targets[0]); 230710696SDavid.Hollister@Sun.COM wsp->walk_data = mdb_alloc(sizeof (pmcs_xscsi_t), UM_SLEEP); 230810696SDavid.Hollister@Sun.COM 230910696SDavid.Hollister@Sun.COM return (WALK_NEXT); 231010696SDavid.Hollister@Sun.COM } 231110696SDavid.Hollister@Sun.COM 231210696SDavid.Hollister@Sun.COM static int 231310696SDavid.Hollister@Sun.COM targets_walk_s(mdb_walk_state_t *wsp) 231410696SDavid.Hollister@Sun.COM { 231510696SDavid.Hollister@Sun.COM int status; 231610696SDavid.Hollister@Sun.COM 231710696SDavid.Hollister@Sun.COM if (target_idx == ss.max_dev) { 231810696SDavid.Hollister@Sun.COM return (WALK_DONE); 231910696SDavid.Hollister@Sun.COM } 232010696SDavid.Hollister@Sun.COM 232110696SDavid.Hollister@Sun.COM if (mdb_vread(wsp->walk_data, sizeof (pmcs_xscsi_t), 232210696SDavid.Hollister@Sun.COM wsp->walk_addr) == -1) { 232310696SDavid.Hollister@Sun.COM mdb_warn("Failed to read target at %p", (void *)wsp->walk_addr); 232410696SDavid.Hollister@Sun.COM return (WALK_DONE); 232510696SDavid.Hollister@Sun.COM } 232610696SDavid.Hollister@Sun.COM 232710696SDavid.Hollister@Sun.COM status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 232810696SDavid.Hollister@Sun.COM wsp->walk_cbdata); 232910696SDavid.Hollister@Sun.COM 233010696SDavid.Hollister@Sun.COM do { 233110696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(targets[++target_idx]); 233210696SDavid.Hollister@Sun.COM } while ((wsp->walk_addr == NULL) && (target_idx < ss.max_dev)); 233310696SDavid.Hollister@Sun.COM 233410696SDavid.Hollister@Sun.COM if (target_idx == ss.max_dev) { 233510696SDavid.Hollister@Sun.COM return (WALK_DONE); 233610696SDavid.Hollister@Sun.COM } 233710696SDavid.Hollister@Sun.COM 233810696SDavid.Hollister@Sun.COM return (status); 233910696SDavid.Hollister@Sun.COM } 234010696SDavid.Hollister@Sun.COM 234110696SDavid.Hollister@Sun.COM static void 234210696SDavid.Hollister@Sun.COM targets_walk_f(mdb_walk_state_t *wsp) 234310696SDavid.Hollister@Sun.COM { 234410696SDavid.Hollister@Sun.COM mdb_free(wsp->walk_data, sizeof (pmcs_xscsi_t)); 234510696SDavid.Hollister@Sun.COM } 234610696SDavid.Hollister@Sun.COM 234710696SDavid.Hollister@Sun.COM 234810696SDavid.Hollister@Sun.COM static pmcs_phy_t * 234910696SDavid.Hollister@Sun.COM pmcs_next_sibling(pmcs_phy_t *phyp) 235010696SDavid.Hollister@Sun.COM { 235110696SDavid.Hollister@Sun.COM pmcs_phy_t parent; 235210696SDavid.Hollister@Sun.COM 235310696SDavid.Hollister@Sun.COM /* 235410696SDavid.Hollister@Sun.COM * First, if this is a root PHY, there are no more siblings 235510696SDavid.Hollister@Sun.COM */ 235610696SDavid.Hollister@Sun.COM if (phyp->level == 0) { 235710696SDavid.Hollister@Sun.COM return (NULL); 235810696SDavid.Hollister@Sun.COM } 235910696SDavid.Hollister@Sun.COM 236010696SDavid.Hollister@Sun.COM /* 236110696SDavid.Hollister@Sun.COM * Otherwise, next sibling is the parent's sibling 236210696SDavid.Hollister@Sun.COM */ 236310696SDavid.Hollister@Sun.COM while (phyp->level > 0) { 236410696SDavid.Hollister@Sun.COM if (mdb_vread(&parent, sizeof (pmcs_phy_t), 236510696SDavid.Hollister@Sun.COM (uintptr_t)phyp->parent) == -1) { 236610696SDavid.Hollister@Sun.COM mdb_warn("pmcs_next_sibling: Failed to read PHY at %p", 236710696SDavid.Hollister@Sun.COM (void *)phyp->parent); 236810696SDavid.Hollister@Sun.COM return (NULL); 236910696SDavid.Hollister@Sun.COM } 237010696SDavid.Hollister@Sun.COM 237110696SDavid.Hollister@Sun.COM if (parent.sibling != NULL) { 237210696SDavid.Hollister@Sun.COM break; 237310696SDavid.Hollister@Sun.COM } 237410696SDavid.Hollister@Sun.COM 237511898SJesse.Butler@Sun.COM /* 237611898SJesse.Butler@Sun.COM * If this PHY's sibling is NULL and it's a root phy, 237711898SJesse.Butler@Sun.COM * we're done. 237811898SJesse.Butler@Sun.COM */ 237911898SJesse.Butler@Sun.COM if (parent.level == 0) { 238011898SJesse.Butler@Sun.COM return (NULL); 238111898SJesse.Butler@Sun.COM } 238211898SJesse.Butler@Sun.COM 238310696SDavid.Hollister@Sun.COM phyp = phyp->parent; 238410696SDavid.Hollister@Sun.COM } 238510696SDavid.Hollister@Sun.COM 238610696SDavid.Hollister@Sun.COM return (parent.sibling); 238710696SDavid.Hollister@Sun.COM } 238810696SDavid.Hollister@Sun.COM 238910696SDavid.Hollister@Sun.COM static int 239010696SDavid.Hollister@Sun.COM phy_walk_i(mdb_walk_state_t *wsp) 239110696SDavid.Hollister@Sun.COM { 239210696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 239310696SDavid.Hollister@Sun.COM mdb_warn("Can not perform global walk\n"); 239410696SDavid.Hollister@Sun.COM return (WALK_ERR); 239510696SDavid.Hollister@Sun.COM } 239610696SDavid.Hollister@Sun.COM 239710696SDavid.Hollister@Sun.COM /* 239810696SDavid.Hollister@Sun.COM * Address provided belongs to HBA softstate. Get the targets pointer 239910696SDavid.Hollister@Sun.COM * to begin the walk. 240010696SDavid.Hollister@Sun.COM */ 240110696SDavid.Hollister@Sun.COM if (mdb_vread(&ss, sizeof (pmcs_hw_t), wsp->walk_addr) != 240210696SDavid.Hollister@Sun.COM sizeof (pmcs_hw_t)) { 240310696SDavid.Hollister@Sun.COM mdb_warn("Unable to read HBA softstate\n"); 240410696SDavid.Hollister@Sun.COM return (WALK_ERR); 240510696SDavid.Hollister@Sun.COM } 240610696SDavid.Hollister@Sun.COM 240710696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(ss.root_phys); 240810696SDavid.Hollister@Sun.COM wsp->walk_data = mdb_alloc(sizeof (pmcs_phy_t), UM_SLEEP); 240910696SDavid.Hollister@Sun.COM 241010696SDavid.Hollister@Sun.COM return (WALK_NEXT); 241110696SDavid.Hollister@Sun.COM } 241210696SDavid.Hollister@Sun.COM 241310696SDavid.Hollister@Sun.COM static int 241410696SDavid.Hollister@Sun.COM phy_walk_s(mdb_walk_state_t *wsp) 241510696SDavid.Hollister@Sun.COM { 241610696SDavid.Hollister@Sun.COM pmcs_phy_t *phyp, *nphyp; 241710696SDavid.Hollister@Sun.COM int status; 241810696SDavid.Hollister@Sun.COM 241910696SDavid.Hollister@Sun.COM if (mdb_vread(wsp->walk_data, sizeof (pmcs_phy_t), 242010696SDavid.Hollister@Sun.COM wsp->walk_addr) == -1) { 242110696SDavid.Hollister@Sun.COM mdb_warn("phy_walk_s: Failed to read PHY at %p", 242210696SDavid.Hollister@Sun.COM (void *)wsp->walk_addr); 242310696SDavid.Hollister@Sun.COM return (WALK_DONE); 242410696SDavid.Hollister@Sun.COM } 242510696SDavid.Hollister@Sun.COM 242610696SDavid.Hollister@Sun.COM status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 242710696SDavid.Hollister@Sun.COM wsp->walk_cbdata); 242810696SDavid.Hollister@Sun.COM 242910696SDavid.Hollister@Sun.COM phyp = (pmcs_phy_t *)wsp->walk_data; 243010696SDavid.Hollister@Sun.COM if (phyp->children) { 243110696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(phyp->children); 243210696SDavid.Hollister@Sun.COM } else { 243310696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)(phyp->sibling); 243410696SDavid.Hollister@Sun.COM } 243510696SDavid.Hollister@Sun.COM 243610696SDavid.Hollister@Sun.COM if (wsp->walk_addr == NULL) { 243710696SDavid.Hollister@Sun.COM /* 243810696SDavid.Hollister@Sun.COM * We reached the end of this sibling list. Trudge back up 243910696SDavid.Hollister@Sun.COM * to the parent and find the next sibling after the expander 244010696SDavid.Hollister@Sun.COM * we just finished traversing, if there is one. 244110696SDavid.Hollister@Sun.COM */ 244210696SDavid.Hollister@Sun.COM nphyp = pmcs_next_sibling(phyp); 244310696SDavid.Hollister@Sun.COM 244410696SDavid.Hollister@Sun.COM if (nphyp == NULL) { 244510696SDavid.Hollister@Sun.COM return (WALK_DONE); 244610696SDavid.Hollister@Sun.COM } 244710696SDavid.Hollister@Sun.COM 244810696SDavid.Hollister@Sun.COM wsp->walk_addr = (uintptr_t)nphyp; 244910696SDavid.Hollister@Sun.COM } 245010696SDavid.Hollister@Sun.COM 245110696SDavid.Hollister@Sun.COM return (status); 245210696SDavid.Hollister@Sun.COM } 245310696SDavid.Hollister@Sun.COM 245410696SDavid.Hollister@Sun.COM static void 245510696SDavid.Hollister@Sun.COM phy_walk_f(mdb_walk_state_t *wsp) 245610696SDavid.Hollister@Sun.COM { 245710696SDavid.Hollister@Sun.COM mdb_free(wsp->walk_data, sizeof (pmcs_phy_t)); 245810696SDavid.Hollister@Sun.COM } 245910696SDavid.Hollister@Sun.COM 246010743SDavid.Hollister@Sun.COM static void 246110743SDavid.Hollister@Sun.COM display_matching_work(struct pmcs_hw ss, uintmax_t index, uintmax_t snum, 246210743SDavid.Hollister@Sun.COM uintmax_t tag_type) 246310743SDavid.Hollister@Sun.COM { 246410743SDavid.Hollister@Sun.COM int idx; 246510743SDavid.Hollister@Sun.COM pmcwork_t work, *wp = &work; 246610743SDavid.Hollister@Sun.COM uintptr_t _wp; 246710743SDavid.Hollister@Sun.COM boolean_t printed_header = B_FALSE; 246810743SDavid.Hollister@Sun.COM uint32_t mask, mask_val, match_val; 246910743SDavid.Hollister@Sun.COM char *match_type; 247010743SDavid.Hollister@Sun.COM 247110743SDavid.Hollister@Sun.COM if (index != UINT_MAX) { 247210743SDavid.Hollister@Sun.COM match_type = "index"; 247310743SDavid.Hollister@Sun.COM mask = PMCS_TAG_INDEX_MASK; 247410743SDavid.Hollister@Sun.COM mask_val = index << PMCS_TAG_INDEX_SHIFT; 247510743SDavid.Hollister@Sun.COM match_val = index; 247610743SDavid.Hollister@Sun.COM } else if (snum != UINT_MAX) { 247710743SDavid.Hollister@Sun.COM match_type = "serial number"; 247810743SDavid.Hollister@Sun.COM mask = PMCS_TAG_SERNO_MASK; 247910743SDavid.Hollister@Sun.COM mask_val = snum << PMCS_TAG_SERNO_SHIFT; 248010743SDavid.Hollister@Sun.COM match_val = snum; 248110743SDavid.Hollister@Sun.COM } else { 248210743SDavid.Hollister@Sun.COM switch (tag_type) { 248310743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_NONE: 248410743SDavid.Hollister@Sun.COM match_type = "tag type NONE"; 248510743SDavid.Hollister@Sun.COM break; 248610743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_CBACK: 248710743SDavid.Hollister@Sun.COM match_type = "tag type CBACK"; 248810743SDavid.Hollister@Sun.COM break; 248910743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_WAIT: 249010743SDavid.Hollister@Sun.COM match_type = "tag type WAIT"; 249110743SDavid.Hollister@Sun.COM break; 249210743SDavid.Hollister@Sun.COM } 249310743SDavid.Hollister@Sun.COM mask = PMCS_TAG_TYPE_MASK; 249410743SDavid.Hollister@Sun.COM mask_val = tag_type << PMCS_TAG_TYPE_SHIFT; 249510743SDavid.Hollister@Sun.COM match_val = tag_type; 249610743SDavid.Hollister@Sun.COM } 249710743SDavid.Hollister@Sun.COM 249810743SDavid.Hollister@Sun.COM _wp = (uintptr_t)ss.work; 249910743SDavid.Hollister@Sun.COM 250010743SDavid.Hollister@Sun.COM for (idx = 0; idx < ss.max_cmd; idx++, _wp += sizeof (pmcwork_t)) { 250110743SDavid.Hollister@Sun.COM if (MDB_RD(&work, sizeof (pmcwork_t), _wp) == -1) { 250210743SDavid.Hollister@Sun.COM NOREAD(pmcwork_t, _wp); 250310743SDavid.Hollister@Sun.COM continue; 250410743SDavid.Hollister@Sun.COM } 250510743SDavid.Hollister@Sun.COM 250610743SDavid.Hollister@Sun.COM if ((work.htag & mask) != mask_val) { 250710743SDavid.Hollister@Sun.COM continue; 250810743SDavid.Hollister@Sun.COM } 250910743SDavid.Hollister@Sun.COM 251010743SDavid.Hollister@Sun.COM if (printed_header == B_FALSE) { 251110743SDavid.Hollister@Sun.COM if (tag_type) { 251210743SDavid.Hollister@Sun.COM mdb_printf("\nWork structures matching %s\n\n", 251310743SDavid.Hollister@Sun.COM match_type, match_val); 251410743SDavid.Hollister@Sun.COM } else { 251510743SDavid.Hollister@Sun.COM mdb_printf("\nWork structures matching %s of " 251610743SDavid.Hollister@Sun.COM "0x%x\n\n", match_type, match_val); 251710743SDavid.Hollister@Sun.COM } 251810743SDavid.Hollister@Sun.COM mdb_printf("%8s %10s %20s %8s %8s O D\n", 251910743SDavid.Hollister@Sun.COM "HTag", "State", "Phy Path", "Target", "Timer"); 252010743SDavid.Hollister@Sun.COM printed_header = B_TRUE; 252110743SDavid.Hollister@Sun.COM } 252210743SDavid.Hollister@Sun.COM 252310743SDavid.Hollister@Sun.COM display_one_work(wp, 0, 0); 252410743SDavid.Hollister@Sun.COM } 252510743SDavid.Hollister@Sun.COM 252610743SDavid.Hollister@Sun.COM if (!printed_header) { 252710743SDavid.Hollister@Sun.COM mdb_printf("No work structure matches found\n"); 252810743SDavid.Hollister@Sun.COM } 252910743SDavid.Hollister@Sun.COM } 253010743SDavid.Hollister@Sun.COM 253110743SDavid.Hollister@Sun.COM static int 253210743SDavid.Hollister@Sun.COM pmcs_tag(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 253310743SDavid.Hollister@Sun.COM { 253410743SDavid.Hollister@Sun.COM struct pmcs_hw ss; 253510743SDavid.Hollister@Sun.COM uintmax_t tag_type = UINT_MAX; 253610743SDavid.Hollister@Sun.COM uintmax_t snum = UINT_MAX; 253710743SDavid.Hollister@Sun.COM uintmax_t index = UINT_MAX; 253810743SDavid.Hollister@Sun.COM int args = 0; 253910743SDavid.Hollister@Sun.COM void *pmcs_state; 254010743SDavid.Hollister@Sun.COM char *state_str; 254110743SDavid.Hollister@Sun.COM struct dev_info dip; 254210743SDavid.Hollister@Sun.COM 254310743SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 254410743SDavid.Hollister@Sun.COM pmcs_state = NULL; 254510743SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 254610743SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 254710743SDavid.Hollister@Sun.COM return (DCMD_ERR); 254810743SDavid.Hollister@Sun.COM } 254910743SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_tag", argc, 255010743SDavid.Hollister@Sun.COM argv, (uintptr_t)pmcs_state) == -1) { 255110743SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed"); 255210743SDavid.Hollister@Sun.COM return (DCMD_ERR); 255310743SDavid.Hollister@Sun.COM } 255410743SDavid.Hollister@Sun.COM return (DCMD_OK); 255510743SDavid.Hollister@Sun.COM } 255610743SDavid.Hollister@Sun.COM 255710743SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 255810743SDavid.Hollister@Sun.COM 'i', MDB_OPT_UINT64, &index, 255910743SDavid.Hollister@Sun.COM 's', MDB_OPT_UINT64, &snum, 256010743SDavid.Hollister@Sun.COM 't', MDB_OPT_UINT64, &tag_type) != argc) 256110743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 256210743SDavid.Hollister@Sun.COM 256310743SDavid.Hollister@Sun.COM /* 256410743SDavid.Hollister@Sun.COM * Count the number of supplied options and make sure they are 256510743SDavid.Hollister@Sun.COM * within appropriate ranges. If they're set to UINT_MAX, that means 256610743SDavid.Hollister@Sun.COM * they were not supplied, in which case reset them to 0. 256710743SDavid.Hollister@Sun.COM */ 256810743SDavid.Hollister@Sun.COM if (index != UINT_MAX) { 256910743SDavid.Hollister@Sun.COM args++; 257010743SDavid.Hollister@Sun.COM if (index > PMCS_TAG_INDEX_MASK) { 257110743SDavid.Hollister@Sun.COM mdb_warn("Index is out of range\n"); 257210743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 257310743SDavid.Hollister@Sun.COM } 257410743SDavid.Hollister@Sun.COM } 257510743SDavid.Hollister@Sun.COM 257610743SDavid.Hollister@Sun.COM if (tag_type != UINT_MAX) { 257710743SDavid.Hollister@Sun.COM args++; 257810743SDavid.Hollister@Sun.COM switch (tag_type) { 257910743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_NONE: 258010743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_CBACK: 258110743SDavid.Hollister@Sun.COM case PMCS_TAG_TYPE_WAIT: 258210743SDavid.Hollister@Sun.COM break; 258310743SDavid.Hollister@Sun.COM default: 258410743SDavid.Hollister@Sun.COM mdb_warn("Invalid tag type\n"); 258510743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 258610743SDavid.Hollister@Sun.COM } 258710743SDavid.Hollister@Sun.COM } 258810743SDavid.Hollister@Sun.COM 258910743SDavid.Hollister@Sun.COM if (snum != UINT_MAX) { 259010743SDavid.Hollister@Sun.COM args++; 259110743SDavid.Hollister@Sun.COM if (snum > (PMCS_TAG_SERNO_MASK >> PMCS_TAG_SERNO_SHIFT)) { 259210743SDavid.Hollister@Sun.COM mdb_warn("Serial number is out of range\n"); 259310743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 259410743SDavid.Hollister@Sun.COM } 259510743SDavid.Hollister@Sun.COM } 259610743SDavid.Hollister@Sun.COM 259710743SDavid.Hollister@Sun.COM /* 259810743SDavid.Hollister@Sun.COM * Make sure 1 and only 1 option is specified 259910743SDavid.Hollister@Sun.COM */ 260010743SDavid.Hollister@Sun.COM if ((args == 0) || (args > 1)) { 260110743SDavid.Hollister@Sun.COM mdb_warn("Exactly one of -i, -s and -t must be specified\n"); 260210743SDavid.Hollister@Sun.COM return (DCMD_USAGE); 260310743SDavid.Hollister@Sun.COM } 260410743SDavid.Hollister@Sun.COM 260510743SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 260610743SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 260710743SDavid.Hollister@Sun.COM return (DCMD_ERR); 260810743SDavid.Hollister@Sun.COM } 260910743SDavid.Hollister@Sun.COM 261010743SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 261110743SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 261210743SDavid.Hollister@Sun.COM return (DCMD_ERR); 261310743SDavid.Hollister@Sun.COM } 261410743SDavid.Hollister@Sun.COM 261510743SDavid.Hollister@Sun.COM /* processing completed */ 261610743SDavid.Hollister@Sun.COM 261710743SDavid.Hollister@Sun.COM if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) || 261810743SDavid.Hollister@Sun.COM (flags & DCMD_LOOPFIRST)) { 261910743SDavid.Hollister@Sun.COM if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST)) 262010743SDavid.Hollister@Sun.COM mdb_printf("\n"); 262110743SDavid.Hollister@Sun.COM mdb_printf("%16s %9s %4s B C WorkFlags wserno DbgMsk %16s\n", 262210743SDavid.Hollister@Sun.COM "Address", "State", "Inst", "DIP"); 262310743SDavid.Hollister@Sun.COM mdb_printf("=================================" 262410743SDavid.Hollister@Sun.COM "============================================\n"); 262510743SDavid.Hollister@Sun.COM } 262610743SDavid.Hollister@Sun.COM 262710743SDavid.Hollister@Sun.COM switch (ss.state) { 262810743SDavid.Hollister@Sun.COM case STATE_NIL: 262910743SDavid.Hollister@Sun.COM state_str = "Invalid"; 263010743SDavid.Hollister@Sun.COM break; 263110743SDavid.Hollister@Sun.COM case STATE_PROBING: 263210743SDavid.Hollister@Sun.COM state_str = "Probing"; 263310743SDavid.Hollister@Sun.COM break; 263410743SDavid.Hollister@Sun.COM case STATE_RUNNING: 263510743SDavid.Hollister@Sun.COM state_str = "Running"; 263610743SDavid.Hollister@Sun.COM break; 263710743SDavid.Hollister@Sun.COM case STATE_UNPROBING: 263810743SDavid.Hollister@Sun.COM state_str = "Unprobing"; 263910743SDavid.Hollister@Sun.COM break; 264010743SDavid.Hollister@Sun.COM case STATE_DEAD: 264110743SDavid.Hollister@Sun.COM state_str = "Dead"; 264210743SDavid.Hollister@Sun.COM break; 264311692SJesse.Butler@Sun.COM case STATE_IN_RESET: 264411692SJesse.Butler@Sun.COM state_str = "In Reset"; 264511692SJesse.Butler@Sun.COM break; 264610743SDavid.Hollister@Sun.COM } 264710743SDavid.Hollister@Sun.COM 264810743SDavid.Hollister@Sun.COM mdb_printf("%16p %9s %4d %1d %1d 0x%08x 0x%04x 0x%04x %16p\n", addr, 264910743SDavid.Hollister@Sun.COM state_str, dip.devi_instance, ss.blocked, ss.configuring, 265010743SDavid.Hollister@Sun.COM ss.work_flags, ss.wserno, ss.debug_mask, ss.dip); 265110743SDavid.Hollister@Sun.COM mdb_printf("\n"); 265210743SDavid.Hollister@Sun.COM 265310743SDavid.Hollister@Sun.COM mdb_inc_indent(4); 265410743SDavid.Hollister@Sun.COM display_matching_work(ss, index, snum, tag_type); 265510743SDavid.Hollister@Sun.COM mdb_dec_indent(4); 265610743SDavid.Hollister@Sun.COM mdb_printf("\n"); 265710743SDavid.Hollister@Sun.COM 265810743SDavid.Hollister@Sun.COM return (DCMD_OK); 265910743SDavid.Hollister@Sun.COM } 266010743SDavid.Hollister@Sun.COM 266111694SDavid.Hollister@Sun.COM #ifndef _KMDB 266211694SDavid.Hollister@Sun.COM static int 266311694SDavid.Hollister@Sun.COM pmcs_dump_fwlog(struct pmcs_hw *ss, int instance, const char *ofile) 266411694SDavid.Hollister@Sun.COM { 266511694SDavid.Hollister@Sun.COM uint8_t *fwlogp; 266611694SDavid.Hollister@Sun.COM int ofilefd = -1; 266711694SDavid.Hollister@Sun.COM char ofilename[MAXPATHLEN]; 266811694SDavid.Hollister@Sun.COM int rval = DCMD_OK; 266911694SDavid.Hollister@Sun.COM 267011694SDavid.Hollister@Sun.COM if (ss->fwlogp == NULL) { 267111694SDavid.Hollister@Sun.COM mdb_warn("Firmware event log disabled for instance %d", 267211694SDavid.Hollister@Sun.COM instance); 267311694SDavid.Hollister@Sun.COM return (DCMD_OK); 267411694SDavid.Hollister@Sun.COM } 267511694SDavid.Hollister@Sun.COM 267611694SDavid.Hollister@Sun.COM if (snprintf(ofilename, MAXPATHLEN, "%s%d", ofile, instance) > 267711694SDavid.Hollister@Sun.COM MAXPATHLEN) { 267811694SDavid.Hollister@Sun.COM mdb_warn("Output filename is too long for instance %d", 267911694SDavid.Hollister@Sun.COM instance); 268011694SDavid.Hollister@Sun.COM return (DCMD_ERR); 268111694SDavid.Hollister@Sun.COM } 268211694SDavid.Hollister@Sun.COM 268311694SDavid.Hollister@Sun.COM fwlogp = mdb_alloc(PMCS_FWLOG_SIZE, UM_SLEEP); 268411694SDavid.Hollister@Sun.COM 268511694SDavid.Hollister@Sun.COM if (MDB_RD(fwlogp, PMCS_FWLOG_SIZE, ss->fwlogp) == -1) { 268611694SDavid.Hollister@Sun.COM NOREAD(fwlogp, ss->fwlogp); 268711694SDavid.Hollister@Sun.COM rval = DCMD_ERR; 268811694SDavid.Hollister@Sun.COM goto cleanup; 268911694SDavid.Hollister@Sun.COM } 269011694SDavid.Hollister@Sun.COM 269111694SDavid.Hollister@Sun.COM ofilefd = open(ofilename, O_WRONLY | O_CREAT, 269211694SDavid.Hollister@Sun.COM S_IRUSR | S_IRGRP | S_IROTH); 269311694SDavid.Hollister@Sun.COM if (ofilefd < 0) { 269411694SDavid.Hollister@Sun.COM mdb_warn("Unable to open '%s' to dump instance %d event log", 269511694SDavid.Hollister@Sun.COM ofilename, instance); 269611694SDavid.Hollister@Sun.COM rval = DCMD_ERR; 269711694SDavid.Hollister@Sun.COM goto cleanup; 269811694SDavid.Hollister@Sun.COM } 269911694SDavid.Hollister@Sun.COM 270011694SDavid.Hollister@Sun.COM if (write(ofilefd, fwlogp, PMCS_FWLOG_SIZE) != PMCS_FWLOG_SIZE) { 270111694SDavid.Hollister@Sun.COM mdb_warn("Failed to write %d bytes to output file: instance %d", 270211694SDavid.Hollister@Sun.COM PMCS_FWLOG_SIZE, instance); 270311694SDavid.Hollister@Sun.COM rval = DCMD_ERR; 270411694SDavid.Hollister@Sun.COM goto cleanup; 270511694SDavid.Hollister@Sun.COM } 270611694SDavid.Hollister@Sun.COM 270711694SDavid.Hollister@Sun.COM mdb_printf("Event log for instance %d written to %s\n", instance, 270811694SDavid.Hollister@Sun.COM ofilename); 270911694SDavid.Hollister@Sun.COM 271011694SDavid.Hollister@Sun.COM cleanup: 271111694SDavid.Hollister@Sun.COM if (ofilefd >= 0) { 271211694SDavid.Hollister@Sun.COM close(ofilefd); 271311694SDavid.Hollister@Sun.COM } 271411694SDavid.Hollister@Sun.COM mdb_free(fwlogp, PMCS_FWLOG_SIZE); 271511694SDavid.Hollister@Sun.COM return (rval); 271611694SDavid.Hollister@Sun.COM } 271711694SDavid.Hollister@Sun.COM 271811694SDavid.Hollister@Sun.COM static int 271911694SDavid.Hollister@Sun.COM pmcs_fwlog(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 272011694SDavid.Hollister@Sun.COM { 272111694SDavid.Hollister@Sun.COM void *pmcs_state; 272211694SDavid.Hollister@Sun.COM const char *ofile = NULL; 272311694SDavid.Hollister@Sun.COM struct pmcs_hw ss; 272411694SDavid.Hollister@Sun.COM struct dev_info dip; 272511694SDavid.Hollister@Sun.COM 272611694SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 'o', MDB_OPT_STR, &ofile, NULL) != argc) { 272711694SDavid.Hollister@Sun.COM return (DCMD_USAGE); 272811694SDavid.Hollister@Sun.COM } 272911694SDavid.Hollister@Sun.COM 273011694SDavid.Hollister@Sun.COM if (ofile == NULL) { 273111694SDavid.Hollister@Sun.COM mdb_printf("No output file specified\n"); 273211694SDavid.Hollister@Sun.COM return (DCMD_USAGE); 273311694SDavid.Hollister@Sun.COM } 273411694SDavid.Hollister@Sun.COM 273511694SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 273611694SDavid.Hollister@Sun.COM pmcs_state = NULL; 273711694SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 273811694SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 273911694SDavid.Hollister@Sun.COM return (DCMD_ERR); 274011694SDavid.Hollister@Sun.COM } 274111694SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_fwlog", argc, 274211694SDavid.Hollister@Sun.COM argv, (uintptr_t)pmcs_state) == -1) { 274311694SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed for pmcs_log"); 274411694SDavid.Hollister@Sun.COM return (DCMD_ERR); 274511694SDavid.Hollister@Sun.COM } 274611694SDavid.Hollister@Sun.COM return (DCMD_OK); 274711694SDavid.Hollister@Sun.COM } 274811694SDavid.Hollister@Sun.COM 274911694SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 275011694SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 275111694SDavid.Hollister@Sun.COM return (DCMD_ERR); 275211694SDavid.Hollister@Sun.COM } 275311694SDavid.Hollister@Sun.COM 275411694SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 275511694SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 275611694SDavid.Hollister@Sun.COM return (DCMD_ERR); 275711694SDavid.Hollister@Sun.COM } 275811694SDavid.Hollister@Sun.COM 275911694SDavid.Hollister@Sun.COM return (pmcs_dump_fwlog(&ss, dip.devi_instance, ofile)); 276011694SDavid.Hollister@Sun.COM } 276111694SDavid.Hollister@Sun.COM #endif /* _KMDB */ 276211694SDavid.Hollister@Sun.COM 276310696SDavid.Hollister@Sun.COM static int 276411048SDavid.Hollister@Sun.COM pmcs_log(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 276511048SDavid.Hollister@Sun.COM { 276611048SDavid.Hollister@Sun.COM void *pmcs_state; 276711048SDavid.Hollister@Sun.COM struct pmcs_hw ss; 276811048SDavid.Hollister@Sun.COM struct dev_info dip; 276911048SDavid.Hollister@Sun.COM const char *match_phy_path = NULL; 277011347SRamana.Srikanth@Sun.COM uint64_t match_sas_address = 0, tail_lines = 0; 2771*12120SDavid.Hollister@Sun.COM uint_t verbose = 0; 277211048SDavid.Hollister@Sun.COM 277311048SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 277411048SDavid.Hollister@Sun.COM pmcs_state = NULL; 277511048SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 277611048SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 277711048SDavid.Hollister@Sun.COM return (DCMD_ERR); 277811048SDavid.Hollister@Sun.COM } 277911048SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_log", argc, 278011048SDavid.Hollister@Sun.COM argv, (uintptr_t)pmcs_state) == -1) { 278111048SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed for pmcs_log"); 278211048SDavid.Hollister@Sun.COM return (DCMD_ERR); 278311048SDavid.Hollister@Sun.COM } 278411048SDavid.Hollister@Sun.COM return (DCMD_OK); 278511048SDavid.Hollister@Sun.COM } 278611048SDavid.Hollister@Sun.COM 278711048SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 278811347SRamana.Srikanth@Sun.COM 'l', MDB_OPT_UINT64, &tail_lines, 278911048SDavid.Hollister@Sun.COM 'p', MDB_OPT_STR, &match_phy_path, 279011048SDavid.Hollister@Sun.COM 's', MDB_OPT_UINT64, &match_sas_address, 2791*12120SDavid.Hollister@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose, 279211048SDavid.Hollister@Sun.COM NULL) != argc) { 279311048SDavid.Hollister@Sun.COM return (DCMD_USAGE); 279411048SDavid.Hollister@Sun.COM } 279511048SDavid.Hollister@Sun.COM 279611048SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 279711048SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 279811048SDavid.Hollister@Sun.COM return (DCMD_ERR); 279911048SDavid.Hollister@Sun.COM } 280011048SDavid.Hollister@Sun.COM 280111048SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 280211048SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 280311048SDavid.Hollister@Sun.COM return (DCMD_ERR); 280411048SDavid.Hollister@Sun.COM } 280511048SDavid.Hollister@Sun.COM 280611048SDavid.Hollister@Sun.COM if (!(flags & DCMD_LOOP)) { 280711048SDavid.Hollister@Sun.COM return (pmcs_dump_tracelog(B_TRUE, dip.devi_instance, 2808*12120SDavid.Hollister@Sun.COM tail_lines, match_phy_path, match_sas_address, verbose)); 280911048SDavid.Hollister@Sun.COM } else if (flags & DCMD_LOOPFIRST) { 281011347SRamana.Srikanth@Sun.COM return (pmcs_dump_tracelog(B_FALSE, 0, tail_lines, 2811*12120SDavid.Hollister@Sun.COM match_phy_path, match_sas_address, verbose)); 281211048SDavid.Hollister@Sun.COM } else { 281311048SDavid.Hollister@Sun.COM return (DCMD_OK); 281411048SDavid.Hollister@Sun.COM } 281511048SDavid.Hollister@Sun.COM } 281611048SDavid.Hollister@Sun.COM 281711048SDavid.Hollister@Sun.COM static int 281810696SDavid.Hollister@Sun.COM pmcs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 281910696SDavid.Hollister@Sun.COM { 282011048SDavid.Hollister@Sun.COM struct pmcs_hw ss; 282110696SDavid.Hollister@Sun.COM uint_t verbose = FALSE; 282210696SDavid.Hollister@Sun.COM uint_t phy_info = FALSE; 282310696SDavid.Hollister@Sun.COM uint_t hw_info = FALSE; 282410696SDavid.Hollister@Sun.COM uint_t target_info = FALSE; 282510696SDavid.Hollister@Sun.COM uint_t work_info = FALSE; 282610696SDavid.Hollister@Sun.COM uint_t ic_info = FALSE; 282710696SDavid.Hollister@Sun.COM uint_t iport_info = FALSE; 282810696SDavid.Hollister@Sun.COM uint_t waitqs_info = FALSE; 282910696SDavid.Hollister@Sun.COM uint_t ibq = FALSE; 283010696SDavid.Hollister@Sun.COM uint_t obq = FALSE; 283110696SDavid.Hollister@Sun.COM uint_t tgt_phy_count = FALSE; 283210743SDavid.Hollister@Sun.COM uint_t compq = FALSE; 283311048SDavid.Hollister@Sun.COM uint_t unconfigured = FALSE; 283411334SReed.Liu@Sun.COM uint_t damap_info = FALSE; 283511334SReed.Liu@Sun.COM uint_t dtc_info = FALSE; 283612060SDavid.Hollister@Sun.COM uint_t wserno = FALSE; 2837*12120SDavid.Hollister@Sun.COM uint_t fwlog = FALSE; 283810696SDavid.Hollister@Sun.COM int rv = DCMD_OK; 283910696SDavid.Hollister@Sun.COM void *pmcs_state; 284010696SDavid.Hollister@Sun.COM char *state_str; 284110696SDavid.Hollister@Sun.COM struct dev_info dip; 284211334SReed.Liu@Sun.COM per_iport_setting_t pis; 284310696SDavid.Hollister@Sun.COM 284410696SDavid.Hollister@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 284510696SDavid.Hollister@Sun.COM pmcs_state = NULL; 284610696SDavid.Hollister@Sun.COM if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) { 284710696SDavid.Hollister@Sun.COM mdb_warn("can't read pmcs_softc_state"); 284810696SDavid.Hollister@Sun.COM return (DCMD_ERR); 284910696SDavid.Hollister@Sun.COM } 285010696SDavid.Hollister@Sun.COM if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs", argc, argv, 285110696SDavid.Hollister@Sun.COM (uintptr_t)pmcs_state) == -1) { 285210696SDavid.Hollister@Sun.COM mdb_warn("mdb_pwalk_dcmd failed"); 285310696SDavid.Hollister@Sun.COM return (DCMD_ERR); 285410696SDavid.Hollister@Sun.COM } 285510696SDavid.Hollister@Sun.COM return (DCMD_OK); 285610696SDavid.Hollister@Sun.COM } 285710696SDavid.Hollister@Sun.COM 285810696SDavid.Hollister@Sun.COM if (mdb_getopts(argc, argv, 285910743SDavid.Hollister@Sun.COM 'c', MDB_OPT_SETBITS, TRUE, &compq, 286011334SReed.Liu@Sun.COM 'd', MDB_OPT_SETBITS, TRUE, &dtc_info, 2861*12120SDavid.Hollister@Sun.COM 'e', MDB_OPT_SETBITS, TRUE, &fwlog, 286210696SDavid.Hollister@Sun.COM 'h', MDB_OPT_SETBITS, TRUE, &hw_info, 286310696SDavid.Hollister@Sun.COM 'i', MDB_OPT_SETBITS, TRUE, &ic_info, 286410696SDavid.Hollister@Sun.COM 'I', MDB_OPT_SETBITS, TRUE, &iport_info, 286511334SReed.Liu@Sun.COM 'm', MDB_OPT_SETBITS, TRUE, &damap_info, 286610696SDavid.Hollister@Sun.COM 'p', MDB_OPT_SETBITS, TRUE, &phy_info, 286710696SDavid.Hollister@Sun.COM 'q', MDB_OPT_SETBITS, TRUE, &ibq, 286810696SDavid.Hollister@Sun.COM 'Q', MDB_OPT_SETBITS, TRUE, &obq, 286912060SDavid.Hollister@Sun.COM 's', MDB_OPT_SETBITS, TRUE, &wserno, 287010696SDavid.Hollister@Sun.COM 't', MDB_OPT_SETBITS, TRUE, &target_info, 287110696SDavid.Hollister@Sun.COM 'T', MDB_OPT_SETBITS, TRUE, &tgt_phy_count, 287211048SDavid.Hollister@Sun.COM 'u', MDB_OPT_SETBITS, TRUE, &unconfigured, 287310696SDavid.Hollister@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose, 287410696SDavid.Hollister@Sun.COM 'w', MDB_OPT_SETBITS, TRUE, &work_info, 287510696SDavid.Hollister@Sun.COM 'W', MDB_OPT_SETBITS, TRUE, &waitqs_info, 287610696SDavid.Hollister@Sun.COM NULL) != argc) 287710696SDavid.Hollister@Sun.COM return (DCMD_USAGE); 287810696SDavid.Hollister@Sun.COM 287911334SReed.Liu@Sun.COM /* 288011334SReed.Liu@Sun.COM * The 'd' and 'm' options implicitly enable the 'I' option 288111334SReed.Liu@Sun.COM */ 288211334SReed.Liu@Sun.COM pis.pis_damap_info = damap_info; 288311334SReed.Liu@Sun.COM pis.pis_dtc_info = dtc_info; 288411334SReed.Liu@Sun.COM if (damap_info || dtc_info) { 288511334SReed.Liu@Sun.COM iport_info = TRUE; 288611334SReed.Liu@Sun.COM } 288711334SReed.Liu@Sun.COM 288810696SDavid.Hollister@Sun.COM if (MDB_RD(&ss, sizeof (ss), addr) == -1) { 288910696SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 289010696SDavid.Hollister@Sun.COM return (DCMD_ERR); 289110696SDavid.Hollister@Sun.COM } 289210696SDavid.Hollister@Sun.COM 289310696SDavid.Hollister@Sun.COM if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) { 289410696SDavid.Hollister@Sun.COM NOREAD(pmcs_hw_t, addr); 289510696SDavid.Hollister@Sun.COM return (DCMD_ERR); 289610696SDavid.Hollister@Sun.COM } 289710696SDavid.Hollister@Sun.COM 289810696SDavid.Hollister@Sun.COM /* processing completed */ 289910696SDavid.Hollister@Sun.COM 290010696SDavid.Hollister@Sun.COM if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) || 290110696SDavid.Hollister@Sun.COM (flags & DCMD_LOOPFIRST) || phy_info || target_info || hw_info || 290211048SDavid.Hollister@Sun.COM work_info || waitqs_info || ibq || obq || tgt_phy_count || compq || 2903*12120SDavid.Hollister@Sun.COM unconfigured || fwlog) { 290410696SDavid.Hollister@Sun.COM if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST)) 290510696SDavid.Hollister@Sun.COM mdb_printf("\n"); 290610696SDavid.Hollister@Sun.COM mdb_printf("%16s %9s %4s B C WorkFlags wserno DbgMsk %16s\n", 290710696SDavid.Hollister@Sun.COM "Address", "State", "Inst", "DIP"); 290810696SDavid.Hollister@Sun.COM mdb_printf("=================================" 290910696SDavid.Hollister@Sun.COM "============================================\n"); 291010696SDavid.Hollister@Sun.COM } 291110696SDavid.Hollister@Sun.COM 291210696SDavid.Hollister@Sun.COM switch (ss.state) { 291310696SDavid.Hollister@Sun.COM case STATE_NIL: 291410696SDavid.Hollister@Sun.COM state_str = "Invalid"; 291510696SDavid.Hollister@Sun.COM break; 291610696SDavid.Hollister@Sun.COM case STATE_PROBING: 291710696SDavid.Hollister@Sun.COM state_str = "Probing"; 291810696SDavid.Hollister@Sun.COM break; 291910696SDavid.Hollister@Sun.COM case STATE_RUNNING: 292010696SDavid.Hollister@Sun.COM state_str = "Running"; 292110696SDavid.Hollister@Sun.COM break; 292210696SDavid.Hollister@Sun.COM case STATE_UNPROBING: 292310696SDavid.Hollister@Sun.COM state_str = "Unprobing"; 292410696SDavid.Hollister@Sun.COM break; 292510696SDavid.Hollister@Sun.COM case STATE_DEAD: 292610696SDavid.Hollister@Sun.COM state_str = "Dead"; 292710696SDavid.Hollister@Sun.COM break; 292811692SJesse.Butler@Sun.COM case STATE_IN_RESET: 292911692SJesse.Butler@Sun.COM state_str = "In Reset"; 293011692SJesse.Butler@Sun.COM break; 293110696SDavid.Hollister@Sun.COM } 293210696SDavid.Hollister@Sun.COM 293310696SDavid.Hollister@Sun.COM mdb_printf("%16p %9s %4d %1d %1d 0x%08x 0x%04x 0x%04x %16p\n", addr, 293410696SDavid.Hollister@Sun.COM state_str, dip.devi_instance, ss.blocked, ss.configuring, 293510696SDavid.Hollister@Sun.COM ss.work_flags, ss.wserno, ss.debug_mask, ss.dip); 293610696SDavid.Hollister@Sun.COM mdb_printf("\n"); 293710696SDavid.Hollister@Sun.COM 293810696SDavid.Hollister@Sun.COM mdb_inc_indent(4); 293910696SDavid.Hollister@Sun.COM 294010696SDavid.Hollister@Sun.COM if (waitqs_info) 294110696SDavid.Hollister@Sun.COM display_waitqs(ss, verbose); 294210696SDavid.Hollister@Sun.COM 294310696SDavid.Hollister@Sun.COM if (hw_info) 294410696SDavid.Hollister@Sun.COM display_hwinfo(ss, verbose); 294510696SDavid.Hollister@Sun.COM 294610696SDavid.Hollister@Sun.COM if (phy_info || tgt_phy_count) 294710696SDavid.Hollister@Sun.COM display_phys(ss, verbose, NULL, 0, tgt_phy_count); 294810696SDavid.Hollister@Sun.COM 294910696SDavid.Hollister@Sun.COM if (target_info || tgt_phy_count) 295010696SDavid.Hollister@Sun.COM display_targets(ss, verbose, tgt_phy_count); 295110696SDavid.Hollister@Sun.COM 295212060SDavid.Hollister@Sun.COM if (work_info || wserno) 295312060SDavid.Hollister@Sun.COM display_work(ss, verbose, wserno); 295410696SDavid.Hollister@Sun.COM 295510696SDavid.Hollister@Sun.COM if (ic_info) 295610696SDavid.Hollister@Sun.COM display_ic(ss, verbose); 295710696SDavid.Hollister@Sun.COM 295810696SDavid.Hollister@Sun.COM if (ibq) 295910696SDavid.Hollister@Sun.COM display_inbound_queues(ss, verbose); 296010696SDavid.Hollister@Sun.COM 296110696SDavid.Hollister@Sun.COM if (obq) 296210696SDavid.Hollister@Sun.COM display_outbound_queues(ss, verbose); 296310696SDavid.Hollister@Sun.COM 296410696SDavid.Hollister@Sun.COM if (iport_info) 296511334SReed.Liu@Sun.COM display_iport(ss, addr, verbose, &pis); 296610696SDavid.Hollister@Sun.COM 296710743SDavid.Hollister@Sun.COM if (compq) 296810743SDavid.Hollister@Sun.COM display_completion_queue(ss); 296910743SDavid.Hollister@Sun.COM 297011048SDavid.Hollister@Sun.COM if (unconfigured) 297111048SDavid.Hollister@Sun.COM display_unconfigured_targets(addr); 297211048SDavid.Hollister@Sun.COM 2973*12120SDavid.Hollister@Sun.COM if (fwlog) 2974*12120SDavid.Hollister@Sun.COM display_event_log(ss); 2975*12120SDavid.Hollister@Sun.COM 297610696SDavid.Hollister@Sun.COM mdb_dec_indent(4); 297710696SDavid.Hollister@Sun.COM 297810696SDavid.Hollister@Sun.COM return (rv); 297910696SDavid.Hollister@Sun.COM } 298010696SDavid.Hollister@Sun.COM 298110696SDavid.Hollister@Sun.COM void 298210696SDavid.Hollister@Sun.COM pmcs_help() 298310696SDavid.Hollister@Sun.COM { 298410696SDavid.Hollister@Sun.COM mdb_printf("Prints summary information about each pmcs instance.\n" 298510743SDavid.Hollister@Sun.COM " -c: Dump the completion queue\n" 298611334SReed.Liu@Sun.COM " -d: Print per-iport information about device tree children\n" 2987*12120SDavid.Hollister@Sun.COM " -e: Display the in-memory firmware event log\n" 298810696SDavid.Hollister@Sun.COM " -h: Print more detailed hardware information\n" 298910696SDavid.Hollister@Sun.COM " -i: Print interrupt coalescing information\n" 299010696SDavid.Hollister@Sun.COM " -I: Print information about each iport\n" 299111334SReed.Liu@Sun.COM " -m: Print per-iport information about DAM/damap state\n" 299210696SDavid.Hollister@Sun.COM " -p: Print information about each attached PHY\n" 299310696SDavid.Hollister@Sun.COM " -q: Dump inbound queues\n" 299410696SDavid.Hollister@Sun.COM " -Q: Dump outbound queues\n" 299512060SDavid.Hollister@Sun.COM " -s: Dump all work structures sorted by serial number\n" 299611048SDavid.Hollister@Sun.COM " -t: Print information about each configured target\n" 299710696SDavid.Hollister@Sun.COM " -T: Print target and PHY count summary\n" 299811048SDavid.Hollister@Sun.COM " -u: Show SAS address of all unconfigured targets\n" 299910696SDavid.Hollister@Sun.COM " -w: Dump work structures\n" 300010696SDavid.Hollister@Sun.COM " -W: List pmcs cmds waiting on various queues\n" 300110696SDavid.Hollister@Sun.COM " -v: Add verbosity to the above options\n"); 300210696SDavid.Hollister@Sun.COM } 300310696SDavid.Hollister@Sun.COM 300410743SDavid.Hollister@Sun.COM void 300511048SDavid.Hollister@Sun.COM pmcs_log_help() 300611048SDavid.Hollister@Sun.COM { 300711048SDavid.Hollister@Sun.COM mdb_printf("Dump the pmcs log buffer, possibly with filtering.\n" 300811347SRamana.Srikanth@Sun.COM " -l TAIL_LINES: Dump the last TAIL_LINES messages\n" 300911048SDavid.Hollister@Sun.COM " -p PHY_PATH: Dump messages matching PHY_PATH\n" 301011048SDavid.Hollister@Sun.COM " -s SAS_ADDRESS: Dump messages matching SAS_ADDRESS\n\n" 301111048SDavid.Hollister@Sun.COM "Where: PHY_PATH can be found with ::pmcs -p (e.g. pp04.18.18.01)\n" 301211048SDavid.Hollister@Sun.COM " SAS_ADDRESS can be found with ::pmcs -t " 301311048SDavid.Hollister@Sun.COM "(e.g. 5000c5000358c221)\n"); 301411048SDavid.Hollister@Sun.COM } 301511048SDavid.Hollister@Sun.COM void 301610743SDavid.Hollister@Sun.COM pmcs_tag_help() 301710743SDavid.Hollister@Sun.COM { 301810743SDavid.Hollister@Sun.COM mdb_printf("Print all work structures by matching the tag.\n" 301910743SDavid.Hollister@Sun.COM " -i index: Match tag index (0x000 - 0xfff)\n" 302010743SDavid.Hollister@Sun.COM " -s serialnumber: Match serial number (0x0000 - 0xffff)\n" 302110743SDavid.Hollister@Sun.COM " -t tagtype: Match tag type [NONE(1), CBACK(2), " 302210743SDavid.Hollister@Sun.COM "WAIT(3)]\n"); 302310743SDavid.Hollister@Sun.COM } 302410743SDavid.Hollister@Sun.COM 302510696SDavid.Hollister@Sun.COM static const mdb_dcmd_t dcmds[] = { 3026*12120SDavid.Hollister@Sun.COM { "pmcs", "?[-cdehiImpQqtTuwWv]", "print pmcs information", 302710696SDavid.Hollister@Sun.COM pmcs_dcmd, pmcs_help 302810696SDavid.Hollister@Sun.COM }, 302911048SDavid.Hollister@Sun.COM { "pmcs_log", 3030*12120SDavid.Hollister@Sun.COM "?[-v] [-p PHY_PATH | -s SAS_ADDRESS | -l TAIL_LINES]", 303111048SDavid.Hollister@Sun.COM "dump pmcs log file", pmcs_log, pmcs_log_help 303211048SDavid.Hollister@Sun.COM }, 303310743SDavid.Hollister@Sun.COM { "pmcs_tag", "?[-t tagtype|-s serialnum|-i index]", 303410743SDavid.Hollister@Sun.COM "Find work structures by tag type, serial number or index", 303510743SDavid.Hollister@Sun.COM pmcs_tag, pmcs_tag_help 303610743SDavid.Hollister@Sun.COM }, 303711694SDavid.Hollister@Sun.COM #ifndef _KMDB 303811694SDavid.Hollister@Sun.COM { "pmcs_fwlog", 303911694SDavid.Hollister@Sun.COM "?-o output_file", 304011694SDavid.Hollister@Sun.COM "dump pmcs firmware event log to output_file", pmcs_fwlog, NULL 304111694SDavid.Hollister@Sun.COM }, 304211694SDavid.Hollister@Sun.COM #endif /* _KMDB */ 304310696SDavid.Hollister@Sun.COM { NULL } 304410696SDavid.Hollister@Sun.COM }; 304510696SDavid.Hollister@Sun.COM 304610696SDavid.Hollister@Sun.COM static const mdb_walker_t walkers[] = { 304710696SDavid.Hollister@Sun.COM { "pmcs_targets", "walk target structures", 304810696SDavid.Hollister@Sun.COM targets_walk_i, targets_walk_s, targets_walk_f }, 304910696SDavid.Hollister@Sun.COM { "pmcs_phys", "walk PHY structures", 305010696SDavid.Hollister@Sun.COM phy_walk_i, phy_walk_s, phy_walk_f }, 305110696SDavid.Hollister@Sun.COM { NULL } 305210696SDavid.Hollister@Sun.COM }; 305310696SDavid.Hollister@Sun.COM 305410696SDavid.Hollister@Sun.COM static const mdb_modinfo_t modinfo = { 305510696SDavid.Hollister@Sun.COM MDB_API_VERSION, dcmds, walkers 305610696SDavid.Hollister@Sun.COM }; 305710696SDavid.Hollister@Sun.COM 305810696SDavid.Hollister@Sun.COM const mdb_modinfo_t * 305910696SDavid.Hollister@Sun.COM _mdb_init(void) 306010696SDavid.Hollister@Sun.COM { 306110696SDavid.Hollister@Sun.COM return (&modinfo); 306210696SDavid.Hollister@Sun.COM } 3063