70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * CDDL HEADER START
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * The contents of this file are subject to the terms of the
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Common Development and Distribution License (the "License").
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * You may not use this file except in compliance with the License.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * or http://www.opensolaris.org/os/licensing.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * See the License for the specific language governing permissions
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * and limitations under the License.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * When distributing Covered Code, include this CDDL HEADER in each
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * If applicable, add the following below this CDDL HEADER, with the
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * fields enclosed by brackets "[]" replaced with your own identifying
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * information: Portions Copyright [yyyy] [name of copyright owner]
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * CDDL HEADER END
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Use is subject to license terms.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#pragma ident "%Z%%M% %I% %E% SMI"
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/kmem.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/proc.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/time.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/conf.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/file.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/ddi.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/ddi_impldefs.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/modctl.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/sunddi.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/scsi/scsi.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/scsi/impl/scsi_reset_notify.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/sunmdi.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/mdi_impldefs.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/scsi/adapters/scsi_vhci.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/scsi/scsi_types.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/disp.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/types.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include <sys/mdb_modapi.h>
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#include "mdi.h"
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat#define FT(var, typ) (*((typ *)(&(var))))
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* Utils */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic int get_mdbstr(uintptr_t addr, char *name);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic void dump_flags(unsigned long long flags, char **strings);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic void dump_mutex(kmutex_t m, char *name);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic void dump_condvar(kcondvar_t c, char *name);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic void dump_string(uintptr_t addr, char *name);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic void dump_state_str(char *name, uintptr_t addr, char **strings);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic int mpxio_walk_cb(uintptr_t addr, const void *data, void *cbdata);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic char *client_lb_str[] =
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "NONE",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "RR",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "LBA",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat NULL
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat};
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic char *mdi_pathinfo_states[] =
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PATHINFO_STATE_INIT",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PATHINFO_STATE_ONLINE",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PATHINFO_STATE_STANDBY",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PATHINFO_STATE_FAULT",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PATHINFO_STATE_OFFLINE",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat NULL
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat};
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic char *mdi_pathinfo_ext_states[] =
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PATHINFO_STATE_USER_DISABLE",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PATHINFO_STATE_DRV_DISABLE",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PATHINFO_STATE_DRV_DISABLE_TRANSIENT",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat NULL
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat};
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic char *mdi_phci_flags[] =
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PHCI_FLAGS_OFFLINE",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PHCI_FLAGS_SUSPEND",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PHCI_FLAGS_POWER_DOWN",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PHCI_FLAGS_DETACH",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PHCI_FLAGS_USER_DISABLE",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PHCI_FLAGS_D_DISABLE",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PHCI_FLAGS_D_DISABLE_TRANS",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "MDI_PHCI_FLAGS_POWER_TRANSITION",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat NULL
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat};
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic uintptr_t firstaddr = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic char mdipathinfo_cb_str[] = "::print struct mdi_pathinfo";
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic char mdiphci_cb_str[] = "::print struct mdi_phci";
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * mdipi()
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Given a path, dump mdi_pathinfo struct and detailed pi_prop list.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* ARGSUSED */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdipi(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat struct mdi_pathinfo value;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (!(flags & DCMD_ADDRSPEC)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("mdipi: requires an address");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (mdb_vread(&value, sizeof (struct mdi_pathinfo), addr) !=
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat sizeof (struct mdi_pathinfo)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("mdipi: Failed read on %l#r\n", addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("------------- mdi_pathinfo @ %#lr ----------\n", addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_string((uintptr_t)value.pi_addr, "PWWN,LUN (pi_addr)");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("pi_client: %25l#r::print struct mdi_client\n",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat value.pi_client);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("pi_phci: %27l#r::print struct mdi_phci\n", value.pi_phci);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("pi_pprivate: %23l#r\n", value.pi_pprivate);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("pi_client_link: %20l#r::print struct mdi_pathinfo\n",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat value.pi_client_link);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("pi_phci_link: %22l#r::print struct mdi_pathinfo\n",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat value.pi_phci_link);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("pi_prop: %27l#r::print struct nv_list\n", value.pi_prop);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdiprops((uintptr_t)value.pi_prop, flags, 0, NULL);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_state_str("Pathinfo State (pi_state) ",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat MDI_PI_STATE(&value), mdi_pathinfo_states);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (MDI_PI_IS_TRANSIENT(&value)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("Pathinfo State is TRANSIENT\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (MDI_PI_EXT_STATE(&value)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf(" Extended (pi_state) : ");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat /*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Need to shift right 20 bits to match mdi_pathinfo_ext_states
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * array.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_flags((unsigned long long)MDI_PI_EXT_STATE(&value) >> 20,
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdi_pathinfo_ext_states);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_state_str("Old Pathinfo State (pi_old_state)",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat MDI_PI_OLD_STATE(&value), mdi_pathinfo_states);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (MDI_PI_OLD_EXT_STATE(&value)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf(" Extended (pi_old_state) : ");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat /*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Need to shift right 20 bits to match mdi_pathinfo_ext_states
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * array.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_flags((unsigned long long)MDI_PI_OLD_EXT_STATE(&value)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat >> 20, mdi_pathinfo_ext_states);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_mutex(value.pi_mutex, "per-path mutex (pi_mutex):");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_condvar(value.pi_state_cv, "Path state (pi_state_cv)");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("pi_ref_cnt: %d\n", value.pi_ref_cnt);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_condvar(value.pi_ref_cv, "pi_ref_cv");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("pi_kstats: %25l#r::print struct mdi_pi_kstats\n",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat value.pi_kstats);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("pi_cprivate UNUSED: %16l#r \n", value.pi_cprivate);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_OK);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * mdiprops()
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Given a pi_prop, dump the pi_prop list.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* ARGSUSED */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdiprops(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (!(flags & DCMD_ADDRSPEC)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("mdiprops: requires an address");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\tnvpairs @ %#lr:\n", addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_pwalk_dcmd("nvpair", "nvpair", argc, argv, addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_OK);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * mdiphci()
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Given a phci, dump mdi_phci struct.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* ARGSUSED */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdiphci(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat struct mdi_phci value;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (!(flags & DCMD_ADDRSPEC)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("mdiphci: requires an address");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (mdb_vread(&value, sizeof (struct mdi_phci), addr) !=
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat sizeof (struct mdi_phci)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("mdiphci: Failed read on %l#r\n", addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("---------------- mdi_phci @ %#lr ----------\n", addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("ph_next: %27l#r::print struct mdi_phci\n", value.ph_next);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("ph_prev: %27l#r::print struct mdi_phci\n", value.ph_prev);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("ph_vhci: %27l#r::print struct mdi_vhci\n", value.ph_vhci);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("ph_dip: %28l#r::print struct dev_info\n", value.ph_dip);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\nph_path_head: %22l#r::print struct mdi_pathinfo\n",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat value.ph_path_head);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("ph_path_tail: %22l#r::print struct mdi_pathinfo\n",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat value.ph_path_tail);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("ph_path_count: %21d\n", value.ph_path_count);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("List of paths:\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_pwalk("mdipi_phci_list", (mdb_walk_cb_t)mpxio_walk_cb,
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdipathinfo_cb_str, (uintptr_t)value.ph_path_head);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("ph_flags: %26d\n", value.ph_flags);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (value.ph_flags) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_flags((unsigned long long)value.ph_flags, mdi_phci_flags);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_mutex(value.ph_mutex, "per-pHCI mutex (ph_mutex):");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_condvar(value.ph_unstable_cv,
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat "Paths in transient state (ph_unstable_cv)");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("ph_unstable: %23d\n", value.ph_unstable);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_OK);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * mdivhci()
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Given a vhci, dump mdi_vhci struct and list all phcis.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* ARGSUSED */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdivhci(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat struct mdi_vhci value;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (!(flags & DCMD_ADDRSPEC)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("mdivhci: requires an address");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (mdb_vread(&value, sizeof (struct mdi_vhci), addr) !=
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat sizeof (struct mdi_vhci)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("mdivhci: Failed read on %l#r\n", addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("----------------- mdi_vhci @ %#lr ----------\n", addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_string((uintptr_t)value.vh_class, "Class name (vh_class)");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("vh_refcnt: %19d\n", value.vh_refcnt);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("vh_dip: %28l#r::print struct dev_info\n", value.vh_dip);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("vh_next: %27l#r::print struct mdi_vhci\n", value.vh_next);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("vh_prev: %27l#r::print struct mdi_vhci\n", value.vh_prev);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_state_str("Load Balance (vh_lb)", value.vh_lb, client_lb_str);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("vh_ops: %28l#r::print struct mdi_vhci_ops\n",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat value.vh_ops);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_mutex(value.vh_phci_mutex, "phci mutex (vh_phci_mutex):");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("vh_phci_count: %21d\n", value.vh_phci_count);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\nvh_phci_head: %22l#r::print struct mdi_phci\n",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat value.vh_phci_head);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("vh_phci_tail: %22l#r::print struct mdi_phci\n",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat value.vh_phci_tail);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat dump_mutex(value.vh_phci_mutex, "client mutex (vh_client_mutex):");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("vh_client_count: %19d\n", value.vh_client_count);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("vh_client_table: %19l#r::print struct client_hash\n",
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat value.vh_client_table);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("List of pHCIs:\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_pwalk("mdiphci_list", (mdb_walk_cb_t)mpxio_walk_cb,
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdiphci_cb_str, (uintptr_t)value.vh_phci_head);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_OK);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* mdi_pathinfo client walker */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* ARGUSED */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdi_pi_client_link_walk_init(mdb_walk_state_t *wsp)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (wsp->walk_addr == NULL) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("Address is required");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_data = mdb_alloc(sizeof (struct mdi_pathinfo), UM_SLEEP);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat firstaddr = wsp->walk_addr;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_NEXT);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* ARGUSED */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdi_pi_client_link_walk_step(mdb_walk_state_t *wsp)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat int status = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat static int counts = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (firstaddr == wsp->walk_addr && counts != 0) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat counts = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_DONE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (wsp->walk_addr == NULL) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat counts = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_DONE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (mdb_vread(wsp->walk_data, sizeof (struct mdi_pathinfo),
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_addr) == -1) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("failed to read mdi_pathinfo at %p", wsp->walk_addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_DONE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_cbdata);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_addr = (uintptr_t)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat (((struct mdi_pathinfo *)wsp->walk_data)->pi_client_link);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat counts++;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (status);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* ARGUSED */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatvoid
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdi_pi_client_link_walk_fini(mdb_walk_state_t *wsp)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_free(wsp->walk_data, sizeof (struct mdi_pathinfo));
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * mdiclient_paths()
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Given a path, walk through mdi_pathinfo client links.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* ARGUSED */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdiclient_paths(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat int status;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (argc != 0)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_USAGE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (!(flags & DCMD_ADDRSPEC)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("Address needs to be specified");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat status =
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_pwalk_dcmd("mdipi_client_list", "mdipi", argc, argv, addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (status);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* mdi_pathinfo phci walker */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdi_pi_phci_link_walk_init(mdb_walk_state_t *wsp)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (wsp->walk_addr == NULL) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("Address is required");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_data = mdb_alloc(sizeof (struct mdi_pathinfo), UM_SLEEP);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat firstaddr = wsp->walk_addr;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_NEXT);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdi_pi_phci_link_walk_step(mdb_walk_state_t *wsp)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat int status;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat static int counts = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (firstaddr == wsp->walk_addr && counts != 0) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat counts = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_DONE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (wsp->walk_addr == NULL) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat counts = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_DONE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (mdb_vread(wsp->walk_data, sizeof (struct mdi_pathinfo),
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_addr) == -1) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("failed to read mdi_pathinfo at %p", wsp->walk_addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_DONE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_cbdata);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_addr = (uintptr_t)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat (((struct mdi_pathinfo *)wsp->walk_data)->pi_phci_link);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat counts++;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (status);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatvoid
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdi_pi_phci_link_walk_fini(mdb_walk_state_t *wsp)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_free(wsp->walk_data, sizeof (struct mdi_pathinfo));
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * mdiphci_paths()
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Given a path, walk through mdi_pathinfo phci links.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdiphci_paths(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat int status;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (argc != 0)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_USAGE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (!(flags & DCMD_ADDRSPEC)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("Address needs to be specified");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat status =
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_pwalk_dcmd("mdipi_phci_list", "mdipi", argc, argv, addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (status);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* mdi_phci walker */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdi_phci_ph_next_walk_init(mdb_walk_state_t *wsp)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (wsp->walk_addr == NULL) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("Address is required");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_data = mdb_alloc(sizeof (struct mdi_phci), UM_SLEEP);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat firstaddr = wsp->walk_addr;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_NEXT);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdi_phci_ph_next_walk_step(mdb_walk_state_t *wsp)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat int status;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat static int counts = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (firstaddr == wsp->walk_addr && counts != 0) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat counts = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_DONE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (wsp->walk_addr == NULL) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat counts = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_DONE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (mdb_vread(wsp->walk_data, sizeof (struct mdi_phci), wsp->walk_addr)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat == -1) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("failed to read mdi_phci at %p", wsp->walk_addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (WALK_DONE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_cbdata);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat wsp->walk_addr = (uintptr_t)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat (((struct mdi_phci *)wsp->walk_data)->ph_next);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat counts++;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (status);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatvoid
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdi_phci_ph_next_walk_fini(mdb_walk_state_t *wsp)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_free(wsp->walk_data, sizeof (struct mdi_phci));
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * mdiphcis()
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat *
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Given a phci, walk through mdi_phci ph_next links.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatint
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmdiphcis(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat int status;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (argc != 0)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_USAGE);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (!(flags & DCMD_ADDRSPEC)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("Address needs to be specified");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (DCMD_ERR);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat status =
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_pwalk_dcmd("mdiphci_list", "mdiphci", argc, argv, addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (status);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/*
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat * Print the flag name by comparing flags to the mask variable.
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic void
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatdump_flags(unsigned long long flags, char **strings)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat int i, linel = 8, first = 1;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat unsigned long long mask = 1;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat for (i = 0; i < 64; i++) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (strings[i] == NULL)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat break;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (flags & mask) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (!first) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf(" | ");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat } else {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat first = 0;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat /* make output pretty */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat linel += strlen(strings[i]) + 3;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (linel > 80) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\n\t");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat linel = strlen(strings[i]) + 1 + 8;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("%s", strings[i]);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mask <<= 1;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("\n");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic void
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatdump_mutex(kmutex_t m, char *name)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("%s is%s held\n", name, FT(m, uint64_t) == 0 ? " not" : "");
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic void
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatdump_condvar(kcondvar_t c, char *name)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("Threads sleeping on %s = %d\n", name, (int)FT(c, ushort_t));
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic int
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatget_mdbstr(uintptr_t addr, char *string_val)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (mdb_readstr(string_val, MAXNAMELEN, addr) == -1) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_warn("Error Reading String from %l#r\n", addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (1);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (0);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic void
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatdump_string(uintptr_t addr, char *name)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat char string_val[MAXNAMELEN];
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat if (get_mdbstr(addr, string_val)) {
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return;
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat }
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("%s: %s (%l#r)\n", name, string_val, addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic void
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatdump_state_str(char *name, uintptr_t addr, char **strings)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("%s: %s (%l#r)\n", name, strings[(unsigned long)addr], addr);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat/* ARGSUSED */
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatstatic int
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramatmpxio_walk_cb(uintptr_t addr, const void *data, void *cbdata)
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat{
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat mdb_printf("%t%l#r%s\n", addr, (char *)cbdata);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat return (0);
70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40ramat}