4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * CDDL HEADER START
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * The contents of this file are subject to the terms of the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Common Development and Distribution License (the "License").
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * You may not use this file except in compliance with the License.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * See the License for the specific language governing permissions
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * and limitations under the License.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * When distributing Covered Code, include this CDDL HEADER in each
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * If applicable, add the following below this CDDL HEADER, with the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * fields enclosed by brackets "[]" replaced with your own identifying
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * information: Portions Copyright [yyyy] [name of copyright owner]
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * CDDL HEADER END
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
33f5ff17089e3a43e6e730bf80384c233123dbd9Milan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister#endif /* _KMDB */
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed * We need use this to pass the settings when display_iport
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed uint_t pis_dtc_info; /* -d: device tree children: dev_info/path_info */
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister * This structure is used for sorting work structures by the wserno
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed#define NOREAD(a, b) mdb_warn("could not read " #a " at 0x%p", b)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic uint32_t sas_phys, sata_phys, exp_phys, num_expanders, empty_phys;
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdhstatic void display_one_work(pmcwork_t *wp, int verbose, int idx);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollisterpmcs_fwtime_to_systime(struct pmcs_hw ss, uint32_t fw_hi, uint32_t fw_lo,
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister * If fwtime < ss.fw_timestamp, then we need to adjust the clock
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister * time backwards from ss.sys_timestamp. Otherwise, the adjustment
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister * goes forward in time
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister stime->tv_nsec = stime->tv_nsec + NSECS_PER_SEC - nsecs;
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister if (stime->tv_nsec + nsecs > NSECS_PER_SEC) {
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister stime->tv_nsec = (stime->tv_nsec + nsecs) % NSECS_PER_SEC;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*ARGSUSED*/
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_readvar(&msec_per_tick, "msec_per_tick") == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*ARGSUSED*/
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhpmcs_iport_phy_walk_cb(uintptr_t addr, const void *wdata, void *priv)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh sizeof (struct pmcs_phy)) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed mdb_ctf_id_t istm_ctfid; /* impl_scsi_tgtmap_t ctf_id */
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed ulong_t tmd_offset = 0; /* tgtmap_dam offset to impl_scsi_tgtmap_t */
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)pdip) !=
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed sizeof (struct dev_info)) {
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed (uintptr_t)dip.devi_driver_data) != sizeof (scsi_hba_tran_t)) {
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed if (mdb_ctf_lookup_by_name("impl_scsi_tgtmap_t", &istm_ctfid) != 0) {
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed if (mdb_ctf_offsetof(istm_ctfid, "tgtmap_dam", &tmd_offset) != 0) {
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed (uintptr_t)(sizeof (dam0) + tmd_offset + (char *)sht.tran_tgtmap));
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed rval = mdb_call_dcmd("damap", dam0, DCMD_ADDRSPEC, 0, NULL);
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed rval = mdb_call_dcmd("damap", dam1, DCMD_ADDRSPEC, 0, NULL);
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed/* ARGSUSED */
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reeddisplay_iport_di_cb(uintptr_t addr, const void *wdata, void *priv)
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)addr) !=
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed sizeof (struct dev_info)) {
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed/* ARGSUSED */
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reeddisplay_iport_pi_cb(uintptr_t addr, const void *wdata, void *priv)
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed if (mdb_vread(&mpi, sizeof (struct mdi_pathinfo), (uintptr_t)addr) !=
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed sizeof (struct mdi_pathinfo)) {
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed mdb_printf(" %3d: @%-21s %p::print struct mdi_pathinfo\n",
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed if (mdb_vread(&dip, sizeof (struct dev_info), (uintptr_t)pdip) !=
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed sizeof (struct dev_info)) {
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed * First, we dump the iport's children dev_info node information.
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed * use existing walker: devinfo_siblings
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed rval = mdb_pwalk("devinfo_siblings", display_iport_di_cb,
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed * Then we try to dump the iport's path_info node information.
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed * use existing walker: mdipi_phci_list
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed (uintptr_t)dip.devi_mdi_xhci) != sizeof (struct mdi_phci)) {
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed mdb_printf("\tdevi_mdi_xhci is NULL, no path_info\n\n");
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed mdb_printf("\tph_path_head is NULL, no path_info\n\n");
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed rval = mdb_pwalk("mdipi_phci_list", display_iport_pi_cb,
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reedstatic void
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reeddisplay_iport_more(dev_info_t *dip, per_iport_setting_t *pis)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*ARGSUSED*/
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhpmcs_iport_walk_cb(uintptr_t addr, const void *wdata, void *priv)
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed per_iport_setting_t *pis = (per_iport_setting_t *)priv;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_vread(&iport, sizeof (struct pmcs_iport), addr) !=
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh sizeof (struct pmcs_iport)) {
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana } else if (iport.portid == PMCS_IPORT_INVALID_PORT_ID) {
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana mdb_snprintf(portid, sizeof (portid), "%s", "N/A");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_snprintf(portid, sizeof (portid), "%d", iport.portid);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Standard iport unit address */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("UA %-16s %16s %8s %8s %16s", "Iport", "UA State",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("%2s %16p %16s %8s %8d %16p\n", unit_address, addr,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Temporary iport unit address */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("%-32s %16s %20s %8s %8s %16s", "UA", "Iport",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("%32s %16p %20s %8s %8d %16p\n", unit_address, addr,
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed * See if we need to show more information based on 'd' or 'm' options
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*ARGSUSED*/
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reeddisplay_iport(struct pmcs_hw m, uintptr_t addr, int verbose,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh list_addr = (uintptr_t)(addr + offsetof(struct pmcs_hw, iports));
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed if (mdb_pwalk("list", pmcs_iport_walk_cb, pis, list_addr) == -1) {
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh/* ARGSUSED */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdhpmcs_utarget_walk_cb(uintptr_t addr, const void *wdata, void *priv)
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh if (mdb_vread(&phy, sizeof (pmcs_phy_t), (uintptr_t)addr) == -1) {
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh mdb_warn("pmcs_utarget_walk_cb: Failed to read PHY at %p",
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (0);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdhstatic void
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh if (mdb_pwalk("pmcs_phys", pmcs_utarget_walk_cb, NULL, addr) == -1) {
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdhstatic void
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh if (mdb_vread(&work, sizeof (pmcwork_t), (uintptr_t)ccb.pwrk)
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh != sizeof (pmcwork_t)) {
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh * Only print the work structure if it's still active. If
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh * it's not, it's been completed since we started looking at
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister uint32_t total_size = PMCS_FWLOG_SIZE, log_size, index, *swapp, sidx;
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister mdb_printf("There is no firmware event log.\n");
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister if (mdb_vread(&fwhdr, sizeof (pmcs_fw_event_hdr_t),
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister (uintptr_t)fwlogp) != sizeof (pmcs_fw_event_hdr_t)) {
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister mdb_warn("Unable to read firmware event log header\n");
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister * Firmware event log is little-endian
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister for (sidx = 0; sidx < (sizeof (pmcs_fw_event_hdr_t) /
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister if (fwhdr.fw_el_signature == PMCS_FWLOG_AAP1_SIG) {
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister } else if (fwhdr.fw_el_signature == PMCS_FWLOG_IOP_SIG) {
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister mdb_warn("Invalid firmware event log signature\n");
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister mdb_printf("Oldest entry: %d\n", fwhdr.fw_el_oldest_idx);
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister mdb_printf("Latest entry: %d\n", fwhdr.fw_el_latest_idx);
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister entry = mdb_alloc(fwhdr.fw_el_entry_size, UM_SLEEP);
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister fw_entryp = (pmcs_fw_event_entry_t *)((void *)entry);
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister mdb_printf("%8s %16s %32s %8s %3s %8s %8s %8s %8s",
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister "Index", "Timestamp", "Time", "Seq Num", "Sev", "Word 0",
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister while (log_size != 0) {
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister if (mdb_vread(entry, fwhdr.fw_el_entry_size,
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister (uintptr_t)fwlogp) != fwhdr.fw_el_entry_size) {
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister mdb_warn("Unable to read event log entry\n");
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister for (sidx = 0; sidx < (fwhdr.fw_el_entry_size /
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister if (fw_entryp->ts_upper || fw_entryp->ts_lower) {
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister pmcs_fwtime_to_systime(ss, fw_entryp->ts_upper,
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister mdb_printf("%8d %08x%08x [%Y.%09ld] %8d %3d "
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*ARGSUSED*/
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
2ac4abe882db38ef90020f7c5ca28586e3d57258David Hollister mdb_printf("ILA version: %08x\n", m.ila_ver);
2ac4abe882db38ef90020f7c5ca28586e3d57258David Hollister mdb_printf("Active f/w img: %c\n", (m.fw_active_img) ? 'A' : 'B');
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister mdb_printf("Open retry intvl: %d usecs\n", m.open_retry_interval);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (m.fwlog == 0) {
2ac4abe882db38ef90020f7c5ca28586e3d57258David Hollister mdb_printf("Firmware logfile: Not configured\n");
2ac4abe882db38ef90020f7c5ca28586e3d57258David Hollister mdb_printf("Firmware logfile: Configured\n");
2ac4abe882db38ef90020f7c5ca28586e3d57258David Hollister mdb_printf("AAP1 log file: %s\n", m.fwlogfile_aap1);
2ac4abe882db38ef90020f7c5ca28586e3d57258David Hollister mdb_printf("IOP logfile: %s\n", m.fwlogfile_iop);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhdisplay_targets(struct pmcs_hw m, int verbose, int totals_only)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh uint32_t sas_targets = 0, smp_targets = 0, sata_targets = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh targets = mdb_alloc(sizeof (targets) * max_dev, UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (MDB_RD(targets, sizeof (targets) * max_dev, m.targets) == -1) {
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana mdb_printf("VTGT %-16s %-16s %-5s %4s %6s %s", "SAS Address",
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana "PHY Address", "DType", "Actv", "OnChip", "DS");
b18a19c275d2531444fcd2f66664cbe3c6897f6aJesse Butler * It has to be new or assigned to be of interest.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "Configured targets:", (sas_targets + sata_targets + smp_targets),
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdhstatic char *
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh switch (state) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister mdb_printf("%08x %10s 0x%016p 0x%016p 0x%016p\n",
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister wp->last_htag, last_state, wp->last_phy, wp->last_xp,
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdhstatic void
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollisterdisplay_work(struct pmcs_hw m, int verbose, int wserno)
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister wserno_list_t *sernop, *sp, *newsp, *sphead = NULL;
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister wp = mdb_alloc(sizeof (pmcwork_t) * m.max_cmd, UM_SLEEP);
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister sernop = mdb_alloc(sizeof (wserno_list_t) * m.max_cmd, UM_SLEEP);
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister bzero(sernop, sizeof (wserno_list_t) * m.max_cmd);
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister * Read in all the work structures
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh for (idx = 0; idx < m.max_cmd; idx++, _wp += sizeof (pmcwork_t)) {
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister if (MDB_RD(wp + idx, sizeof (pmcwork_t), _wp) == -1) {
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister * Sort by serial number?
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister serno = PMCS_TAG_SERNO((wp + idx)->last_htag);
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister /* Start at the beginning of the list */
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister /* If this is the first entry, just add it */
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister /* Find out where in the list this goes */
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister /* This item goes before sp */
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister * If sp->next is NULL, this entry goes at the
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister * end of the list
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister * Now print the sorted list
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister mdb_printf(" Idx %8s %10s %20s %8s %8s O D ",
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister "HTag", "State", "Phy Path", "Target", "Timer");
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister mdb_printf("%8s %10s %18s %18s %18s\n", "LastHTAG",
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister "LastState", "LastPHY", "LastTgt", "LastArg");
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister * Now print the list, sorted by index
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister if (!verbose && ((wp + idx)->htag == PMCS_TAG_TYPE_FREE)) {
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister mdb_free(wp, sizeof (pmcwork_t) * m.max_cmd);
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister mdb_free(sernop, sizeof (wserno_list_t) * m.max_cmd);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdhprint_spcmd(pmcs_cmd_t *sp, void *kaddr, int printhdr, int verbose)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh kaddr, sp->cmd_pkt, sp->cmd_clist, sp->cmd_tag, sp->cmd_satltag);
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh * If we're printing verbose, dump the CDB as well.
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh sizeof (struct scsi_pkt)) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*ARGSUSED1*/
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh while (sp) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh while (sp) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh targets = mdb_alloc(sizeof (targets) * max_dev, UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (MDB_RD(targets, sizeof (targets) * max_dev, m.targets) == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh for (i = 0; i < max_dev; i++) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh while (sp) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh while (sp) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh while (sp) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic char *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("UNKNOWN");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("I/O");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("Other");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic char *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh switch (qnum) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("I/O");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("General");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("Events");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("UNKNOWN");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic char *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh switch (cat) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("NET");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("FC");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SAS");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SCSI");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("???");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("PHY STOP");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("PHY UP");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("SATA PHY UP");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("SATA SPINUP HOLD");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("PHY DOWN");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("BROADCAST CHANGE");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("BROADCAST SES");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("INBOUND CRC ERROR");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("HARD RESET");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("IDENTIFY FRAME TIMEOUT");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("BROADCAST EXPANDER");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("PHY START");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("INVALID DWORD");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("DISPARITY ERROR");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("CODE VIOLATION");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("LOSS OF DWORD SYNC");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("PHY RESET FAILED");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("PORT RECOVERY TIMEOUT");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("PORT RECOVERY");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("PORT RESET TIMEOUT");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("PORT RESET COMPLETE");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("BROADCAST ASYNC");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("I/T NEXUS LOSS");
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister return ("Unknown Event");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic char *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh switch (opcode) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("ECHO");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_INFO");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_VPD");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("PHY_START");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("PHY_STOP");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("INI_IO_START");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("INI_TM_START");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("INI_EXT_IO_START");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("DEVICE_HANDLE_ACCEPT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("TGT_IO_START");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("TGT_RESPONSE_START");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("INI_EDC_EXT_IO_START");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("INI_EDC_EXT_IO_START1");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("TGT_EDC_IO_START");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SSP_ABORT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("DEREGISTER_DEVICE_HANDLE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_DEVICE_HANDLE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SMP_REQUEST");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SMP_RESPONSE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SMP_ABORT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("ASSISTED_DISCOVERY");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("REGISTER_DEVICE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SATA_HOST_IO_START");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SATA_ABORT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("LOCAL_PHY_CONTROL");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_DEVICE_INFO");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("TWI");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("FW_FLASH_UPDATE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SET_VPD");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GPIO");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SAS_DIAG_MODE_START_END");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SAS_DIAG_EXECUTE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SAS_HW_EVENT_ACK");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_TIME_STAMP");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("PORT_CONTROL");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_NVMD_DATA");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SET_NVMD_DATA");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SET_DEVICE_STATE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_DEVICE_STATE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("UNKNOWN");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic char *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh switch (opcode) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("ECHO");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_INFO");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_VPD");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SAS_HW_EVENT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SSP_COMPLETION");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SMP_COMPLETION");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("LOCAL_PHY_CONTROL");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SAS_ASSISTED_DISCOVERY_SENT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SATA_ASSISTED_DISCOVERY_SENT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("DEVICE_REGISTRATION");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("DEREGISTER_DEVICE_HANDLE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_DEVICE_HANDLE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SATA_COMPLETION");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SATA_EVENT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SSP_EVENT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("DEVICE_HANDLE_ARRIVED");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SSP_REQUEST_RECEIVED");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("DEVICE_INFO");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("FW_FLASH_UPDATE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SET_VPD");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GPIO");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GPIO_EVENT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GENERAL_EVENT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("TWI");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SSP_ABORT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SATA_ABORT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SAS_DIAG_MODE_START_END");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SAS_DIAG_EXECUTE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_TIME_STAMP");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SAS_HW_EVENT_ACK_ACK");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("PORT_CONTROL");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SKIP_ENTRIES");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SMP_ABORT");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_NVMD_DATA");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SET_NVMD_DATA");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("DEVICE_HANDLE_REMOVED");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SET_DEVICE_STATE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("GET_DEVICE_STATE");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("SET_DEVICE_INFO");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return ("UNKNOWN");
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollisterget_devid_from_ob_iomb(struct pmcs_hw ss, uint32_t *qentryp, uint16_t opcode)
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * These are obtained via the HTAG which is in word 1
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister wp = mdb_alloc(sizeof (pmcwork_t), UM_SLEEP);
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister _wp = (uintptr_t)ss.work + (sizeof (pmcwork_t) * index);
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister if (MDB_RD(wp, sizeof (pmcwork_t), _wp) == -1) {
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister phy = mdb_alloc(sizeof (pmcs_phy_t), UM_SLEEP);
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * If we have a PHY, read it in and get it's handle
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister if (MDB_RD(phy, sizeof (*phy), _phy) == -1) {
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * The device ID is in the outbound IOMB at word 1
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister devid = LE_32(*(qentryp + 1)) & PMCS_DEVICE_ID_MASK;
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * The device ID is in the outbound IOMB at word 2
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister devid = LE_32(*(qentryp + 2)) & PMCS_DEVICE_ID_MASK;
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * In this (very rare - never seen it) state, the device ID
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * comes from the HTAG in the inbound IOMB, which would be word
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * 3 in the outbound IOMB
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * The device ID is in the outbound IOMB at word 3
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister devid = LE_32(*(qentryp + 3)) & PMCS_DEVICE_ID_MASK;
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * Device ID is in the outbound IOMB at word 4
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister devid = LE_32(*(qentryp + 4)) & PMCS_DEVICE_ID_MASK;
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollisteriomb_is_dev_hdl_specific(uint32_t word0, boolean_t inbound)
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister uint16_t opcode = word0 & PMCS_IOMB_OPCODE_MASK;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollisterdump_one_qentry_outbound(struct pmcs_hw ss, uint32_t *qentryp, int idx,
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * Check to see if we're filtering on a device ID
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister if (devid_filter != PMCS_INVALID_DEVICE_ID) {
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister if (!iomb_is_dev_hdl_specific(word0, B_FALSE)) {
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * Go find the device id. It might be in the outbound
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * IOMB or we may have to go find the work structure and
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * get it from there.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh iomb_cat((word0 & PMCS_IOMB_CAT_MASK) >> PMCS_IOMB_CAT_SHIFT));
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister if ((word0 & PMCS_IOMB_OPCODE_MASK) == PMCOUT_SAS_HW_EVENT) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh for (qeidx = 1; qeidx < (PMCS_QENTRY_SIZE / 4); qeidx++) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollisterdisplay_outbound_queues(struct pmcs_hw ss, uint64_t devid_filter,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh uint32_t *qentryp = mdb_alloc(PMCS_QENTRY_SIZE, UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("Outbound Queue #%d (Queue Type = %s)\n", qidx,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Chip is the producer, so read the actual producer index
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * and not the driver's version
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister dump_one_qentry_outbound(ss, qentryp, last_consumed,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollisterdump_one_qentry_inbound(uint32_t *qentryp, int idx, uint64_t devid_filter)
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * Check to see if we're filtering on a device ID
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister if (devid_filter != PMCS_INVALID_DEVICE_ID) {
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister if (iomb_is_dev_hdl_specific(word0, B_TRUE)) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh iomb_cat((word0 & PMCS_IOMB_CAT_MASK) >> PMCS_IOMB_CAT_SHIFT));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh for (qeidx = 2; qeidx < (PMCS_QENTRY_SIZE / 4); qeidx++) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollisterdisplay_inbound_queues(struct pmcs_hw ss, uint64_t devid_filter, uint_t verbose)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh uint32_t *qentryp = mdb_alloc(PMCS_QENTRY_SIZE, UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("Inbound Queue #%d (Queue Type = %s)\n", qidx,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (iqci == 0) {
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister dump_one_qentry_inbound(qentryp, last_consumed,
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister dump_one_qentry_inbound(qentryp, idx, devid_filter);
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister * phy is our copy of the PHY structure. phyp is the pointer to the actual
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister * kernel PHY data structure
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollisterdisplay_phy(struct pmcs_phy phy, struct pmcs_phy *phyp, int verbose,
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister mdb_printf("%-4s %-4s %-4s %-4s %-4s %3d %3c/%1c %3d "
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister "%1d 0x%p ", cfgd, apend, asent, changed, dead,
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister phy.enum_attempts, phy.reenumerate, phy.phy_lock);
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister * In verbose mode, on the next line print the drill down
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister * info to see either the DISCOVER response or the REPORT
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister * GENERAL response depending on the PHY's dtype
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister "print smp_report_general_resp_t\n",
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister "print smp_discover_resp_t\n",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhdisplay_phys(struct pmcs_hw ss, int verbose, struct pmcs_phy *parent, int level,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (level == 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (level == 0) {
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister mdb_printf("Cfgd AbtP AbtS Chgd Dead Ref RtA/M Enm R "
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister display_phy(phy, pphy, verbose, totals_only);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (level == 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "Occupied PHYs:",
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * filter is used to indicate whether we are filtering log messages based
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * on "instance". The other filtering (based on options) depends on the
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * values that are passed in for "sas_addr" and "phy_path".
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * MAX_INST_STRLEN is the largest string size from which we will attempt
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * to convert to an instance number. The string will be formed up as
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * "0t<inst>\0" so that mdb_strtoull can parse it properly.
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramanapmcs_dump_tracelog(boolean_t filter, int instance, uint64_t tail_lines,
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister const char *phy_path, uint64_t sas_address, uint64_t verbose)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Get the address of the first element */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Get the total number */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_readvar(&tbuf_num_elems, "pmcs_tbuf_num_elems") == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Get the current index */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Indicator as to whether the buffer has wrapped */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * On little-endian systems, the SAS address passed in will be
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * byte swapped. Take care of that here.
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana /* Ensure the tail number isn't greater than the size of the log */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Figure out where we start and stop */
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana /* Do we need to wrap backwards? */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Dump the buffer contents */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh while (elems_to_print != 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (MDB_RD(&tbuf, sizeof (pmcs_tbuf_t), (tbuf_addr + idx))
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * Check for filtering on HBA instance
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Skip the driver name */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Get the instance */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * This message is not being filtered by HBA instance.
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * Now check to see if we're filtering based on
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * PHY path or SAS address.
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * Filtering is an "OR" operation. So, if any of the
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * criteria matches, this message will be printed.
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh 8) == 0) {
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister * If the -v flag was given, print the firmware
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister * timestamp along with the clock time
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Address provided belongs to HBA softstate. Get the targets pointer
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * to begin the walk.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_vread(&ss, sizeof (pmcs_hw_t), wsp->walk_addr) !=
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh sizeof (pmcs_hw_t)) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh targets = mdb_alloc(sizeof (targets) * ss.max_dev, UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (MDB_RD(targets, sizeof (targets) * ss.max_dev, ss.targets) == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh wsp->walk_data = mdb_alloc(sizeof (pmcs_xscsi_t), UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_warn("Failed to read target at %p", (void *)wsp->walk_addr);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh } while ((wsp->walk_addr == NULL) && (target_idx < ss.max_dev));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * First, if this is a root PHY, there are no more siblings
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Otherwise, next sibling is the parent's sibling
e71c81d1003489d75b970c7d0a3a33772608b3abJesse Butler * If this PHY's sibling is NULL and it's a root phy,
e71c81d1003489d75b970c7d0a3a33772608b3abJesse Butler * we're done.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Address provided belongs to HBA softstate. Get the targets pointer
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * to begin the walk.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_vread(&ss, sizeof (pmcs_hw_t), wsp->walk_addr) !=
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh sizeof (pmcs_hw_t)) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh wsp->walk_data = mdb_alloc(sizeof (pmcs_phy_t), UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * We reached the end of this sibling list. Trudge back up
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * to the parent and find the next sibling after the expander
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * we just finished traversing, if there is one.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdhstatic void
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdhdisplay_matching_work(struct pmcs_hw ss, uintmax_t index, uintmax_t snum,
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh for (idx = 0; idx < ss.max_cmd; idx++, _wp += sizeof (pmcwork_t)) {
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdhpmcs_tag(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) {
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_tag", argc,
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh * Count the number of supplied options and make sure they are
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh * within appropriate ranges. If they're set to UINT_MAX, that means
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh * they were not supplied, in which case reset them to 0.
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh if (snum > (PMCS_TAG_SERNO_MASK >> PMCS_TAG_SERNO_SHIFT)) {
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh * Make sure 1 and only 1 option is specified
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh mdb_warn("Exactly one of -i, -s and -t must be specified\n");
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) {
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh /* processing completed */
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh mdb_printf("%16s %9s %4s B C WorkFlags wserno DbgMsk %16s\n",
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh "============================================\n");
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh mdb_printf("%16p %9s %4d %1d %1d 0x%08x 0x%04x 0x%04x %16p\n", addr,
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh state_str, dip.devi_instance, ss.blocked, ss.configuring,
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollisterpmcs_dump_fwlog(struct pmcs_hw *ss, int instance, const char *ofile)
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister mdb_warn("Firmware event log disabled for instance %d",
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister if (snprintf(ofilename, MAXPATHLEN, "%s%d", ofile, instance) >
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister mdb_warn("Output filename is too long for instance %d",
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister fwlogp = mdb_alloc(PMCS_FWLOG_SIZE, UM_SLEEP);
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister if (MDB_RD(fwlogp, PMCS_FWLOG_SIZE, ss->fwlogp) == -1) {
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister ofilefd = open(ofilename, O_WRONLY | O_CREAT,
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister mdb_warn("Unable to open '%s' to dump instance %d event log",
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister if (write(ofilefd, fwlogp, PMCS_FWLOG_SIZE) != PMCS_FWLOG_SIZE) {
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister mdb_warn("Failed to write %d bytes to output file: instance %d",
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister mdb_printf("Event log for instance %d written to %s\n", instance,
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollisterpmcs_fwlog(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister if (mdb_getopts(argc, argv, 'o', MDB_OPT_STR, &ofile, NULL) != argc) {
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) {
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_fwlog", argc,
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister mdb_warn("mdb_pwalk_dcmd failed for pmcs_log");
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) {
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister return (pmcs_dump_fwlog(&ss, dip.devi_instance, ofile));
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister#endif /* _KMDB */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdhpmcs_log(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana uint64_t match_sas_address = 0, tail_lines = 0;
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) {
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs_log", argc,
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) {
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister tail_lines, match_phy_path, match_sas_address, verbose));
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana return (pmcs_dump_tracelog(B_FALSE, 0, tail_lines,
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister match_phy_path, match_sas_address, verbose));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhpmcs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_readvar(&pmcs_state, "pmcs_softc_state") == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_pwalk_dcmd("genunix`softstate", "pmcs`pmcs", argc, argv,
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister 'D', MDB_OPT_UINTPTR_SET, &devid_filter, &pdevid,
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed * The 'd' and 'm' options implicitly enable the 'I' option
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister * The -D option is meaningless without -q and/or -Q, and implies
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister mdb_printf("-D requires either -q or -Q\n");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (MDB_RD(&dip, sizeof (struct dev_info), ss.dip) == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* processing completed */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (flags & DCMD_LOOPFIRST) || phy_info || target_info || hw_info ||
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh work_info || waitqs_info || ibq || obq || tgt_phy_count || compq ||
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("%16s %9s %4s B C WorkFlags wserno DbgMsk %16s\n",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "============================================\n");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("%16p %9s %4d %1d %1d 0x%08x 0x%04x 0x%04x %16p\n", addr,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh state_str, dip.devi_instance, ss.blocked, ss.configuring,
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister display_outbound_queues(ss, devid, verbose);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rv);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("Prints summary information about each pmcs instance.\n"
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh " -c: Dump the completion queue\n"
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed " -d: Print per-iport information about device tree children\n"
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister " -D <device ID>: With -q/-Q, filter by device handle\n"
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister " -e: Display the in-memory firmware event log\n"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh " -h: Print more detailed hardware information\n"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh " -i: Print interrupt coalescing information\n"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh " -I: Print information about each iport\n"
f7aef0b0ce0e9a2c3da9c2e3aa9122f3642c1459Reed " -m: Print per-iport information about DAM/damap state\n"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh " -p: Print information about each attached PHY\n"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh " -q: Dump inbound queues\n"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh " -Q: Dump outbound queues\n"
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister " -s: Dump all work structures sorted by serial number\n"
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh " -t: Print information about each configured target\n"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh " -T: Print target and PHY count summary\n"
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh " -u: Show SAS address of all unconfigured targets\n"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh " -w: Dump work structures\n"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh " -W: List pmcs cmds waiting on various queues\n"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh " -v: Add verbosity to the above options\n");
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh mdb_printf("Dump the pmcs log buffer, possibly with filtering.\n"
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana " -l TAIL_LINES: Dump the last TAIL_LINES messages\n"
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh " -p PHY_PATH: Dump messages matching PHY_PATH\n"
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh " -s SAS_ADDRESS: Dump messages matching SAS_ADDRESS\n\n"
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh "Where: PHY_PATH can be found with ::pmcs -p (e.g. pp04.18.18.01)\n"
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh " SAS_ADDRESS can be found with ::pmcs -t "
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh "(e.g. 5000c5000358c221)\n");
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh mdb_printf("Print all work structures by matching the tag.\n"
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh " -i index: Match tag index (0x000 - 0xfff)\n"
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh " -s serialnumber: Match serial number (0x0000 - 0xffff)\n"
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh " -t tagtype: Match tag type [NONE(1), CBACK(2), "
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh "WAIT(3)]\n");
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister { "pmcs", "?[-cdehiImpQqtTuwWv] [-D <device ID>]",
65e70c04884b95e29d10e9933a3d55f0ec5af3beDavid Hollister "print pmcs information", pmcs_dcmd, pmcs_help
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh { "pmcs_log",
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister "?[-v] [-p PHY_PATH | -s SAS_ADDRESS | -l TAIL_LINES]",
14d6cf0a831fafb130183d4a32c30acbe84b9f4bdh "Find work structures by tag type, serial number or index",
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister { "pmcs_fwlog",
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister "?-o output_file",
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister "dump pmcs firmware event log to output_file", pmcs_fwlog, NULL
9719310a57482091af0a7f0ee31b5e2eec35f154David Hollister#endif /* _KMDB */