1*10696SDavid.Hollister@Sun.COM /* 2*10696SDavid.Hollister@Sun.COM * CDDL HEADER START 3*10696SDavid.Hollister@Sun.COM * 4*10696SDavid.Hollister@Sun.COM * The contents of this file are subject to the terms of the 5*10696SDavid.Hollister@Sun.COM * Common Development and Distribution License (the "License"). 6*10696SDavid.Hollister@Sun.COM * You may not use this file except in compliance with the License. 7*10696SDavid.Hollister@Sun.COM * 8*10696SDavid.Hollister@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*10696SDavid.Hollister@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*10696SDavid.Hollister@Sun.COM * See the License for the specific language governing permissions 11*10696SDavid.Hollister@Sun.COM * and limitations under the License. 12*10696SDavid.Hollister@Sun.COM * 13*10696SDavid.Hollister@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*10696SDavid.Hollister@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*10696SDavid.Hollister@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*10696SDavid.Hollister@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*10696SDavid.Hollister@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*10696SDavid.Hollister@Sun.COM * 19*10696SDavid.Hollister@Sun.COM * CDDL HEADER END 20*10696SDavid.Hollister@Sun.COM */ 21*10696SDavid.Hollister@Sun.COM 22*10696SDavid.Hollister@Sun.COM /* 23*10696SDavid.Hollister@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*10696SDavid.Hollister@Sun.COM * Use is subject to license terms. 25*10696SDavid.Hollister@Sun.COM */ 26*10696SDavid.Hollister@Sun.COM 27*10696SDavid.Hollister@Sun.COM #include <sys/note.h> 28*10696SDavid.Hollister@Sun.COM #include <sys/types.h> 29*10696SDavid.Hollister@Sun.COM #include <sys/param.h> 30*10696SDavid.Hollister@Sun.COM #include <sys/systm.h> 31*10696SDavid.Hollister@Sun.COM #include <sys/buf.h> 32*10696SDavid.Hollister@Sun.COM #include <sys/kmem.h> 33*10696SDavid.Hollister@Sun.COM #include <sys/cmn_err.h> 34*10696SDavid.Hollister@Sun.COM #include <sys/debug.h> 35*10696SDavid.Hollister@Sun.COM #include <sys/sunndi.h> 36*10696SDavid.Hollister@Sun.COM #include <sys/kstat.h> 37*10696SDavid.Hollister@Sun.COM #include <sys/conf.h> 38*10696SDavid.Hollister@Sun.COM #include <sys/ddi_timer.h> 39*10696SDavid.Hollister@Sun.COM #include <sys/devctl.h> 40*10696SDavid.Hollister@Sun.COM #include <sys/callb.h> 41*10696SDavid.Hollister@Sun.COM #include <sys/sysevent.h> 42*10696SDavid.Hollister@Sun.COM #include <sys/taskq.h> 43*10696SDavid.Hollister@Sun.COM #include <sys/ddi.h> 44*10696SDavid.Hollister@Sun.COM #include <sys/bitset.h> 45*10696SDavid.Hollister@Sun.COM #include <sys/damap.h> 46*10696SDavid.Hollister@Sun.COM #include <sys/damap_impl.h> 47*10696SDavid.Hollister@Sun.COM 48*10696SDavid.Hollister@Sun.COM #ifdef DEBUG 49*10696SDavid.Hollister@Sun.COM static int damap_debug = 0; 50*10696SDavid.Hollister@Sun.COM #endif /* DEBUG */ 51*10696SDavid.Hollister@Sun.COM 52*10696SDavid.Hollister@Sun.COM static void dam_addrset_activate(dam_t *, bitset_t *); 53*10696SDavid.Hollister@Sun.COM static void dam_addrset_release(dam_t *, bitset_t *); 54*10696SDavid.Hollister@Sun.COM static void dam_activate_taskq(void *); 55*10696SDavid.Hollister@Sun.COM static void dam_addr_stable_cb(void *); 56*10696SDavid.Hollister@Sun.COM static void dam_set_stable_cb(void *); 57*10696SDavid.Hollister@Sun.COM static void dam_sched_tmo(dam_t *, clock_t, void (*tmo_cb)()); 58*10696SDavid.Hollister@Sun.COM static void dam_add_report(dam_t *, dam_da_t *, id_t, int); 59*10696SDavid.Hollister@Sun.COM static void dam_release(dam_t *, id_t); 60*10696SDavid.Hollister@Sun.COM static void dam_release_report(dam_t *, id_t); 61*10696SDavid.Hollister@Sun.COM static void dam_deactivate_addr(dam_t *, id_t); 62*10696SDavid.Hollister@Sun.COM static id_t dam_get_addrid(dam_t *, char *); 63*10696SDavid.Hollister@Sun.COM static int dam_kstat_create(dam_t *); 64*10696SDavid.Hollister@Sun.COM static void dam_kstat_destroy(dam_t *); 65*10696SDavid.Hollister@Sun.COM 66*10696SDavid.Hollister@Sun.COM #define DAM_INCR_STAT(mapp, stat) \ 67*10696SDavid.Hollister@Sun.COM if ((mapp)->dam_kstatsp) { \ 68*10696SDavid.Hollister@Sun.COM struct dam_kstats *stp = (mapp)->dam_kstatsp->ks_data; \ 69*10696SDavid.Hollister@Sun.COM stp->stat.value.ui32++; \ 70*10696SDavid.Hollister@Sun.COM } 71*10696SDavid.Hollister@Sun.COM 72*10696SDavid.Hollister@Sun.COM #define DAM_SET_STAT(mapp, stat, val) \ 73*10696SDavid.Hollister@Sun.COM if ((mapp)->dam_kstatsp) { \ 74*10696SDavid.Hollister@Sun.COM struct dam_kstats *stp = (mapp)->dam_kstatsp->ks_data; \ 75*10696SDavid.Hollister@Sun.COM stp->stat.value.ui32 = (val); \ 76*10696SDavid.Hollister@Sun.COM } 77*10696SDavid.Hollister@Sun.COM 78*10696SDavid.Hollister@Sun.COM /* 79*10696SDavid.Hollister@Sun.COM * Create new device address map 80*10696SDavid.Hollister@Sun.COM * 81*10696SDavid.Hollister@Sun.COM * ident: map name (kstat) 82*10696SDavid.Hollister@Sun.COM * size: max # of map entries 83*10696SDavid.Hollister@Sun.COM * rptmode: type or mode of reporting 84*10696SDavid.Hollister@Sun.COM * stable_usec: # of quiescent microseconds before report/map is stable 85*10696SDavid.Hollister@Sun.COM * 86*10696SDavid.Hollister@Sun.COM * activate_arg: address provider activation-callout private 87*10696SDavid.Hollister@Sun.COM * activate_cb: address provider activation callback handler 88*10696SDavid.Hollister@Sun.COM * deactivate_cb: address provider deactivation callback handler 89*10696SDavid.Hollister@Sun.COM * 90*10696SDavid.Hollister@Sun.COM * config_arg: configuration-callout private 91*10696SDavid.Hollister@Sun.COM * config_cb: class configuration callout 92*10696SDavid.Hollister@Sun.COM * unconfig_cb: class unconfiguration callout 93*10696SDavid.Hollister@Sun.COM * 94*10696SDavid.Hollister@Sun.COM * damapp: pointer to map handle (return) 95*10696SDavid.Hollister@Sun.COM * 96*10696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 97*10696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 98*10696SDavid.Hollister@Sun.COM * DAM_FAILURE General failure 99*10696SDavid.Hollister@Sun.COM */ 100*10696SDavid.Hollister@Sun.COM int 101*10696SDavid.Hollister@Sun.COM damap_create(char *ident, size_t size, damap_rptmode_t rptmode, 102*10696SDavid.Hollister@Sun.COM clock_t stable_usec, 103*10696SDavid.Hollister@Sun.COM void *activate_arg, damap_activate_cb_t activate_cb, 104*10696SDavid.Hollister@Sun.COM damap_deactivate_cb_t deactivate_cb, 105*10696SDavid.Hollister@Sun.COM void *config_arg, damap_configure_cb_t configure_cb, 106*10696SDavid.Hollister@Sun.COM damap_unconfig_cb_t unconfig_cb, 107*10696SDavid.Hollister@Sun.COM damap_t **damapp) 108*10696SDavid.Hollister@Sun.COM { 109*10696SDavid.Hollister@Sun.COM dam_t *mapp; 110*10696SDavid.Hollister@Sun.COM void *softstate_p; 111*10696SDavid.Hollister@Sun.COM 112*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__create__entry, char *, ident); 113*10696SDavid.Hollister@Sun.COM if ((configure_cb == NULL) || (unconfig_cb == NULL)) 114*10696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 115*10696SDavid.Hollister@Sun.COM 116*10696SDavid.Hollister@Sun.COM if (ddi_soft_state_init(&softstate_p, sizeof (dam_da_t), size) != 117*10696SDavid.Hollister@Sun.COM DDI_SUCCESS) 118*10696SDavid.Hollister@Sun.COM return (DAM_FAILURE); 119*10696SDavid.Hollister@Sun.COM 120*10696SDavid.Hollister@Sun.COM mapp = kmem_zalloc(sizeof (*mapp), KM_SLEEP); 121*10696SDavid.Hollister@Sun.COM if (ddi_strid_init(&mapp->dam_addr_hash, size) != DDI_SUCCESS) { 122*10696SDavid.Hollister@Sun.COM ddi_soft_state_fini(&softstate_p); 123*10696SDavid.Hollister@Sun.COM kmem_free(mapp, sizeof (*mapp)); 124*10696SDavid.Hollister@Sun.COM return (DAM_FAILURE); 125*10696SDavid.Hollister@Sun.COM } 126*10696SDavid.Hollister@Sun.COM 127*10696SDavid.Hollister@Sun.COM mapp->dam_da = softstate_p; 128*10696SDavid.Hollister@Sun.COM mapp->dam_stabletmo = drv_usectohz(stable_usec); 129*10696SDavid.Hollister@Sun.COM mapp->dam_size = size; 130*10696SDavid.Hollister@Sun.COM mapp->dam_high = 1; 131*10696SDavid.Hollister@Sun.COM mapp->dam_rptmode = rptmode; 132*10696SDavid.Hollister@Sun.COM 133*10696SDavid.Hollister@Sun.COM mapp->dam_activate_arg = activate_arg; 134*10696SDavid.Hollister@Sun.COM mapp->dam_activate_cb = (activate_cb_t)activate_cb; 135*10696SDavid.Hollister@Sun.COM mapp->dam_deactivate_cb = (deactivate_cb_t)deactivate_cb; 136*10696SDavid.Hollister@Sun.COM 137*10696SDavid.Hollister@Sun.COM mapp->dam_config_arg = config_arg; 138*10696SDavid.Hollister@Sun.COM mapp->dam_configure_cb = (configure_cb_t)configure_cb; 139*10696SDavid.Hollister@Sun.COM mapp->dam_unconfig_cb = (unconfig_cb_t)unconfig_cb; 140*10696SDavid.Hollister@Sun.COM 141*10696SDavid.Hollister@Sun.COM if (ident) 142*10696SDavid.Hollister@Sun.COM mapp->dam_name = i_ddi_strdup(ident, KM_SLEEP); 143*10696SDavid.Hollister@Sun.COM 144*10696SDavid.Hollister@Sun.COM bitset_init(&mapp->dam_active_set); 145*10696SDavid.Hollister@Sun.COM bitset_resize(&mapp->dam_active_set, size); 146*10696SDavid.Hollister@Sun.COM bitset_init(&mapp->dam_stable_set); 147*10696SDavid.Hollister@Sun.COM bitset_resize(&mapp->dam_stable_set, size); 148*10696SDavid.Hollister@Sun.COM bitset_init(&mapp->dam_report_set); 149*10696SDavid.Hollister@Sun.COM bitset_resize(&mapp->dam_report_set, size); 150*10696SDavid.Hollister@Sun.COM mutex_init(&mapp->dam_lock, NULL, MUTEX_DRIVER, NULL); 151*10696SDavid.Hollister@Sun.COM cv_init(&mapp->dam_cv, NULL, CV_DRIVER, NULL); 152*10696SDavid.Hollister@Sun.COM mapp->dam_taskqp = ddi_taskq_create(NULL, ident, 1, TASKQ_DEFAULTPRI, 153*10696SDavid.Hollister@Sun.COM 0); 154*10696SDavid.Hollister@Sun.COM *damapp = (damap_t *)mapp; 155*10696SDavid.Hollister@Sun.COM if (dam_kstat_create(mapp) != DDI_SUCCESS) { 156*10696SDavid.Hollister@Sun.COM damap_destroy((damap_t *)mapp); 157*10696SDavid.Hollister@Sun.COM return (DAM_FAILURE); 158*10696SDavid.Hollister@Sun.COM } 159*10696SDavid.Hollister@Sun.COM 160*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__create__exit, dam_t *, mapp); 161*10696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 162*10696SDavid.Hollister@Sun.COM } 163*10696SDavid.Hollister@Sun.COM 164*10696SDavid.Hollister@Sun.COM /* 165*10696SDavid.Hollister@Sun.COM * Destroy device address map 166*10696SDavid.Hollister@Sun.COM * 167*10696SDavid.Hollister@Sun.COM * damapp: address map 168*10696SDavid.Hollister@Sun.COM * 169*10696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 170*10696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 171*10696SDavid.Hollister@Sun.COM * DAM_FAILURE General failure 172*10696SDavid.Hollister@Sun.COM */ 173*10696SDavid.Hollister@Sun.COM void 174*10696SDavid.Hollister@Sun.COM damap_destroy(damap_t *damapp) 175*10696SDavid.Hollister@Sun.COM { 176*10696SDavid.Hollister@Sun.COM int i; 177*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 178*10696SDavid.Hollister@Sun.COM 179*10696SDavid.Hollister@Sun.COM ASSERT(mapp); 180*10696SDavid.Hollister@Sun.COM 181*10696SDavid.Hollister@Sun.COM DTRACE_PROBE2(damap__destroy__entry, dam_t *, mapp, char *, 182*10696SDavid.Hollister@Sun.COM mapp->dam_name); 183*10696SDavid.Hollister@Sun.COM 184*10696SDavid.Hollister@Sun.COM DAM_FLAG_SET(mapp, DAM_DESTROYPEND); 185*10696SDavid.Hollister@Sun.COM (void) damap_sync(damapp); 186*10696SDavid.Hollister@Sun.COM 187*10696SDavid.Hollister@Sun.COM /* 188*10696SDavid.Hollister@Sun.COM * cancel pending timeouts and kill off the taskq 189*10696SDavid.Hollister@Sun.COM */ 190*10696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, 0, NULL); 191*10696SDavid.Hollister@Sun.COM ddi_taskq_wait(mapp->dam_taskqp); 192*10696SDavid.Hollister@Sun.COM ddi_taskq_destroy(mapp->dam_taskqp); 193*10696SDavid.Hollister@Sun.COM 194*10696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 195*10696SDavid.Hollister@Sun.COM if (ddi_get_soft_state(mapp->dam_da, i) == NULL) 196*10696SDavid.Hollister@Sun.COM continue; 197*10696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, i)) 198*10696SDavid.Hollister@Sun.COM dam_release_report(mapp, i); 199*10696SDavid.Hollister@Sun.COM if (DAM_IS_STABLE(mapp, i)) 200*10696SDavid.Hollister@Sun.COM dam_deactivate_addr(mapp, i); 201*10696SDavid.Hollister@Sun.COM ddi_strid_free(mapp->dam_addr_hash, i); 202*10696SDavid.Hollister@Sun.COM ddi_soft_state_free(mapp->dam_da, i); 203*10696SDavid.Hollister@Sun.COM } 204*10696SDavid.Hollister@Sun.COM ddi_strid_fini(&mapp->dam_addr_hash); 205*10696SDavid.Hollister@Sun.COM ddi_soft_state_fini(&mapp->dam_da); 206*10696SDavid.Hollister@Sun.COM bitset_fini(&mapp->dam_active_set); 207*10696SDavid.Hollister@Sun.COM bitset_fini(&mapp->dam_stable_set); 208*10696SDavid.Hollister@Sun.COM bitset_fini(&mapp->dam_report_set); 209*10696SDavid.Hollister@Sun.COM dam_kstat_destroy(mapp); 210*10696SDavid.Hollister@Sun.COM mutex_destroy(&mapp->dam_lock); 211*10696SDavid.Hollister@Sun.COM cv_destroy(&mapp->dam_cv); 212*10696SDavid.Hollister@Sun.COM if (mapp->dam_name) 213*10696SDavid.Hollister@Sun.COM kmem_free(mapp->dam_name, strlen(mapp->dam_name) + 1); 214*10696SDavid.Hollister@Sun.COM kmem_free(mapp, sizeof (*mapp)); 215*10696SDavid.Hollister@Sun.COM DTRACE_PROBE(damap__destroy__exit); 216*10696SDavid.Hollister@Sun.COM } 217*10696SDavid.Hollister@Sun.COM 218*10696SDavid.Hollister@Sun.COM /* 219*10696SDavid.Hollister@Sun.COM * Wait for map stability. 220*10696SDavid.Hollister@Sun.COM * 221*10696SDavid.Hollister@Sun.COM * damapp: address map 222*10696SDavid.Hollister@Sun.COM */ 223*10696SDavid.Hollister@Sun.COM int 224*10696SDavid.Hollister@Sun.COM damap_sync(damap_t *damapp) 225*10696SDavid.Hollister@Sun.COM { 226*10696SDavid.Hollister@Sun.COM 227*10696SDavid.Hollister@Sun.COM #define WAITFOR_FLAGS (DAM_SETADD | DAM_SPEND | MAP_LOCK) 228*10696SDavid.Hollister@Sun.COM 229*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 230*10696SDavid.Hollister@Sun.COM int none_active; 231*10696SDavid.Hollister@Sun.COM 232*10696SDavid.Hollister@Sun.COM ASSERT(mapp); 233*10696SDavid.Hollister@Sun.COM 234*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__sync__entry, dam_t *, mapp); 235*10696SDavid.Hollister@Sun.COM 236*10696SDavid.Hollister@Sun.COM mutex_enter(&mapp->dam_lock); 237*10696SDavid.Hollister@Sun.COM while ((mapp->dam_flags & WAITFOR_FLAGS) || 238*10696SDavid.Hollister@Sun.COM (!bitset_is_null(&mapp->dam_report_set)) || (mapp->dam_tid != 0)) { 239*10696SDavid.Hollister@Sun.COM cv_wait(&mapp->dam_cv, &mapp->dam_lock); 240*10696SDavid.Hollister@Sun.COM } 241*10696SDavid.Hollister@Sun.COM 242*10696SDavid.Hollister@Sun.COM none_active = bitset_is_null(&mapp->dam_active_set); 243*10696SDavid.Hollister@Sun.COM 244*10696SDavid.Hollister@Sun.COM mutex_exit(&mapp->dam_lock); 245*10696SDavid.Hollister@Sun.COM DTRACE_PROBE2(damap__sync__exit, dam_t *, mapp, int, none_active); 246*10696SDavid.Hollister@Sun.COM 247*10696SDavid.Hollister@Sun.COM return (none_active); 248*10696SDavid.Hollister@Sun.COM } 249*10696SDavid.Hollister@Sun.COM 250*10696SDavid.Hollister@Sun.COM /* 251*10696SDavid.Hollister@Sun.COM * Get the name of a device address map 252*10696SDavid.Hollister@Sun.COM * 253*10696SDavid.Hollister@Sun.COM * damapp: address map 254*10696SDavid.Hollister@Sun.COM * 255*10696SDavid.Hollister@Sun.COM * Returns: name 256*10696SDavid.Hollister@Sun.COM */ 257*10696SDavid.Hollister@Sun.COM char * 258*10696SDavid.Hollister@Sun.COM damap_name(damap_t *damapp) 259*10696SDavid.Hollister@Sun.COM { 260*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 261*10696SDavid.Hollister@Sun.COM 262*10696SDavid.Hollister@Sun.COM return (mapp ? mapp->dam_name : "UNKNOWN_damap"); 263*10696SDavid.Hollister@Sun.COM } 264*10696SDavid.Hollister@Sun.COM 265*10696SDavid.Hollister@Sun.COM /* 266*10696SDavid.Hollister@Sun.COM * Report an address to per-address report 267*10696SDavid.Hollister@Sun.COM * 268*10696SDavid.Hollister@Sun.COM * damapp: address map handle 269*10696SDavid.Hollister@Sun.COM * address: address in ascii string representation 270*10696SDavid.Hollister@Sun.COM * rindx: index if address stabilizes 271*10696SDavid.Hollister@Sun.COM * nvl: optional nvlist of configuration-private data 272*10696SDavid.Hollister@Sun.COM * addr_priv: optional provider-private (passed to activate/deactivate cb) 273*10696SDavid.Hollister@Sun.COM * 274*10696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 275*10696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 276*10696SDavid.Hollister@Sun.COM * DAM_MAPFULL address map exhausted 277*10696SDavid.Hollister@Sun.COM */ 278*10696SDavid.Hollister@Sun.COM int 279*10696SDavid.Hollister@Sun.COM damap_addr_add(damap_t *damapp, char *address, damap_id_t *ridx, nvlist_t *nvl, 280*10696SDavid.Hollister@Sun.COM void *addr_priv) 281*10696SDavid.Hollister@Sun.COM { 282*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 283*10696SDavid.Hollister@Sun.COM id_t addrid; 284*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 285*10696SDavid.Hollister@Sun.COM 286*10696SDavid.Hollister@Sun.COM DTRACE_PROBE2(damap__addr__add__entry, dam_t *, mapp, 287*10696SDavid.Hollister@Sun.COM char *, address); 288*10696SDavid.Hollister@Sun.COM if (!mapp || !address || (mapp->dam_rptmode != DAMAP_REPORT_PERADDR) || 289*10696SDavid.Hollister@Sun.COM (mapp->dam_flags & DAM_DESTROYPEND)) 290*10696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 291*10696SDavid.Hollister@Sun.COM 292*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 293*10696SDavid.Hollister@Sun.COM if ((addrid = dam_get_addrid(mapp, address)) == 0) { 294*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 295*10696SDavid.Hollister@Sun.COM return (DAM_MAPFULL); 296*10696SDavid.Hollister@Sun.COM } 297*10696SDavid.Hollister@Sun.COM 298*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 299*10696SDavid.Hollister@Sun.COM ASSERT(passp != NULL); 300*10696SDavid.Hollister@Sun.COM 301*10696SDavid.Hollister@Sun.COM /* 302*10696SDavid.Hollister@Sun.COM * If re-reporting the same address (add or remove) clear 303*10696SDavid.Hollister@Sun.COM * the existing report 304*10696SDavid.Hollister@Sun.COM */ 305*10696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, addrid)) { 306*10696SDavid.Hollister@Sun.COM DAM_INCR_STAT(mapp, dam_rereport); 307*10696SDavid.Hollister@Sun.COM dam_release_report(mapp, addrid); 308*10696SDavid.Hollister@Sun.COM passp->da_jitter++; 309*10696SDavid.Hollister@Sun.COM } 310*10696SDavid.Hollister@Sun.COM passp->da_ppriv_rpt = addr_priv; 311*10696SDavid.Hollister@Sun.COM if (nvl) 312*10696SDavid.Hollister@Sun.COM (void) nvlist_dup(nvl, &passp->da_nvl_rpt, KM_SLEEP); 313*10696SDavid.Hollister@Sun.COM 314*10696SDavid.Hollister@Sun.COM dam_add_report(mapp, passp, addrid, RPT_ADDR_ADD); 315*10696SDavid.Hollister@Sun.COM if (ridx != NULL) 316*10696SDavid.Hollister@Sun.COM *ridx = (damap_id_t)addrid; 317*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 318*10696SDavid.Hollister@Sun.COM DTRACE_PROBE3(damap__addr__add__exit, dam_t *, mapp, char *, 319*10696SDavid.Hollister@Sun.COM address, int, addrid); 320*10696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 321*10696SDavid.Hollister@Sun.COM } 322*10696SDavid.Hollister@Sun.COM 323*10696SDavid.Hollister@Sun.COM /* 324*10696SDavid.Hollister@Sun.COM * Report removal of address from per-address report 325*10696SDavid.Hollister@Sun.COM * 326*10696SDavid.Hollister@Sun.COM * damapp: address map 327*10696SDavid.Hollister@Sun.COM * address: address in ascii string representation 328*10696SDavid.Hollister@Sun.COM * 329*10696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 330*10696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 331*10696SDavid.Hollister@Sun.COM * DAM_FAILURE General failure 332*10696SDavid.Hollister@Sun.COM */ 333*10696SDavid.Hollister@Sun.COM int 334*10696SDavid.Hollister@Sun.COM damap_addr_del(damap_t *damapp, char *address) 335*10696SDavid.Hollister@Sun.COM { 336*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 337*10696SDavid.Hollister@Sun.COM id_t addrid; 338*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 339*10696SDavid.Hollister@Sun.COM 340*10696SDavid.Hollister@Sun.COM DTRACE_PROBE2(damap__addr__del__entry, dam_t *, mapp, 341*10696SDavid.Hollister@Sun.COM char *, address); 342*10696SDavid.Hollister@Sun.COM if (!mapp || !address || (mapp->dam_rptmode != DAMAP_REPORT_PERADDR) || 343*10696SDavid.Hollister@Sun.COM (mapp->dam_flags & DAM_DESTROYPEND)) 344*10696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 345*10696SDavid.Hollister@Sun.COM 346*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 347*10696SDavid.Hollister@Sun.COM if (!(addrid = ddi_strid_str2id(mapp->dam_addr_hash, address))) { 348*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 349*10696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 350*10696SDavid.Hollister@Sun.COM } 351*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 352*10696SDavid.Hollister@Sun.COM ASSERT(passp); 353*10696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, addrid)) { 354*10696SDavid.Hollister@Sun.COM DAM_INCR_STAT(mapp, dam_rereport); 355*10696SDavid.Hollister@Sun.COM dam_release_report(mapp, addrid); 356*10696SDavid.Hollister@Sun.COM passp->da_jitter++; 357*10696SDavid.Hollister@Sun.COM } 358*10696SDavid.Hollister@Sun.COM dam_add_report(mapp, passp, addrid, RPT_ADDR_DEL); 359*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 360*10696SDavid.Hollister@Sun.COM DTRACE_PROBE3(damap__addr__del__exit, dam_t *, mapp, 361*10696SDavid.Hollister@Sun.COM char *, address, int, addrid); 362*10696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 363*10696SDavid.Hollister@Sun.COM } 364*10696SDavid.Hollister@Sun.COM 365*10696SDavid.Hollister@Sun.COM /* 366*10696SDavid.Hollister@Sun.COM * Initiate full-set report 367*10696SDavid.Hollister@Sun.COM * 368*10696SDavid.Hollister@Sun.COM * damapp: address map 369*10696SDavid.Hollister@Sun.COM * 370*10696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 371*10696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 372*10696SDavid.Hollister@Sun.COM */ 373*10696SDavid.Hollister@Sun.COM int 374*10696SDavid.Hollister@Sun.COM damap_addrset_begin(damap_t *damapp) 375*10696SDavid.Hollister@Sun.COM { 376*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 377*10696SDavid.Hollister@Sun.COM int i; 378*10696SDavid.Hollister@Sun.COM 379*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__addrset__begin__entry, dam_t *, mapp); 380*10696SDavid.Hollister@Sun.COM 381*10696SDavid.Hollister@Sun.COM if ((mapp->dam_rptmode != DAMAP_REPORT_FULLSET) || 382*10696SDavid.Hollister@Sun.COM (mapp->dam_flags & DAM_DESTROYPEND)) 383*10696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 384*10696SDavid.Hollister@Sun.COM 385*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 386*10696SDavid.Hollister@Sun.COM /* 387*10696SDavid.Hollister@Sun.COM * reset any pending reports 388*10696SDavid.Hollister@Sun.COM */ 389*10696SDavid.Hollister@Sun.COM if (mapp->dam_flags & DAM_SETADD) { 390*10696SDavid.Hollister@Sun.COM /* 391*10696SDavid.Hollister@Sun.COM * cancel stabilization timeout 392*10696SDavid.Hollister@Sun.COM */ 393*10696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, 0, NULL); 394*10696SDavid.Hollister@Sun.COM DAM_INCR_STAT(mapp, dam_rereport); 395*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 396*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 397*10696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 398*10696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, i)) 399*10696SDavid.Hollister@Sun.COM dam_release_report(mapp, i); 400*10696SDavid.Hollister@Sun.COM } 401*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 402*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 403*10696SDavid.Hollister@Sun.COM } 404*10696SDavid.Hollister@Sun.COM DAM_FLAG_SET(mapp, DAM_SETADD); 405*10696SDavid.Hollister@Sun.COM bitset_zero(&mapp->dam_report_set); 406*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 407*10696SDavid.Hollister@Sun.COM DTRACE_PROBE(damap__addrset__begin__exit); 408*10696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 409*10696SDavid.Hollister@Sun.COM } 410*10696SDavid.Hollister@Sun.COM 411*10696SDavid.Hollister@Sun.COM /* 412*10696SDavid.Hollister@Sun.COM * Report address to full-set report 413*10696SDavid.Hollister@Sun.COM * 414*10696SDavid.Hollister@Sun.COM * damapp: address map handle 415*10696SDavid.Hollister@Sun.COM * address: address in ascii string representation 416*10696SDavid.Hollister@Sun.COM * rindx: index if address stabilizes 417*10696SDavid.Hollister@Sun.COM * nvl: optional nvlist of configuration-private data 418*10696SDavid.Hollister@Sun.COM * addr_priv: optional provider-private data (passed to activate/release cb) 419*10696SDavid.Hollister@Sun.COM * 420*10696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 421*10696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 422*10696SDavid.Hollister@Sun.COM * DAM_MAPFULL address map exhausted 423*10696SDavid.Hollister@Sun.COM * DAM_FAILURE General failure 424*10696SDavid.Hollister@Sun.COM */ 425*10696SDavid.Hollister@Sun.COM int 426*10696SDavid.Hollister@Sun.COM damap_addrset_add(damap_t *damapp, char *address, damap_id_t *ridx, 427*10696SDavid.Hollister@Sun.COM nvlist_t *nvl, void *addr_priv) 428*10696SDavid.Hollister@Sun.COM { 429*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 430*10696SDavid.Hollister@Sun.COM id_t addrid; 431*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 432*10696SDavid.Hollister@Sun.COM 433*10696SDavid.Hollister@Sun.COM DTRACE_PROBE2(damap__addrset__add__entry, dam_t *, mapp, 434*10696SDavid.Hollister@Sun.COM char *, address); 435*10696SDavid.Hollister@Sun.COM 436*10696SDavid.Hollister@Sun.COM if (!mapp || !address || (mapp->dam_rptmode != DAMAP_REPORT_FULLSET) || 437*10696SDavid.Hollister@Sun.COM (mapp->dam_flags & DAM_DESTROYPEND)) 438*10696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 439*10696SDavid.Hollister@Sun.COM 440*10696SDavid.Hollister@Sun.COM if (!(mapp->dam_flags & DAM_SETADD)) 441*10696SDavid.Hollister@Sun.COM return (DAM_FAILURE); 442*10696SDavid.Hollister@Sun.COM 443*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 444*10696SDavid.Hollister@Sun.COM if ((addrid = dam_get_addrid(mapp, address)) == 0) { 445*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 446*10696SDavid.Hollister@Sun.COM return (DAM_MAPFULL); 447*10696SDavid.Hollister@Sun.COM } 448*10696SDavid.Hollister@Sun.COM 449*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 450*10696SDavid.Hollister@Sun.COM ASSERT(passp); 451*10696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, addrid)) { 452*10696SDavid.Hollister@Sun.COM dam_release_report(mapp, addrid); 453*10696SDavid.Hollister@Sun.COM passp->da_jitter++; 454*10696SDavid.Hollister@Sun.COM } 455*10696SDavid.Hollister@Sun.COM passp->da_ppriv_rpt = addr_priv; 456*10696SDavid.Hollister@Sun.COM if (nvl) 457*10696SDavid.Hollister@Sun.COM (void) nvlist_dup(nvl, &passp->da_nvl_rpt, KM_SLEEP); 458*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 459*10696SDavid.Hollister@Sun.COM bitset_add(&mapp->dam_report_set, addrid); 460*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 461*10696SDavid.Hollister@Sun.COM if (ridx) 462*10696SDavid.Hollister@Sun.COM *ridx = (damap_id_t)addrid; 463*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 464*10696SDavid.Hollister@Sun.COM DTRACE_PROBE3(damap__addr__addset__exit, dam_t *, mapp, char *, 465*10696SDavid.Hollister@Sun.COM address, int, addrid); 466*10696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 467*10696SDavid.Hollister@Sun.COM } 468*10696SDavid.Hollister@Sun.COM 469*10696SDavid.Hollister@Sun.COM /* 470*10696SDavid.Hollister@Sun.COM * Commit full-set report for stabilization 471*10696SDavid.Hollister@Sun.COM * 472*10696SDavid.Hollister@Sun.COM * damapp: address map handle 473*10696SDavid.Hollister@Sun.COM * flags: (currently 0) 474*10696SDavid.Hollister@Sun.COM * 475*10696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 476*10696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 477*10696SDavid.Hollister@Sun.COM * DAM_FAILURE General failure 478*10696SDavid.Hollister@Sun.COM */ 479*10696SDavid.Hollister@Sun.COM int 480*10696SDavid.Hollister@Sun.COM damap_addrset_end(damap_t *damapp, int flags) 481*10696SDavid.Hollister@Sun.COM { 482*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 483*10696SDavid.Hollister@Sun.COM int i; 484*10696SDavid.Hollister@Sun.COM 485*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__addrset__end__entry, dam_t *, mapp); 486*10696SDavid.Hollister@Sun.COM 487*10696SDavid.Hollister@Sun.COM if (!mapp || (mapp->dam_rptmode != DAMAP_REPORT_FULLSET) || 488*10696SDavid.Hollister@Sun.COM (mapp->dam_flags & DAM_DESTROYPEND)) 489*10696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 490*10696SDavid.Hollister@Sun.COM 491*10696SDavid.Hollister@Sun.COM if (!(mapp->dam_flags & DAM_SETADD)) 492*10696SDavid.Hollister@Sun.COM return (DAM_FAILURE); 493*10696SDavid.Hollister@Sun.COM 494*10696SDavid.Hollister@Sun.COM if (flags & DAMAP_RESET) { 495*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 496*10696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, 0, NULL); 497*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 498*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 499*10696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) 500*10696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, i)) 501*10696SDavid.Hollister@Sun.COM dam_release_report(mapp, i); 502*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 503*10696SDavid.Hollister@Sun.COM } else { 504*10696SDavid.Hollister@Sun.COM mapp->dam_last_update = gethrtime(); 505*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 506*10696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, mapp->dam_stabletmo, dam_set_stable_cb); 507*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 508*10696SDavid.Hollister@Sun.COM } 509*10696SDavid.Hollister@Sun.COM DTRACE_PROBE(damap__addrset__end__exit); 510*10696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 511*10696SDavid.Hollister@Sun.COM } 512*10696SDavid.Hollister@Sun.COM 513*10696SDavid.Hollister@Sun.COM /* 514*10696SDavid.Hollister@Sun.COM * Return nvlist registered with reported address 515*10696SDavid.Hollister@Sun.COM * 516*10696SDavid.Hollister@Sun.COM * damapp: address map handle 517*10696SDavid.Hollister@Sun.COM * aid: address ID 518*10696SDavid.Hollister@Sun.COM * 519*10696SDavid.Hollister@Sun.COM * Returns: nvlist_t * provider supplied via damap_addr{set}_add()) 520*10696SDavid.Hollister@Sun.COM * NULL 521*10696SDavid.Hollister@Sun.COM */ 522*10696SDavid.Hollister@Sun.COM nvlist_t * 523*10696SDavid.Hollister@Sun.COM damap_id2nvlist(damap_t *damapp, damap_id_t addrid) 524*10696SDavid.Hollister@Sun.COM { 525*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 526*10696SDavid.Hollister@Sun.COM id_t aid = (id_t)addrid; 527*10696SDavid.Hollister@Sun.COM dam_da_t *pass; 528*10696SDavid.Hollister@Sun.COM 529*10696SDavid.Hollister@Sun.COM if (ddi_strid_id2str(mapp->dam_addr_hash, aid)) { 530*10696SDavid.Hollister@Sun.COM if (pass = ddi_get_soft_state(mapp->dam_da, aid)) 531*10696SDavid.Hollister@Sun.COM return (pass->da_nvl); 532*10696SDavid.Hollister@Sun.COM } 533*10696SDavid.Hollister@Sun.COM return (NULL); 534*10696SDavid.Hollister@Sun.COM } 535*10696SDavid.Hollister@Sun.COM 536*10696SDavid.Hollister@Sun.COM /* 537*10696SDavid.Hollister@Sun.COM * Return address string 538*10696SDavid.Hollister@Sun.COM * 539*10696SDavid.Hollister@Sun.COM * damapp: address map handle 540*10696SDavid.Hollister@Sun.COM * aid: address ID 541*10696SDavid.Hollister@Sun.COM * 542*10696SDavid.Hollister@Sun.COM * Returns: char * Address string 543*10696SDavid.Hollister@Sun.COM * NULL 544*10696SDavid.Hollister@Sun.COM */ 545*10696SDavid.Hollister@Sun.COM char * 546*10696SDavid.Hollister@Sun.COM damap_id2addr(damap_t *damapp, damap_id_t aid) 547*10696SDavid.Hollister@Sun.COM { 548*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 549*10696SDavid.Hollister@Sun.COM 550*10696SDavid.Hollister@Sun.COM return (ddi_strid_id2str(mapp->dam_addr_hash, (id_t)aid)); 551*10696SDavid.Hollister@Sun.COM } 552*10696SDavid.Hollister@Sun.COM 553*10696SDavid.Hollister@Sun.COM /* 554*10696SDavid.Hollister@Sun.COM * Hold address reference in map 555*10696SDavid.Hollister@Sun.COM * 556*10696SDavid.Hollister@Sun.COM * damapp: address map handle 557*10696SDavid.Hollister@Sun.COM * aid: address ID 558*10696SDavid.Hollister@Sun.COM * 559*10696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 560*10696SDavid.Hollister@Sun.COM * DAM_FAILURE 561*10696SDavid.Hollister@Sun.COM */ 562*10696SDavid.Hollister@Sun.COM int 563*10696SDavid.Hollister@Sun.COM damap_id_hold(damap_t *damapp, damap_id_t aid) 564*10696SDavid.Hollister@Sun.COM { 565*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 566*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 567*10696SDavid.Hollister@Sun.COM 568*10696SDavid.Hollister@Sun.COM 569*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 570*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, (id_t)aid); 571*10696SDavid.Hollister@Sun.COM if (!passp) { 572*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 573*10696SDavid.Hollister@Sun.COM return (DAM_FAILURE); 574*10696SDavid.Hollister@Sun.COM } 575*10696SDavid.Hollister@Sun.COM passp->da_ref++; 576*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 577*10696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 578*10696SDavid.Hollister@Sun.COM } 579*10696SDavid.Hollister@Sun.COM 580*10696SDavid.Hollister@Sun.COM /* 581*10696SDavid.Hollister@Sun.COM * Release address reference in map 582*10696SDavid.Hollister@Sun.COM * 583*10696SDavid.Hollister@Sun.COM * damapp: address map handle 584*10696SDavid.Hollister@Sun.COM * aid: address ID 585*10696SDavid.Hollister@Sun.COM */ 586*10696SDavid.Hollister@Sun.COM void 587*10696SDavid.Hollister@Sun.COM damap_id_rele(damap_t *damapp, damap_id_t addrid) 588*10696SDavid.Hollister@Sun.COM { 589*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 590*10696SDavid.Hollister@Sun.COM 591*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 592*10696SDavid.Hollister@Sun.COM dam_release(mapp, (id_t)addrid); 593*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 594*10696SDavid.Hollister@Sun.COM } 595*10696SDavid.Hollister@Sun.COM 596*10696SDavid.Hollister@Sun.COM /* 597*10696SDavid.Hollister@Sun.COM * Return current reference count on address reference in map 598*10696SDavid.Hollister@Sun.COM * 599*10696SDavid.Hollister@Sun.COM * damapp: address map handle 600*10696SDavid.Hollister@Sun.COM * aid: address ID 601*10696SDavid.Hollister@Sun.COM * 602*10696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 603*10696SDavid.Hollister@Sun.COM * DAM_FAILURE 604*10696SDavid.Hollister@Sun.COM */ 605*10696SDavid.Hollister@Sun.COM int 606*10696SDavid.Hollister@Sun.COM damap_id_ref(damap_t *damapp, damap_id_t aid) 607*10696SDavid.Hollister@Sun.COM { 608*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 609*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 610*10696SDavid.Hollister@Sun.COM int ref = -1; 611*10696SDavid.Hollister@Sun.COM 612*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 613*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, (id_t)aid); 614*10696SDavid.Hollister@Sun.COM if (passp) 615*10696SDavid.Hollister@Sun.COM ref = passp->da_ref; 616*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 617*10696SDavid.Hollister@Sun.COM return (ref); 618*10696SDavid.Hollister@Sun.COM } 619*10696SDavid.Hollister@Sun.COM 620*10696SDavid.Hollister@Sun.COM /* 621*10696SDavid.Hollister@Sun.COM * Return next address ID in list 622*10696SDavid.Hollister@Sun.COM * 623*10696SDavid.Hollister@Sun.COM * damapp: address map handle 624*10696SDavid.Hollister@Sun.COM * damap_list: address ID list passed to config|unconfig 625*10696SDavid.Hollister@Sun.COM * returned by look by lookup_all 626*10696SDavid.Hollister@Sun.COM * last: last ID returned, 0 is start of list 627*10696SDavid.Hollister@Sun.COM * 628*10696SDavid.Hollister@Sun.COM * Returns: addrid Next ID from the list 629*10696SDavid.Hollister@Sun.COM * 0 End of the list 630*10696SDavid.Hollister@Sun.COM */ 631*10696SDavid.Hollister@Sun.COM damap_id_t 632*10696SDavid.Hollister@Sun.COM damap_id_next(damap_t *damapp, damap_id_list_t damap_list, damap_id_t last) 633*10696SDavid.Hollister@Sun.COM { 634*10696SDavid.Hollister@Sun.COM int i, start; 635*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 636*10696SDavid.Hollister@Sun.COM bitset_t *dam_list = (bitset_t *)damap_list; 637*10696SDavid.Hollister@Sun.COM 638*10696SDavid.Hollister@Sun.COM if (!mapp || !dam_list) 639*10696SDavid.Hollister@Sun.COM return ((damap_id_t)0); 640*10696SDavid.Hollister@Sun.COM 641*10696SDavid.Hollister@Sun.COM start = (int)last + 1; 642*10696SDavid.Hollister@Sun.COM for (i = start; i < mapp->dam_high; i++) 643*10696SDavid.Hollister@Sun.COM if (bitset_in_set(dam_list, i)) 644*10696SDavid.Hollister@Sun.COM return ((damap_id_t)i); 645*10696SDavid.Hollister@Sun.COM return ((damap_id_t)0); 646*10696SDavid.Hollister@Sun.COM } 647*10696SDavid.Hollister@Sun.COM 648*10696SDavid.Hollister@Sun.COM /* 649*10696SDavid.Hollister@Sun.COM * Set config private data 650*10696SDavid.Hollister@Sun.COM * 651*10696SDavid.Hollister@Sun.COM * damapp: address map handle 652*10696SDavid.Hollister@Sun.COM * aid: address ID 653*10696SDavid.Hollister@Sun.COM * cfg_priv: configuration private data 654*10696SDavid.Hollister@Sun.COM * 655*10696SDavid.Hollister@Sun.COM */ 656*10696SDavid.Hollister@Sun.COM void 657*10696SDavid.Hollister@Sun.COM damap_id_priv_set(damap_t *damapp, damap_id_t aid, void *cfg_priv) 658*10696SDavid.Hollister@Sun.COM { 659*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 660*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 661*10696SDavid.Hollister@Sun.COM 662*10696SDavid.Hollister@Sun.COM 663*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 664*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, (id_t)aid); 665*10696SDavid.Hollister@Sun.COM if (!passp) { 666*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 667*10696SDavid.Hollister@Sun.COM return; 668*10696SDavid.Hollister@Sun.COM } 669*10696SDavid.Hollister@Sun.COM passp->da_cfg_priv = cfg_priv; 670*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 671*10696SDavid.Hollister@Sun.COM } 672*10696SDavid.Hollister@Sun.COM 673*10696SDavid.Hollister@Sun.COM /* 674*10696SDavid.Hollister@Sun.COM * Get config private data 675*10696SDavid.Hollister@Sun.COM * 676*10696SDavid.Hollister@Sun.COM * damapp: address map handle 677*10696SDavid.Hollister@Sun.COM * aid: address ID 678*10696SDavid.Hollister@Sun.COM * 679*10696SDavid.Hollister@Sun.COM * Returns: configuration private data 680*10696SDavid.Hollister@Sun.COM */ 681*10696SDavid.Hollister@Sun.COM void * 682*10696SDavid.Hollister@Sun.COM damap_id_priv_get(damap_t *damapp, damap_id_t aid) 683*10696SDavid.Hollister@Sun.COM { 684*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 685*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 686*10696SDavid.Hollister@Sun.COM void *rv; 687*10696SDavid.Hollister@Sun.COM 688*10696SDavid.Hollister@Sun.COM 689*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 690*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, (id_t)aid); 691*10696SDavid.Hollister@Sun.COM if (!passp) { 692*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 693*10696SDavid.Hollister@Sun.COM return (NULL); 694*10696SDavid.Hollister@Sun.COM } 695*10696SDavid.Hollister@Sun.COM rv = passp->da_cfg_priv; 696*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 697*10696SDavid.Hollister@Sun.COM return (rv); 698*10696SDavid.Hollister@Sun.COM } 699*10696SDavid.Hollister@Sun.COM 700*10696SDavid.Hollister@Sun.COM /* 701*10696SDavid.Hollister@Sun.COM * Lookup a single address in the active address map 702*10696SDavid.Hollister@Sun.COM * 703*10696SDavid.Hollister@Sun.COM * damapp: address map handle 704*10696SDavid.Hollister@Sun.COM * address: address string 705*10696SDavid.Hollister@Sun.COM * 706*10696SDavid.Hollister@Sun.COM * Returns: ID of active/stable address 707*10696SDavid.Hollister@Sun.COM * 0 Address not in stable set 708*10696SDavid.Hollister@Sun.COM * 709*10696SDavid.Hollister@Sun.COM * Future: Allow the caller to wait for stabilize before returning not found. 710*10696SDavid.Hollister@Sun.COM */ 711*10696SDavid.Hollister@Sun.COM damap_id_t 712*10696SDavid.Hollister@Sun.COM damap_lookup(damap_t *damapp, char *address) 713*10696SDavid.Hollister@Sun.COM { 714*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 715*10696SDavid.Hollister@Sun.COM id_t addrid = 0; 716*10696SDavid.Hollister@Sun.COM dam_da_t *passp = NULL; 717*10696SDavid.Hollister@Sun.COM 718*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 719*10696SDavid.Hollister@Sun.COM addrid = ddi_strid_str2id(mapp->dam_addr_hash, address); 720*10696SDavid.Hollister@Sun.COM if (addrid) { 721*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 722*10696SDavid.Hollister@Sun.COM if (DAM_IS_STABLE(mapp, addrid)) { 723*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 724*10696SDavid.Hollister@Sun.COM ASSERT(passp); 725*10696SDavid.Hollister@Sun.COM if (passp) { 726*10696SDavid.Hollister@Sun.COM passp->da_ref++; 727*10696SDavid.Hollister@Sun.COM } else { 728*10696SDavid.Hollister@Sun.COM addrid = 0; 729*10696SDavid.Hollister@Sun.COM } 730*10696SDavid.Hollister@Sun.COM } else { 731*10696SDavid.Hollister@Sun.COM addrid = 0; 732*10696SDavid.Hollister@Sun.COM } 733*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 734*10696SDavid.Hollister@Sun.COM } 735*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 736*10696SDavid.Hollister@Sun.COM return ((damap_id_t)addrid); 737*10696SDavid.Hollister@Sun.COM } 738*10696SDavid.Hollister@Sun.COM 739*10696SDavid.Hollister@Sun.COM 740*10696SDavid.Hollister@Sun.COM /* 741*10696SDavid.Hollister@Sun.COM * Return the list of stable addresses in the map 742*10696SDavid.Hollister@Sun.COM * 743*10696SDavid.Hollister@Sun.COM * damapp: address map handle 744*10696SDavid.Hollister@Sun.COM * id_listp: pointer to list of address IDs in stable map (returned) 745*10696SDavid.Hollister@Sun.COM * 746*10696SDavid.Hollister@Sun.COM * Returns: # of entries returned in alist 747*10696SDavid.Hollister@Sun.COM */ 748*10696SDavid.Hollister@Sun.COM int 749*10696SDavid.Hollister@Sun.COM damap_lookup_all(damap_t *damapp, damap_id_list_t *id_listp) 750*10696SDavid.Hollister@Sun.COM { 751*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 752*10696SDavid.Hollister@Sun.COM int mapsz = mapp->dam_size; 753*10696SDavid.Hollister@Sun.COM int n_ids, i; 754*10696SDavid.Hollister@Sun.COM bitset_t *bsp; 755*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 756*10696SDavid.Hollister@Sun.COM 757*10696SDavid.Hollister@Sun.COM bsp = kmem_alloc(sizeof (*bsp), KM_SLEEP); 758*10696SDavid.Hollister@Sun.COM bitset_init(bsp); 759*10696SDavid.Hollister@Sun.COM bitset_resize(bsp, mapsz); 760*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 761*10696SDavid.Hollister@Sun.COM bitset_copy(&mapp->dam_active_set, bsp); 762*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 763*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 764*10696SDavid.Hollister@Sun.COM for (n_ids = 0, i = 1; i < mapsz; i++) { 765*10696SDavid.Hollister@Sun.COM if (bitset_in_set(bsp, i)) { 766*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, i); 767*10696SDavid.Hollister@Sun.COM ASSERT(passp); 768*10696SDavid.Hollister@Sun.COM if (passp) { 769*10696SDavid.Hollister@Sun.COM passp->da_ref++; 770*10696SDavid.Hollister@Sun.COM n_ids++; 771*10696SDavid.Hollister@Sun.COM } 772*10696SDavid.Hollister@Sun.COM } 773*10696SDavid.Hollister@Sun.COM } 774*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 775*10696SDavid.Hollister@Sun.COM if (n_ids) { 776*10696SDavid.Hollister@Sun.COM *id_listp = (damap_id_list_t)bsp; 777*10696SDavid.Hollister@Sun.COM return (n_ids); 778*10696SDavid.Hollister@Sun.COM } else { 779*10696SDavid.Hollister@Sun.COM *id_listp = (damap_id_list_t)NULL; 780*10696SDavid.Hollister@Sun.COM bitset_fini(bsp); 781*10696SDavid.Hollister@Sun.COM kmem_free(bsp, sizeof (*bsp)); 782*10696SDavid.Hollister@Sun.COM return (0); 783*10696SDavid.Hollister@Sun.COM } 784*10696SDavid.Hollister@Sun.COM } 785*10696SDavid.Hollister@Sun.COM 786*10696SDavid.Hollister@Sun.COM /* 787*10696SDavid.Hollister@Sun.COM * Release the address list returned by damap_lookup_all() 788*10696SDavid.Hollister@Sun.COM * 789*10696SDavid.Hollister@Sun.COM * mapp: address map handle 790*10696SDavid.Hollister@Sun.COM * id_list: list of address IDs returned in damap_lookup_all() 791*10696SDavid.Hollister@Sun.COM */ 792*10696SDavid.Hollister@Sun.COM void 793*10696SDavid.Hollister@Sun.COM damap_id_list_rele(damap_t *damapp, damap_id_list_t id_list) 794*10696SDavid.Hollister@Sun.COM { 795*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 796*10696SDavid.Hollister@Sun.COM int i; 797*10696SDavid.Hollister@Sun.COM 798*10696SDavid.Hollister@Sun.COM if (id_list == NULL) 799*10696SDavid.Hollister@Sun.COM return; 800*10696SDavid.Hollister@Sun.COM 801*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 802*10696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 803*10696SDavid.Hollister@Sun.COM if (bitset_in_set((bitset_t *)id_list, i)) 804*10696SDavid.Hollister@Sun.COM (void) dam_release(mapp, i); 805*10696SDavid.Hollister@Sun.COM } 806*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 807*10696SDavid.Hollister@Sun.COM bitset_fini((bitset_t *)id_list); 808*10696SDavid.Hollister@Sun.COM kmem_free((void *)id_list, sizeof (bitset_t)); 809*10696SDavid.Hollister@Sun.COM } 810*10696SDavid.Hollister@Sun.COM 811*10696SDavid.Hollister@Sun.COM /* 812*10696SDavid.Hollister@Sun.COM * Activate a set of stabilized addresses 813*10696SDavid.Hollister@Sun.COM */ 814*10696SDavid.Hollister@Sun.COM static void 815*10696SDavid.Hollister@Sun.COM dam_addrset_activate(dam_t *mapp, bitset_t *active_set) 816*10696SDavid.Hollister@Sun.COM { 817*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 818*10696SDavid.Hollister@Sun.COM char *addrstr; 819*10696SDavid.Hollister@Sun.COM int i; 820*10696SDavid.Hollister@Sun.COM uint32_t n_active = 0; 821*10696SDavid.Hollister@Sun.COM 822*10696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 823*10696SDavid.Hollister@Sun.COM if (bitset_in_set(&mapp->dam_active_set, i)) 824*10696SDavid.Hollister@Sun.COM n_active++; 825*10696SDavid.Hollister@Sun.COM if (!bitset_in_set(active_set, i)) 826*10696SDavid.Hollister@Sun.COM continue; 827*10696SDavid.Hollister@Sun.COM n_active++; 828*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, i); 829*10696SDavid.Hollister@Sun.COM ASSERT(passp); 830*10696SDavid.Hollister@Sun.COM if (mapp->dam_activate_cb) { 831*10696SDavid.Hollister@Sun.COM addrstr = ddi_strid_id2str(mapp->dam_addr_hash, i); 832*10696SDavid.Hollister@Sun.COM (*mapp->dam_activate_cb)( 833*10696SDavid.Hollister@Sun.COM mapp->dam_activate_arg, addrstr, i, 834*10696SDavid.Hollister@Sun.COM &passp->da_ppriv_rpt); 835*10696SDavid.Hollister@Sun.COM } 836*10696SDavid.Hollister@Sun.COM DTRACE_PROBE2(damap__addrset__activate, dam_t *, mapp, int, i); 837*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 838*10696SDavid.Hollister@Sun.COM bitset_add(&mapp->dam_active_set, i); 839*10696SDavid.Hollister@Sun.COM /* 840*10696SDavid.Hollister@Sun.COM * copy the reported nvlist and provider private data 841*10696SDavid.Hollister@Sun.COM */ 842*10696SDavid.Hollister@Sun.COM passp->da_nvl = passp->da_nvl_rpt; 843*10696SDavid.Hollister@Sun.COM passp->da_ppriv = passp->da_ppriv_rpt; 844*10696SDavid.Hollister@Sun.COM passp->da_ppriv_rpt = NULL; 845*10696SDavid.Hollister@Sun.COM passp->da_nvl_rpt = NULL; 846*10696SDavid.Hollister@Sun.COM passp->da_last_stable = gethrtime(); 847*10696SDavid.Hollister@Sun.COM passp->da_stable_cnt++; 848*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 849*10696SDavid.Hollister@Sun.COM DAM_SET_STAT(mapp, dam_numstable, n_active); 850*10696SDavid.Hollister@Sun.COM } 851*10696SDavid.Hollister@Sun.COM } 852*10696SDavid.Hollister@Sun.COM 853*10696SDavid.Hollister@Sun.COM /* 854*10696SDavid.Hollister@Sun.COM * Release a set of stabilized addresses 855*10696SDavid.Hollister@Sun.COM */ 856*10696SDavid.Hollister@Sun.COM static void 857*10696SDavid.Hollister@Sun.COM dam_addrset_release(dam_t *mapp, bitset_t *release_set) 858*10696SDavid.Hollister@Sun.COM { 859*10696SDavid.Hollister@Sun.COM int i; 860*10696SDavid.Hollister@Sun.COM 861*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 862*10696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 863*10696SDavid.Hollister@Sun.COM if (bitset_in_set(release_set, i)) { 864*10696SDavid.Hollister@Sun.COM DTRACE_PROBE2(damap__addrset__release, dam_t *, mapp, 865*10696SDavid.Hollister@Sun.COM int, i); 866*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 867*10696SDavid.Hollister@Sun.COM bitset_del(&mapp->dam_active_set, i); 868*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 869*10696SDavid.Hollister@Sun.COM (void) dam_release(mapp, i); 870*10696SDavid.Hollister@Sun.COM } 871*10696SDavid.Hollister@Sun.COM } 872*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 873*10696SDavid.Hollister@Sun.COM } 874*10696SDavid.Hollister@Sun.COM 875*10696SDavid.Hollister@Sun.COM /* 876*10696SDavid.Hollister@Sun.COM * release a previously activated address 877*10696SDavid.Hollister@Sun.COM */ 878*10696SDavid.Hollister@Sun.COM static void 879*10696SDavid.Hollister@Sun.COM dam_release(dam_t *mapp, id_t addrid) 880*10696SDavid.Hollister@Sun.COM { 881*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 882*10696SDavid.Hollister@Sun.COM 883*10696SDavid.Hollister@Sun.COM DAM_ASSERT_LOCKED(mapp, ADDR_LOCK); 884*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 885*10696SDavid.Hollister@Sun.COM ASSERT(passp); 886*10696SDavid.Hollister@Sun.COM 887*10696SDavid.Hollister@Sun.COM /* 888*10696SDavid.Hollister@Sun.COM * invoke the deactivation callback to notify 889*10696SDavid.Hollister@Sun.COM * this address is no longer active 890*10696SDavid.Hollister@Sun.COM */ 891*10696SDavid.Hollister@Sun.COM dam_deactivate_addr(mapp, addrid); 892*10696SDavid.Hollister@Sun.COM 893*10696SDavid.Hollister@Sun.COM /* 894*10696SDavid.Hollister@Sun.COM * allow pending reports for this address to stabilize 895*10696SDavid.Hollister@Sun.COM */ 896*10696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, addrid)) 897*10696SDavid.Hollister@Sun.COM return; 898*10696SDavid.Hollister@Sun.COM 899*10696SDavid.Hollister@Sun.COM /* 900*10696SDavid.Hollister@Sun.COM * defer teardown until outstanding references are released 901*10696SDavid.Hollister@Sun.COM */ 902*10696SDavid.Hollister@Sun.COM if (--passp->da_ref) { 903*10696SDavid.Hollister@Sun.COM passp->da_flags |= DA_RELE; 904*10696SDavid.Hollister@Sun.COM return; 905*10696SDavid.Hollister@Sun.COM } 906*10696SDavid.Hollister@Sun.COM ddi_strid_free(mapp->dam_addr_hash, addrid); 907*10696SDavid.Hollister@Sun.COM ddi_soft_state_free(mapp->dam_da, addrid); 908*10696SDavid.Hollister@Sun.COM } 909*10696SDavid.Hollister@Sun.COM 910*10696SDavid.Hollister@Sun.COM /* 911*10696SDavid.Hollister@Sun.COM * process stabilized address reports 912*10696SDavid.Hollister@Sun.COM */ 913*10696SDavid.Hollister@Sun.COM static void 914*10696SDavid.Hollister@Sun.COM dam_activate_taskq(void *arg) 915*10696SDavid.Hollister@Sun.COM { 916*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)arg; 917*10696SDavid.Hollister@Sun.COM bitset_t delta; 918*10696SDavid.Hollister@Sun.COM bitset_t cfg; 919*10696SDavid.Hollister@Sun.COM bitset_t uncfg; 920*10696SDavid.Hollister@Sun.COM int has_cfg, has_uncfg; 921*10696SDavid.Hollister@Sun.COM 922*10696SDavid.Hollister@Sun.COM bitset_init(&delta); 923*10696SDavid.Hollister@Sun.COM bitset_resize(&delta, mapp->dam_size); 924*10696SDavid.Hollister@Sun.COM bitset_init(&cfg); 925*10696SDavid.Hollister@Sun.COM bitset_resize(&cfg, mapp->dam_size); 926*10696SDavid.Hollister@Sun.COM bitset_init(&uncfg); 927*10696SDavid.Hollister@Sun.COM bitset_resize(&uncfg, mapp->dam_size); 928*10696SDavid.Hollister@Sun.COM 929*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__activate__taskq__entry, dam_t, mapp); 930*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 931*10696SDavid.Hollister@Sun.COM if (!bitset_xor(&mapp->dam_active_set, &mapp->dam_stable_set, 932*10696SDavid.Hollister@Sun.COM &delta)) { 933*10696SDavid.Hollister@Sun.COM bitset_zero(&mapp->dam_stable_set); 934*10696SDavid.Hollister@Sun.COM DAM_FLAG_CLR(mapp, DAM_SPEND); 935*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 936*10696SDavid.Hollister@Sun.COM bitset_fini(&uncfg); 937*10696SDavid.Hollister@Sun.COM bitset_fini(&cfg); 938*10696SDavid.Hollister@Sun.COM bitset_fini(&delta); 939*10696SDavid.Hollister@Sun.COM return; 940*10696SDavid.Hollister@Sun.COM } 941*10696SDavid.Hollister@Sun.COM has_cfg = bitset_and(&delta, &mapp->dam_stable_set, &cfg); 942*10696SDavid.Hollister@Sun.COM has_uncfg = bitset_and(&delta, &mapp->dam_active_set, &uncfg); 943*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 944*10696SDavid.Hollister@Sun.COM if (has_cfg) { 945*10696SDavid.Hollister@Sun.COM dam_addrset_activate(mapp, &cfg); 946*10696SDavid.Hollister@Sun.COM (*mapp->dam_configure_cb)(mapp->dam_config_arg, mapp, &cfg); 947*10696SDavid.Hollister@Sun.COM } 948*10696SDavid.Hollister@Sun.COM if (has_uncfg) { 949*10696SDavid.Hollister@Sun.COM (*mapp->dam_unconfig_cb)(mapp->dam_config_arg, mapp, &uncfg); 950*10696SDavid.Hollister@Sun.COM dam_addrset_release(mapp, &uncfg); 951*10696SDavid.Hollister@Sun.COM } 952*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 953*10696SDavid.Hollister@Sun.COM bitset_zero(&mapp->dam_stable_set); 954*10696SDavid.Hollister@Sun.COM DAM_FLAG_CLR(mapp, DAM_SPEND); 955*10696SDavid.Hollister@Sun.COM mapp->dam_last_stable = gethrtime(); 956*10696SDavid.Hollister@Sun.COM mapp->dam_stable_cnt++; 957*10696SDavid.Hollister@Sun.COM DAM_INCR_STAT(mapp, dam_stable); 958*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 959*10696SDavid.Hollister@Sun.COM bitset_fini(&uncfg); 960*10696SDavid.Hollister@Sun.COM bitset_fini(&cfg); 961*10696SDavid.Hollister@Sun.COM bitset_fini(&delta); 962*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__activate__taskq__exit, dam_t, mapp); 963*10696SDavid.Hollister@Sun.COM } 964*10696SDavid.Hollister@Sun.COM 965*10696SDavid.Hollister@Sun.COM /* 966*10696SDavid.Hollister@Sun.COM * per-address stabilization timeout 967*10696SDavid.Hollister@Sun.COM */ 968*10696SDavid.Hollister@Sun.COM static void 969*10696SDavid.Hollister@Sun.COM dam_addr_stable_cb(void *arg) 970*10696SDavid.Hollister@Sun.COM { 971*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)arg; 972*10696SDavid.Hollister@Sun.COM int i; 973*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 974*10696SDavid.Hollister@Sun.COM int spend = 0; 975*10696SDavid.Hollister@Sun.COM int tpend = 0; 976*10696SDavid.Hollister@Sun.COM int64_t next_tmov = mapp->dam_stabletmo; 977*10696SDavid.Hollister@Sun.COM int64_t tmo_delta; 978*10696SDavid.Hollister@Sun.COM int64_t ts = lbolt64; 979*10696SDavid.Hollister@Sun.COM 980*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__addr__stable__cb__entry, dam_t *, mapp); 981*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 982*10696SDavid.Hollister@Sun.COM if (mapp->dam_tid == 0) { 983*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 984*10696SDavid.Hollister@Sun.COM return; 985*10696SDavid.Hollister@Sun.COM } 986*10696SDavid.Hollister@Sun.COM mapp->dam_tid = 0; 987*10696SDavid.Hollister@Sun.COM /* 988*10696SDavid.Hollister@Sun.COM * If still under stabilization, reschedule timeout, 989*10696SDavid.Hollister@Sun.COM * else dispatch the task to activate & deactivate the stable 990*10696SDavid.Hollister@Sun.COM * set. 991*10696SDavid.Hollister@Sun.COM */ 992*10696SDavid.Hollister@Sun.COM if (mapp->dam_flags & DAM_SPEND) { 993*10696SDavid.Hollister@Sun.COM DAM_INCR_STAT(mapp, dam_stable_blocked); 994*10696SDavid.Hollister@Sun.COM mapp->dam_stable_overrun++; 995*10696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, mapp->dam_stabletmo, dam_addr_stable_cb); 996*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 997*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__addr__stable__cb__overrun, 998*10696SDavid.Hollister@Sun.COM dam_t *, mapp); 999*10696SDavid.Hollister@Sun.COM return; 1000*10696SDavid.Hollister@Sun.COM } 1001*10696SDavid.Hollister@Sun.COM 1002*10696SDavid.Hollister@Sun.COM bitset_copy(&mapp->dam_active_set, &mapp->dam_stable_set); 1003*10696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 1004*10696SDavid.Hollister@Sun.COM if (!bitset_in_set(&mapp->dam_report_set, i)) 1005*10696SDavid.Hollister@Sun.COM continue; 1006*10696SDavid.Hollister@Sun.COM /* 1007*10696SDavid.Hollister@Sun.COM * Stabilize each address 1008*10696SDavid.Hollister@Sun.COM */ 1009*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, i); 1010*10696SDavid.Hollister@Sun.COM ASSERT(passp); 1011*10696SDavid.Hollister@Sun.COM if (!passp) { 1012*10696SDavid.Hollister@Sun.COM cmn_err(CE_WARN, "Clearing report no softstate %d", i); 1013*10696SDavid.Hollister@Sun.COM bitset_del(&mapp->dam_report_set, i); 1014*10696SDavid.Hollister@Sun.COM continue; 1015*10696SDavid.Hollister@Sun.COM } 1016*10696SDavid.Hollister@Sun.COM 1017*10696SDavid.Hollister@Sun.COM /* report has stabilized */ 1018*10696SDavid.Hollister@Sun.COM if (passp->da_deadline <= ts) { 1019*10696SDavid.Hollister@Sun.COM bitset_del(&mapp->dam_report_set, i); 1020*10696SDavid.Hollister@Sun.COM if (passp->da_flags & DA_RELE) { 1021*10696SDavid.Hollister@Sun.COM DTRACE_PROBE2(damap__addr__stable__del, 1022*10696SDavid.Hollister@Sun.COM dam_t *, mapp, int, i); 1023*10696SDavid.Hollister@Sun.COM bitset_del(&mapp->dam_stable_set, i); 1024*10696SDavid.Hollister@Sun.COM } else { 1025*10696SDavid.Hollister@Sun.COM DTRACE_PROBE2(damap__addr__stable__add, 1026*10696SDavid.Hollister@Sun.COM dam_t *, mapp, int, i); 1027*10696SDavid.Hollister@Sun.COM bitset_add(&mapp->dam_stable_set, i); 1028*10696SDavid.Hollister@Sun.COM } 1029*10696SDavid.Hollister@Sun.COM spend++; 1030*10696SDavid.Hollister@Sun.COM continue; 1031*10696SDavid.Hollister@Sun.COM } 1032*10696SDavid.Hollister@Sun.COM 1033*10696SDavid.Hollister@Sun.COM /* 1034*10696SDavid.Hollister@Sun.COM * not stabilized, determine next (future) map timeout 1035*10696SDavid.Hollister@Sun.COM */ 1036*10696SDavid.Hollister@Sun.COM tpend++; 1037*10696SDavid.Hollister@Sun.COM tmo_delta = passp->da_deadline - ts; 1038*10696SDavid.Hollister@Sun.COM if (tmo_delta < next_tmov) 1039*10696SDavid.Hollister@Sun.COM next_tmov = tmo_delta; 1040*10696SDavid.Hollister@Sun.COM } 1041*10696SDavid.Hollister@Sun.COM 1042*10696SDavid.Hollister@Sun.COM /* 1043*10696SDavid.Hollister@Sun.COM * schedule taskq activation of stabilized reports 1044*10696SDavid.Hollister@Sun.COM */ 1045*10696SDavid.Hollister@Sun.COM if (spend) { 1046*10696SDavid.Hollister@Sun.COM if (ddi_taskq_dispatch(mapp->dam_taskqp, dam_activate_taskq, 1047*10696SDavid.Hollister@Sun.COM mapp, DDI_NOSLEEP) == DDI_SUCCESS) { 1048*10696SDavid.Hollister@Sun.COM DAM_FLAG_SET(mapp, DAM_SPEND); 1049*10696SDavid.Hollister@Sun.COM } else 1050*10696SDavid.Hollister@Sun.COM tpend++; 1051*10696SDavid.Hollister@Sun.COM } 1052*10696SDavid.Hollister@Sun.COM 1053*10696SDavid.Hollister@Sun.COM /* 1054*10696SDavid.Hollister@Sun.COM * schedule timeout to handle future stabalization of active reports 1055*10696SDavid.Hollister@Sun.COM */ 1056*10696SDavid.Hollister@Sun.COM if (tpend) 1057*10696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, (clock_t)next_tmov, dam_addr_stable_cb); 1058*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 1059*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__addr__stable__cb__exit, dam_t *, mapp); 1060*10696SDavid.Hollister@Sun.COM } 1061*10696SDavid.Hollister@Sun.COM 1062*10696SDavid.Hollister@Sun.COM /* 1063*10696SDavid.Hollister@Sun.COM * fullset stabilization timeout 1064*10696SDavid.Hollister@Sun.COM */ 1065*10696SDavid.Hollister@Sun.COM static void 1066*10696SDavid.Hollister@Sun.COM dam_set_stable_cb(void *arg) 1067*10696SDavid.Hollister@Sun.COM { 1068*10696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)arg; 1069*10696SDavid.Hollister@Sun.COM 1070*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__set__stable__cb__enter, dam_t *, mapp); 1071*10696SDavid.Hollister@Sun.COM 1072*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 1073*10696SDavid.Hollister@Sun.COM if (mapp->dam_tid == 0) { 1074*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 1075*10696SDavid.Hollister@Sun.COM return; 1076*10696SDavid.Hollister@Sun.COM } 1077*10696SDavid.Hollister@Sun.COM mapp->dam_tid = 0; 1078*10696SDavid.Hollister@Sun.COM 1079*10696SDavid.Hollister@Sun.COM /* 1080*10696SDavid.Hollister@Sun.COM * If still under stabilization, reschedule timeout, 1081*10696SDavid.Hollister@Sun.COM * else dispatch the task to activate & deactivate the stable 1082*10696SDavid.Hollister@Sun.COM * set. 1083*10696SDavid.Hollister@Sun.COM */ 1084*10696SDavid.Hollister@Sun.COM if (mapp->dam_flags & DAM_SPEND) { 1085*10696SDavid.Hollister@Sun.COM DAM_INCR_STAT(mapp, dam_stable_blocked); 1086*10696SDavid.Hollister@Sun.COM mapp->dam_stable_overrun++; 1087*10696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, mapp->dam_stabletmo, dam_set_stable_cb); 1088*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__set__stable__cb__overrun, 1089*10696SDavid.Hollister@Sun.COM dam_t *, mapp); 1090*10696SDavid.Hollister@Sun.COM } else if (ddi_taskq_dispatch(mapp->dam_taskqp, dam_activate_taskq, 1091*10696SDavid.Hollister@Sun.COM mapp, DDI_NOSLEEP) == DDI_FAILURE) { 1092*10696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, mapp->dam_stabletmo, dam_set_stable_cb); 1093*10696SDavid.Hollister@Sun.COM } else { 1094*10696SDavid.Hollister@Sun.COM bitset_copy(&mapp->dam_report_set, &mapp->dam_stable_set); 1095*10696SDavid.Hollister@Sun.COM bitset_zero(&mapp->dam_report_set); 1096*10696SDavid.Hollister@Sun.COM DAM_FLAG_CLR(mapp, DAM_SETADD); 1097*10696SDavid.Hollister@Sun.COM DAM_FLAG_SET(mapp, DAM_SPEND); 1098*10696SDavid.Hollister@Sun.COM } 1099*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 1100*10696SDavid.Hollister@Sun.COM DTRACE_PROBE1(damap__set__stable__cb__exit, dam_t *, mapp); 1101*10696SDavid.Hollister@Sun.COM } 1102*10696SDavid.Hollister@Sun.COM 1103*10696SDavid.Hollister@Sun.COM /* 1104*10696SDavid.Hollister@Sun.COM * reschedule map timeout 'tmo_ms' ticks 1105*10696SDavid.Hollister@Sun.COM */ 1106*10696SDavid.Hollister@Sun.COM static void 1107*10696SDavid.Hollister@Sun.COM dam_sched_tmo(dam_t *mapp, clock_t tmo_ms, void (*tmo_cb)()) 1108*10696SDavid.Hollister@Sun.COM { 1109*10696SDavid.Hollister@Sun.COM timeout_id_t tid; 1110*10696SDavid.Hollister@Sun.COM 1111*10696SDavid.Hollister@Sun.COM if ((tid = mapp->dam_tid) != 0) { 1112*10696SDavid.Hollister@Sun.COM mapp->dam_tid = 0; 1113*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 1114*10696SDavid.Hollister@Sun.COM (void) untimeout(tid); 1115*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 1116*10696SDavid.Hollister@Sun.COM } 1117*10696SDavid.Hollister@Sun.COM 1118*10696SDavid.Hollister@Sun.COM if (tmo_cb && (tmo_ms != 0)) 1119*10696SDavid.Hollister@Sun.COM mapp->dam_tid = timeout(tmo_cb, mapp, tmo_ms); 1120*10696SDavid.Hollister@Sun.COM } 1121*10696SDavid.Hollister@Sun.COM 1122*10696SDavid.Hollister@Sun.COM /* 1123*10696SDavid.Hollister@Sun.COM * record report addition or removal of an address 1124*10696SDavid.Hollister@Sun.COM */ 1125*10696SDavid.Hollister@Sun.COM static void 1126*10696SDavid.Hollister@Sun.COM dam_add_report(dam_t *mapp, dam_da_t *passp, id_t addrid, int report) 1127*10696SDavid.Hollister@Sun.COM { 1128*10696SDavid.Hollister@Sun.COM ASSERT(!DAM_IN_REPORT(mapp, addrid)); 1129*10696SDavid.Hollister@Sun.COM passp->da_last_report = gethrtime(); 1130*10696SDavid.Hollister@Sun.COM mapp->dam_last_update = gethrtime(); 1131*10696SDavid.Hollister@Sun.COM passp->da_report_cnt++; 1132*10696SDavid.Hollister@Sun.COM passp->da_deadline = lbolt64 + mapp->dam_stabletmo; 1133*10696SDavid.Hollister@Sun.COM if (report == RPT_ADDR_DEL) 1134*10696SDavid.Hollister@Sun.COM passp->da_flags |= DA_RELE; 1135*10696SDavid.Hollister@Sun.COM else if (report == RPT_ADDR_ADD) 1136*10696SDavid.Hollister@Sun.COM passp->da_flags &= ~DA_RELE; 1137*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 1138*10696SDavid.Hollister@Sun.COM bitset_add(&mapp->dam_report_set, addrid); 1139*10696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, mapp->dam_stabletmo, dam_addr_stable_cb); 1140*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 1141*10696SDavid.Hollister@Sun.COM 1142*10696SDavid.Hollister@Sun.COM } 1143*10696SDavid.Hollister@Sun.COM 1144*10696SDavid.Hollister@Sun.COM /* 1145*10696SDavid.Hollister@Sun.COM * release an address report 1146*10696SDavid.Hollister@Sun.COM */ 1147*10696SDavid.Hollister@Sun.COM static void 1148*10696SDavid.Hollister@Sun.COM dam_release_report(dam_t *mapp, id_t addrid) 1149*10696SDavid.Hollister@Sun.COM { 1150*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 1151*10696SDavid.Hollister@Sun.COM 1152*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 1153*10696SDavid.Hollister@Sun.COM ASSERT(passp); 1154*10696SDavid.Hollister@Sun.COM passp->da_ppriv_rpt = NULL; 1155*10696SDavid.Hollister@Sun.COM if (passp->da_nvl_rpt) 1156*10696SDavid.Hollister@Sun.COM nvlist_free(passp->da_nvl_rpt); 1157*10696SDavid.Hollister@Sun.COM passp->da_nvl_rpt = NULL; 1158*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, MAP_LOCK); 1159*10696SDavid.Hollister@Sun.COM bitset_del(&mapp->dam_report_set, addrid); 1160*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, MAP_LOCK); 1161*10696SDavid.Hollister@Sun.COM } 1162*10696SDavid.Hollister@Sun.COM 1163*10696SDavid.Hollister@Sun.COM /* 1164*10696SDavid.Hollister@Sun.COM * deactivate a previously stable address 1165*10696SDavid.Hollister@Sun.COM */ 1166*10696SDavid.Hollister@Sun.COM static void 1167*10696SDavid.Hollister@Sun.COM dam_deactivate_addr(dam_t *mapp, id_t addrid) 1168*10696SDavid.Hollister@Sun.COM { 1169*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 1170*10696SDavid.Hollister@Sun.COM 1171*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 1172*10696SDavid.Hollister@Sun.COM ASSERT(passp); 1173*10696SDavid.Hollister@Sun.COM if (passp == NULL) 1174*10696SDavid.Hollister@Sun.COM return; 1175*10696SDavid.Hollister@Sun.COM DAM_UNLOCK(mapp, ADDR_LOCK); 1176*10696SDavid.Hollister@Sun.COM if (mapp->dam_deactivate_cb) 1177*10696SDavid.Hollister@Sun.COM (*mapp->dam_deactivate_cb)( 1178*10696SDavid.Hollister@Sun.COM mapp->dam_activate_arg, 1179*10696SDavid.Hollister@Sun.COM ddi_strid_id2str(mapp->dam_addr_hash, 1180*10696SDavid.Hollister@Sun.COM addrid), addrid, passp->da_ppriv); 1181*10696SDavid.Hollister@Sun.COM DAM_LOCK(mapp, ADDR_LOCK); 1182*10696SDavid.Hollister@Sun.COM passp->da_ppriv = NULL; 1183*10696SDavid.Hollister@Sun.COM if (passp->da_nvl) 1184*10696SDavid.Hollister@Sun.COM nvlist_free(passp->da_nvl); 1185*10696SDavid.Hollister@Sun.COM passp->da_nvl = NULL; 1186*10696SDavid.Hollister@Sun.COM } 1187*10696SDavid.Hollister@Sun.COM 1188*10696SDavid.Hollister@Sun.COM /* 1189*10696SDavid.Hollister@Sun.COM * return the map ID of an address 1190*10696SDavid.Hollister@Sun.COM */ 1191*10696SDavid.Hollister@Sun.COM static id_t 1192*10696SDavid.Hollister@Sun.COM dam_get_addrid(dam_t *mapp, char *address) 1193*10696SDavid.Hollister@Sun.COM { 1194*10696SDavid.Hollister@Sun.COM damap_id_t addrid; 1195*10696SDavid.Hollister@Sun.COM dam_da_t *passp; 1196*10696SDavid.Hollister@Sun.COM 1197*10696SDavid.Hollister@Sun.COM if ((addrid = ddi_strid_str2id(mapp->dam_addr_hash, address)) == 0) { 1198*10696SDavid.Hollister@Sun.COM if ((addrid = ddi_strid_fixed_alloc(mapp->dam_addr_hash, 1199*10696SDavid.Hollister@Sun.COM address)) == (damap_id_t)0) { 1200*10696SDavid.Hollister@Sun.COM return (0); 1201*10696SDavid.Hollister@Sun.COM } 1202*10696SDavid.Hollister@Sun.COM if (ddi_soft_state_zalloc(mapp->dam_da, addrid) != 1203*10696SDavid.Hollister@Sun.COM DDI_SUCCESS) { 1204*10696SDavid.Hollister@Sun.COM ddi_strid_free(mapp->dam_addr_hash, addrid); 1205*10696SDavid.Hollister@Sun.COM return (0); 1206*10696SDavid.Hollister@Sun.COM } 1207*10696SDavid.Hollister@Sun.COM if (addrid >= mapp->dam_high) 1208*10696SDavid.Hollister@Sun.COM mapp->dam_high = addrid + 1; 1209*10696SDavid.Hollister@Sun.COM } 1210*10696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 1211*10696SDavid.Hollister@Sun.COM if (passp == NULL) 1212*10696SDavid.Hollister@Sun.COM return (0); 1213*10696SDavid.Hollister@Sun.COM passp->da_ref++; 1214*10696SDavid.Hollister@Sun.COM if (passp->da_addr == NULL) 1215*10696SDavid.Hollister@Sun.COM passp->da_addr = ddi_strid_id2str( 1216*10696SDavid.Hollister@Sun.COM mapp->dam_addr_hash, addrid); /* for mdb */ 1217*10696SDavid.Hollister@Sun.COM return (addrid); 1218*10696SDavid.Hollister@Sun.COM } 1219*10696SDavid.Hollister@Sun.COM 1220*10696SDavid.Hollister@Sun.COM /* 1221*10696SDavid.Hollister@Sun.COM * create and install map statistics 1222*10696SDavid.Hollister@Sun.COM */ 1223*10696SDavid.Hollister@Sun.COM static int 1224*10696SDavid.Hollister@Sun.COM dam_kstat_create(dam_t *mapp) 1225*10696SDavid.Hollister@Sun.COM { 1226*10696SDavid.Hollister@Sun.COM kstat_t *mapsp; 1227*10696SDavid.Hollister@Sun.COM struct dam_kstats *statsp; 1228*10696SDavid.Hollister@Sun.COM 1229*10696SDavid.Hollister@Sun.COM mapsp = kstat_create("dam", 0, mapp->dam_name, "damap", 1230*10696SDavid.Hollister@Sun.COM KSTAT_TYPE_NAMED, 1231*10696SDavid.Hollister@Sun.COM sizeof (struct dam_kstats) / sizeof (kstat_named_t), 0); 1232*10696SDavid.Hollister@Sun.COM if (mapsp == NULL) { 1233*10696SDavid.Hollister@Sun.COM return (DDI_FAILURE); 1234*10696SDavid.Hollister@Sun.COM } 1235*10696SDavid.Hollister@Sun.COM 1236*10696SDavid.Hollister@Sun.COM statsp = (struct dam_kstats *)mapsp->ks_data; 1237*10696SDavid.Hollister@Sun.COM kstat_named_init(&statsp->dam_stable, "stable cycles", 1238*10696SDavid.Hollister@Sun.COM KSTAT_DATA_UINT32); 1239*10696SDavid.Hollister@Sun.COM kstat_named_init(&statsp->dam_stable_blocked, 1240*10696SDavid.Hollister@Sun.COM "stable cycle overrun", KSTAT_DATA_UINT32); 1241*10696SDavid.Hollister@Sun.COM kstat_named_init(&statsp->dam_rereport, 1242*10696SDavid.Hollister@Sun.COM "restarted reports", KSTAT_DATA_UINT32); 1243*10696SDavid.Hollister@Sun.COM kstat_named_init(&statsp->dam_numstable, 1244*10696SDavid.Hollister@Sun.COM "# of stable map entries", KSTAT_DATA_UINT32); 1245*10696SDavid.Hollister@Sun.COM kstat_install(mapsp); 1246*10696SDavid.Hollister@Sun.COM mapp->dam_kstatsp = mapsp; 1247*10696SDavid.Hollister@Sun.COM return (DDI_SUCCESS); 1248*10696SDavid.Hollister@Sun.COM } 1249*10696SDavid.Hollister@Sun.COM 1250*10696SDavid.Hollister@Sun.COM /* 1251*10696SDavid.Hollister@Sun.COM * destroy map stats 1252*10696SDavid.Hollister@Sun.COM */ 1253*10696SDavid.Hollister@Sun.COM static void 1254*10696SDavid.Hollister@Sun.COM dam_kstat_destroy(dam_t *mapp) 1255*10696SDavid.Hollister@Sun.COM { 1256*10696SDavid.Hollister@Sun.COM 1257*10696SDavid.Hollister@Sun.COM kstat_delete(mapp->dam_kstatsp); 1258*10696SDavid.Hollister@Sun.COM } 1259