4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * CDDL HEADER START
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *
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 *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * or http://www.opensolaris.org/os/licensing.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * See the License for the specific language governing permissions
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * and limitations under the License.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *
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 *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * CDDL HEADER END
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
5d562cec9a5c49bc665980c775f32f708cb2f3e9Milos Muzik * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <mdb/mdb_modapi.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/sysmacros.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/sunddi.h>
d189c17091985028902e6d1c75816619dc62c7d0Reed#include <sys/damap.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include <sys/damap_impl.h>
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#include "damap.h"
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhvoid
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhdamap_help(void)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("Print the damap at the address given.\n");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("\n");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("EXAMPLE: SCSI: To display the SCSI tgtmap damaps ");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("associated with a scsi HBA driver iport dip:\n");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("\n");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("::devbindings -q <driver_name>\n");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("\n");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("<iport-dip>::print struct dev_info devi_driver_data|");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("::print scsi_hba_tran_t tran_tgtmap|");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("::print impl_scsi_tgtmap_t ");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("tgtmap_dam[0] tgtmap_dam[1]|::damap\n");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic char *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhlocal_strdup(const char *s)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (s)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (strcpy(mdb_alloc(strlen(s) + 1, UM_SLEEP), s));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh else
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (NULL);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhlocal_strfree(const char *s)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (s)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_free((void *)s, strlen(s) + 1);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhbitset_free(bitset_t *bs, int embedded)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (bs == NULL)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (bs->bs_set && bs->bs_words)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_free(bs->bs_set, bs->bs_words * sizeof (ulong_t));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (!embedded)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_free(bs, sizeof (*bs)); /* not embedded, free */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic bitset_t *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhbitset_get(uintptr_t bsaddr)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bitset_t *bs;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bs = mdb_zalloc(sizeof (*bs), UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_vread(bs, sizeof (*bs), bsaddr) == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_warn("couldn't read bitset 0x%p", bsaddr);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bitset_free(bs, 0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (NULL);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bsaddr = (uintptr_t)bs->bs_set;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bs->bs_set = mdb_alloc(bs->bs_words * sizeof (ulong_t), UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_vread(bs->bs_set,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bs->bs_words * sizeof (ulong_t), bsaddr) == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_warn("couldn't read bitset bs_set 0x%p", bsaddr);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bitset_free(bs, 0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (NULL);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (bs);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhdamap_free(struct dam *dam, void **kdamda, int kdamda_n)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int i;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh struct i_ddi_soft_state *ss;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam_da_t *da;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (dam) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* free in dam_da_t softstate */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ss = (struct i_ddi_soft_state *)dam->dam_da;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ss) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ss->n_items && ss->array) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh for (i = 0; i < ss->n_items; i++) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh da = ss->array[i];
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (da == NULL)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh continue;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh local_strfree(da->da_addr);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_free(da, sizeof (*da));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_free(ss, sizeof (*ss));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* free dam_active/stable/report_set embedded in dam */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bitset_free(&dam->dam_report_set, 1);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bitset_free(&dam->dam_stable_set, 1);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bitset_free(&dam->dam_active_set, 1);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* free dam_name */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh local_strfree(dam->dam_name);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* free dam */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_free(dam, sizeof (*dam));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (kdamda)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_free(kdamda, kdamda_n * sizeof (void *));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * The dam implementation uses a number of different abstractions. Given a
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * pointer to a damap_t, this function make an mdb instantiation of the dam -
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * many, but not all, of the different abstractions used in the dam
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * implementation are also instantiated in mdb. This means that callers of
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * damap_get can perform some (but not all) types of structure pointer
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * traversals.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstruct dam *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhdamap_get(uintptr_t damaddr, void ***pkdamda, int *pkdamda_n)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* variables that hold instantiation read from kernel */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh struct dam kdam;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh char kstring[MAXPATHLEN];
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh struct i_ddi_soft_state kss;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh void **kssarray = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int array_sz = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* variables that hold mdb instantiation */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh struct dam *dam = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh struct i_ddi_soft_state *ss;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bitset_t *bs;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam_da_t *da;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int i;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* read kernel: dam */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_vread(&kdam, sizeof (kdam), damaddr) == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_warn("couldn't read dam 0x%p", damaddr);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh goto err;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* read kernel: dam->dam_name */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_readstr(kstring, sizeof (kstring), (uintptr_t)kdam.dam_name);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* read kernel: dam->dam_da (softstate) */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_vread(&kss, sizeof (kss), (uintptr_t)kdam.dam_da) == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_warn("couldn't read dam dam_da 0x%p",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (uintptr_t)kdam.dam_da);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh goto err;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* read kernel ((struct i_ddi_soft_state *)dam->dam_da)->array */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh array_sz = kss.n_items * sizeof (void *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh kssarray = mdb_alloc(array_sz, UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_vread(kssarray, array_sz, (uintptr_t)kss.array) == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_warn("couldn't read dam dam_da array 0x%p",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (uintptr_t)kss.array);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh goto err;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /*
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Produce mdb instantiation of kernel data structures.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Structure copy kdam to dam, then clear out pointers in dam (some
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * will be filled in by mdb instantiation code below).
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam = mdb_zalloc(sizeof (*dam), UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *dam = kdam;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam->dam_name = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam->dam_active_set.bs_set = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam->dam_stable_set.bs_set = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam->dam_report_set.bs_set = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam->dam_da = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* dam_addr_hash, dam_taskqp, dam_kstatp left as kernel addresses */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* fill in dam_name */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam->dam_name = local_strdup(kstring);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* fill in dam_active/stable/report_set embedded in the dam */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bs = bitset_get(damaddr + (offsetof(struct dam, dam_active_set)));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (bs) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam->dam_active_set = *bs;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_free(bs, sizeof (*bs));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bs = bitset_get(damaddr + (offsetof(struct dam, dam_stable_set)));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (bs) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam->dam_stable_set = *bs;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_free(bs, sizeof (*bs));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh bs = bitset_get(damaddr + (offsetof(struct dam, dam_report_set)));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (bs) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam->dam_report_set = *bs;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_free(bs, sizeof (*bs));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* fill in dam_da_t softstate */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ss = mdb_zalloc(sizeof (struct i_ddi_soft_state), UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *ss = kss;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ss->next = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ss->array = mdb_zalloc(array_sz, UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam->dam_da = ss;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh for (i = 0; i < kss.n_items; i++) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (kssarray[i] == NULL)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh continue;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh da = ss->array[i] = mdb_zalloc(sizeof (*da), UM_SLEEP);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (mdb_vread(da, sizeof (*da), (uintptr_t)kssarray[i]) == -1) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_warn("couldn't read dam dam_da %d 0x%p", i,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (uintptr_t)kss.array);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh goto err;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* da_nvl, da_ppriv_rpt, da_nvl_rpt left as kernel addresses */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* read kernel: da->da_addr */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_readstr(kstring, sizeof (kstring), (uintptr_t)da->da_addr);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh da->da_addr = local_strdup(kstring);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* return array of kernel dam_da_t pointers associated with each id */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *pkdamda = kssarray;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *pkdamda_n = array_sz / sizeof (void *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* return pointer to mdb instantiation of the dam */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (dam);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dherr: damap_free(dam, kssarray, array_sz / sizeof (void *));
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *pkdamda = NULL;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh *pkdamda_n = 0;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (NULL);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*ARGSUSED*/
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhdamap_print(struct dam *dam, void **kdamda, int kdamda_n)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh struct i_ddi_soft_state *ss;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam_da_t *da;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int i;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("%s:\n", dam->dam_name);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ss = (struct i_ddi_soft_state *)dam->dam_da;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ss == NULL)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if ((ss->n_items == 0) || (ss->array == NULL))
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
5d562cec9a5c49bc665980c775f32f708cb2f3e9Milos Muzik mdb_printf(" #: %-20s [ASR] ref config-private provider-private\n",
5d562cec9a5c49bc665980c775f32f708cb2f3e9Milos Muzik "address");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh for (i = 0; i < ss->n_items; i++) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh da = ss->array[i];
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (da == NULL)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh continue;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Print index and address. */
5d562cec9a5c49bc665980c775f32f708cb2f3e9Milos Muzik mdb_printf(" %3d: %-20s [", i, da->da_addr);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Print shorthand of Active/Stable/Report set membership */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (BT_TEST(dam->dam_active_set.bs_set, i))
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("A");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh else
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf(".");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (BT_TEST(dam->dam_stable_set.bs_set, i))
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("S");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh else
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf(".");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (BT_TEST(dam->dam_report_set.bs_set, i))
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf("R");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh else
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh mdb_printf(".");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Print the reference count and priv */
5d562cec9a5c49bc665980c775f32f708cb2f3e9Milos Muzik mdb_printf("] %-3d %0?lx %0?lx\n",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh da->da_ref, da->da_cfg_priv, da->da_ppriv);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
5d562cec9a5c49bc665980c775f32f708cb2f3e9Milos Muzik mdb_printf(" %p::print -ta dam_da_t\n", kdamda[i]);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh }
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/*ARGSUSED*/
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhdamap(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh{
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh struct dam *dam;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh void **kdamda;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int kdamda_n;
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
5d562cec9a5c49bc665980c775f32f708cb2f3e9Milos Muzik if (!(flags & DCMD_ADDRSPEC)) {
5d562cec9a5c49bc665980c775f32f708cb2f3e9Milos Muzik return (DCMD_ERR);
5d562cec9a5c49bc665980c775f32f708cb2f3e9Milos Muzik }
5d562cec9a5c49bc665980c775f32f708cb2f3e9Milos Muzik
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh dam = damap_get(addr, &kdamda, &kdamda_n);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (dam == NULL)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (DCMD_ERR);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh damap_print(dam, kdamda, kdamda_n);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh damap_free(dam, kdamda, kdamda_n);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (DCMD_OK);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh}