110696SDavid.Hollister@Sun.COM /* 210696SDavid.Hollister@Sun.COM * CDDL HEADER START 310696SDavid.Hollister@Sun.COM * 410696SDavid.Hollister@Sun.COM * The contents of this file are subject to the terms of the 510696SDavid.Hollister@Sun.COM * Common Development and Distribution License (the "License"). 610696SDavid.Hollister@Sun.COM * You may not use this file except in compliance with the License. 710696SDavid.Hollister@Sun.COM * 810696SDavid.Hollister@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 910696SDavid.Hollister@Sun.COM * or http://www.opensolaris.org/os/licensing. 1010696SDavid.Hollister@Sun.COM * See the License for the specific language governing permissions 1110696SDavid.Hollister@Sun.COM * and limitations under the License. 1210696SDavid.Hollister@Sun.COM * 1310696SDavid.Hollister@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 1410696SDavid.Hollister@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1510696SDavid.Hollister@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 1610696SDavid.Hollister@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 1710696SDavid.Hollister@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 1810696SDavid.Hollister@Sun.COM * 1910696SDavid.Hollister@Sun.COM * CDDL HEADER END 2010696SDavid.Hollister@Sun.COM */ 2110696SDavid.Hollister@Sun.COM 2210696SDavid.Hollister@Sun.COM /* 2311601SDavid.Hollister@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 2410696SDavid.Hollister@Sun.COM * Use is subject to license terms. 2510696SDavid.Hollister@Sun.COM */ 2610696SDavid.Hollister@Sun.COM 2710696SDavid.Hollister@Sun.COM #include <sys/note.h> 2810696SDavid.Hollister@Sun.COM #include <sys/types.h> 2910696SDavid.Hollister@Sun.COM #include <sys/param.h> 3010696SDavid.Hollister@Sun.COM #include <sys/systm.h> 3110696SDavid.Hollister@Sun.COM #include <sys/buf.h> 3210696SDavid.Hollister@Sun.COM #include <sys/kmem.h> 3310696SDavid.Hollister@Sun.COM #include <sys/cmn_err.h> 3410696SDavid.Hollister@Sun.COM #include <sys/debug.h> 3510696SDavid.Hollister@Sun.COM #include <sys/sunndi.h> 3610696SDavid.Hollister@Sun.COM #include <sys/kstat.h> 3710696SDavid.Hollister@Sun.COM #include <sys/conf.h> 3810696SDavid.Hollister@Sun.COM #include <sys/ddi_timer.h> 3910696SDavid.Hollister@Sun.COM #include <sys/devctl.h> 4010696SDavid.Hollister@Sun.COM #include <sys/callb.h> 4110696SDavid.Hollister@Sun.COM #include <sys/sysevent.h> 4210696SDavid.Hollister@Sun.COM #include <sys/taskq.h> 4310696SDavid.Hollister@Sun.COM #include <sys/ddi.h> 4410696SDavid.Hollister@Sun.COM #include <sys/bitset.h> 4510696SDavid.Hollister@Sun.COM #include <sys/damap.h> 4610696SDavid.Hollister@Sun.COM #include <sys/damap_impl.h> 4710696SDavid.Hollister@Sun.COM 4810696SDavid.Hollister@Sun.COM #ifdef DEBUG 4910696SDavid.Hollister@Sun.COM static int damap_debug = 0; 5010696SDavid.Hollister@Sun.COM #endif /* DEBUG */ 5110696SDavid.Hollister@Sun.COM 5211068SJohn.Danielson@Sun.COM extern taskq_t *system_taskq; 5311068SJohn.Danielson@Sun.COM 5410696SDavid.Hollister@Sun.COM static void dam_addrset_activate(dam_t *, bitset_t *); 5511068SJohn.Danielson@Sun.COM static void dam_addrset_deactivate(dam_t *, bitset_t *); 5611068SJohn.Danielson@Sun.COM static void dam_stabilize_map(void *); 5710696SDavid.Hollister@Sun.COM static void dam_addr_stable_cb(void *); 5811068SJohn.Danielson@Sun.COM static void dam_addrset_stable_cb(void *); 5910696SDavid.Hollister@Sun.COM static void dam_sched_tmo(dam_t *, clock_t, void (*tmo_cb)()); 6011068SJohn.Danielson@Sun.COM static void dam_addr_report(dam_t *, dam_da_t *, id_t, int); 6111068SJohn.Danielson@Sun.COM static void dam_addr_release(dam_t *, id_t); 6211068SJohn.Danielson@Sun.COM static void dam_addr_report_release(dam_t *, id_t); 6311068SJohn.Danielson@Sun.COM static void dam_addr_deactivate(dam_t *, id_t); 6411363SReed.Liu@Sun.COM static void dam_deact_cleanup(dam_t *, id_t, char *, damap_deact_rsn_t); 6510696SDavid.Hollister@Sun.COM static id_t dam_get_addrid(dam_t *, char *); 6610696SDavid.Hollister@Sun.COM static int dam_kstat_create(dam_t *); 6711068SJohn.Danielson@Sun.COM static int dam_map_alloc(dam_t *); 6810696SDavid.Hollister@Sun.COM 6910696SDavid.Hollister@Sun.COM #define DAM_INCR_STAT(mapp, stat) \ 7010696SDavid.Hollister@Sun.COM if ((mapp)->dam_kstatsp) { \ 7110696SDavid.Hollister@Sun.COM struct dam_kstats *stp = (mapp)->dam_kstatsp->ks_data; \ 7210696SDavid.Hollister@Sun.COM stp->stat.value.ui32++; \ 7310696SDavid.Hollister@Sun.COM } 7410696SDavid.Hollister@Sun.COM 7510696SDavid.Hollister@Sun.COM #define DAM_SET_STAT(mapp, stat, val) \ 7610696SDavid.Hollister@Sun.COM if ((mapp)->dam_kstatsp) { \ 7710696SDavid.Hollister@Sun.COM struct dam_kstats *stp = (mapp)->dam_kstatsp->ks_data; \ 7810696SDavid.Hollister@Sun.COM stp->stat.value.ui32 = (val); \ 7910696SDavid.Hollister@Sun.COM } 8010696SDavid.Hollister@Sun.COM 8111068SJohn.Danielson@Sun.COM 8211068SJohn.Danielson@Sun.COM /* 8311068SJohn.Danielson@Sun.COM * increase damap size by 64 entries at a time 8411068SJohn.Danielson@Sun.COM */ 8511068SJohn.Danielson@Sun.COM #define DAM_SIZE_BUMP 64 8611068SJohn.Danielson@Sun.COM 8711854SChris.Horne@Sun.COM int damap_taskq_dispatch_retry_usec = 1000; 8811854SChris.Horne@Sun.COM 8911068SJohn.Danielson@Sun.COM /* 9011068SJohn.Danielson@Sun.COM * config/unconfig taskq data 9111068SJohn.Danielson@Sun.COM */ 9211068SJohn.Danielson@Sun.COM typedef struct { 9311068SJohn.Danielson@Sun.COM dam_t *tqd_mapp; 9411068SJohn.Danielson@Sun.COM id_t tqd_id; 9511068SJohn.Danielson@Sun.COM } cfg_tqd_t; 9611068SJohn.Danielson@Sun.COM 9711068SJohn.Danielson@Sun.COM extern pri_t maxclsyspri; 9811068SJohn.Danielson@Sun.COM 9910696SDavid.Hollister@Sun.COM /* 10010696SDavid.Hollister@Sun.COM * Create new device address map 10110696SDavid.Hollister@Sun.COM * 10211068SJohn.Danielson@Sun.COM * name: map name (kstat unique) 10310696SDavid.Hollister@Sun.COM * size: max # of map entries 10411068SJohn.Danielson@Sun.COM * mode: style of address reports: per-address or fullset 10510696SDavid.Hollister@Sun.COM * stable_usec: # of quiescent microseconds before report/map is stable 10610696SDavid.Hollister@Sun.COM * 10710696SDavid.Hollister@Sun.COM * activate_arg: address provider activation-callout private 10810696SDavid.Hollister@Sun.COM * activate_cb: address provider activation callback handler 10910696SDavid.Hollister@Sun.COM * deactivate_cb: address provider deactivation callback handler 11010696SDavid.Hollister@Sun.COM * 11110696SDavid.Hollister@Sun.COM * config_arg: configuration-callout private 11210696SDavid.Hollister@Sun.COM * config_cb: class configuration callout 11310696SDavid.Hollister@Sun.COM * unconfig_cb: class unconfiguration callout 11410696SDavid.Hollister@Sun.COM * 11510696SDavid.Hollister@Sun.COM * damapp: pointer to map handle (return) 11610696SDavid.Hollister@Sun.COM * 11710696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 11810696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 11910696SDavid.Hollister@Sun.COM * DAM_FAILURE General failure 12010696SDavid.Hollister@Sun.COM */ 12110696SDavid.Hollister@Sun.COM int 12211068SJohn.Danielson@Sun.COM damap_create(char *name, damap_rptmode_t mode, int map_opts, 12311068SJohn.Danielson@Sun.COM clock_t stable_usec, void *activate_arg, damap_activate_cb_t activate_cb, 12410696SDavid.Hollister@Sun.COM damap_deactivate_cb_t deactivate_cb, 12510696SDavid.Hollister@Sun.COM void *config_arg, damap_configure_cb_t configure_cb, 12610696SDavid.Hollister@Sun.COM damap_unconfig_cb_t unconfig_cb, 12710696SDavid.Hollister@Sun.COM damap_t **damapp) 12810696SDavid.Hollister@Sun.COM { 12910696SDavid.Hollister@Sun.COM dam_t *mapp; 13010696SDavid.Hollister@Sun.COM 13111068SJohn.Danielson@Sun.COM if (configure_cb == NULL || unconfig_cb == NULL || name == NULL) 13210696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 13310696SDavid.Hollister@Sun.COM 13411068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__create, char *, name, 13511068SJohn.Danielson@Sun.COM damap_rptmode_t, mode, clock_t, stable_usec); 13610696SDavid.Hollister@Sun.COM 13710696SDavid.Hollister@Sun.COM mapp = kmem_zalloc(sizeof (*mapp), KM_SLEEP); 13811068SJohn.Danielson@Sun.COM mapp->dam_options = map_opts; 13910696SDavid.Hollister@Sun.COM mapp->dam_stabletmo = drv_usectohz(stable_usec); 14011068SJohn.Danielson@Sun.COM mapp->dam_size = 0; 14111068SJohn.Danielson@Sun.COM mapp->dam_rptmode = mode; 14210696SDavid.Hollister@Sun.COM mapp->dam_activate_arg = activate_arg; 14310696SDavid.Hollister@Sun.COM mapp->dam_activate_cb = (activate_cb_t)activate_cb; 14410696SDavid.Hollister@Sun.COM mapp->dam_deactivate_cb = (deactivate_cb_t)deactivate_cb; 14510696SDavid.Hollister@Sun.COM mapp->dam_config_arg = config_arg; 14610696SDavid.Hollister@Sun.COM mapp->dam_configure_cb = (configure_cb_t)configure_cb; 14710696SDavid.Hollister@Sun.COM mapp->dam_unconfig_cb = (unconfig_cb_t)unconfig_cb; 14811068SJohn.Danielson@Sun.COM mapp->dam_name = i_ddi_strdup(name, KM_SLEEP); 14910696SDavid.Hollister@Sun.COM mutex_init(&mapp->dam_lock, NULL, MUTEX_DRIVER, NULL); 15010696SDavid.Hollister@Sun.COM cv_init(&mapp->dam_cv, NULL, CV_DRIVER, NULL); 15111068SJohn.Danielson@Sun.COM bitset_init(&mapp->dam_active_set); 15211068SJohn.Danielson@Sun.COM bitset_init(&mapp->dam_stable_set); 15311068SJohn.Danielson@Sun.COM bitset_init(&mapp->dam_report_set); 15410696SDavid.Hollister@Sun.COM *damapp = (damap_t *)mapp; 15510696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 15610696SDavid.Hollister@Sun.COM } 15710696SDavid.Hollister@Sun.COM 15810696SDavid.Hollister@Sun.COM /* 15911068SJohn.Danielson@Sun.COM * Allocate backing resources 16011068SJohn.Danielson@Sun.COM * 16111068SJohn.Danielson@Sun.COM * DAMs are lightly backed on create - major allocations occur 16211068SJohn.Danielson@Sun.COM * at the time a report is made to the map, and are extended on 16311068SJohn.Danielson@Sun.COM * a demand basis. 16411068SJohn.Danielson@Sun.COM */ 16511068SJohn.Danielson@Sun.COM static int 16611068SJohn.Danielson@Sun.COM dam_map_alloc(dam_t *mapp) 16711068SJohn.Danielson@Sun.COM { 16811068SJohn.Danielson@Sun.COM void *softstate_p; 16911068SJohn.Danielson@Sun.COM 17011068SJohn.Danielson@Sun.COM ASSERT(mutex_owned(&mapp->dam_lock)); 17111068SJohn.Danielson@Sun.COM if (mapp->dam_flags & DAM_DESTROYPEND) 17211068SJohn.Danielson@Sun.COM return (DAM_FAILURE); 17311068SJohn.Danielson@Sun.COM 17411068SJohn.Danielson@Sun.COM /* 17511068SJohn.Danielson@Sun.COM * dam_high > 0 signals map allocation complete 17611068SJohn.Danielson@Sun.COM */ 17711068SJohn.Danielson@Sun.COM if (mapp->dam_high) 17811068SJohn.Danielson@Sun.COM return (DAM_SUCCESS); 17911068SJohn.Danielson@Sun.COM 18011068SJohn.Danielson@Sun.COM mapp->dam_size = DAM_SIZE_BUMP; 18111068SJohn.Danielson@Sun.COM if (ddi_soft_state_init(&softstate_p, sizeof (dam_da_t), 18211068SJohn.Danielson@Sun.COM mapp->dam_size) != DDI_SUCCESS) 18311068SJohn.Danielson@Sun.COM return (DAM_FAILURE); 18411068SJohn.Danielson@Sun.COM 18511068SJohn.Danielson@Sun.COM if (ddi_strid_init(&mapp->dam_addr_hash, mapp->dam_size) != 18611068SJohn.Danielson@Sun.COM DDI_SUCCESS) { 18711068SJohn.Danielson@Sun.COM ddi_soft_state_fini(softstate_p); 18811068SJohn.Danielson@Sun.COM return (DAM_FAILURE); 18911068SJohn.Danielson@Sun.COM } 19011068SJohn.Danielson@Sun.COM if (dam_kstat_create(mapp) != DDI_SUCCESS) { 19111068SJohn.Danielson@Sun.COM ddi_soft_state_fini(softstate_p); 19211068SJohn.Danielson@Sun.COM ddi_strid_fini(&mapp->dam_addr_hash); 19311068SJohn.Danielson@Sun.COM return (DAM_FAILURE); 19411068SJohn.Danielson@Sun.COM } 19511068SJohn.Danielson@Sun.COM mapp->dam_da = softstate_p; 19611068SJohn.Danielson@Sun.COM mapp->dam_high = 1; 19711068SJohn.Danielson@Sun.COM bitset_resize(&mapp->dam_active_set, mapp->dam_size); 19811068SJohn.Danielson@Sun.COM bitset_resize(&mapp->dam_stable_set, mapp->dam_size); 19911068SJohn.Danielson@Sun.COM bitset_resize(&mapp->dam_report_set, mapp->dam_size); 20011068SJohn.Danielson@Sun.COM return (DAM_SUCCESS); 20111068SJohn.Danielson@Sun.COM } 20211068SJohn.Danielson@Sun.COM 20311068SJohn.Danielson@Sun.COM /* 20411068SJohn.Danielson@Sun.COM * Destroy address map 20510696SDavid.Hollister@Sun.COM * 20610696SDavid.Hollister@Sun.COM * damapp: address map 20710696SDavid.Hollister@Sun.COM * 20810696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 20910696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 21010696SDavid.Hollister@Sun.COM * DAM_FAILURE General failure 21110696SDavid.Hollister@Sun.COM */ 21210696SDavid.Hollister@Sun.COM void 21310696SDavid.Hollister@Sun.COM damap_destroy(damap_t *damapp) 21410696SDavid.Hollister@Sun.COM { 21510696SDavid.Hollister@Sun.COM int i; 21610696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 21710696SDavid.Hollister@Sun.COM 21810696SDavid.Hollister@Sun.COM ASSERT(mapp); 21910696SDavid.Hollister@Sun.COM 22011068SJohn.Danielson@Sun.COM DTRACE_PROBE1(damap__destroy, char *, mapp->dam_name); 22110696SDavid.Hollister@Sun.COM 22211068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 22310696SDavid.Hollister@Sun.COM 22410696SDavid.Hollister@Sun.COM /* 22511068SJohn.Danielson@Sun.COM * prevent new reports from being added to the map 22610696SDavid.Hollister@Sun.COM */ 22711068SJohn.Danielson@Sun.COM mapp->dam_flags |= DAM_DESTROYPEND; 22811068SJohn.Danielson@Sun.COM 22911068SJohn.Danielson@Sun.COM if (mapp->dam_high) { 23011068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 23111068SJohn.Danielson@Sun.COM /* 23211068SJohn.Danielson@Sun.COM * wait for outstanding reports to stabilize and cancel 23311068SJohn.Danielson@Sun.COM * the timer for this map 23411068SJohn.Danielson@Sun.COM */ 23511068SJohn.Danielson@Sun.COM (void) damap_sync(damapp); 23611068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 23711068SJohn.Danielson@Sun.COM dam_sched_tmo(mapp, 0, NULL); 23810696SDavid.Hollister@Sun.COM 23911068SJohn.Danielson@Sun.COM /* 24011068SJohn.Danielson@Sun.COM * map is at full stop 24111068SJohn.Danielson@Sun.COM * release the contents of the map, invoking the 24211068SJohn.Danielson@Sun.COM * detactivation protocol as addresses are released 24311068SJohn.Danielson@Sun.COM */ 24411068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 24511068SJohn.Danielson@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 24611068SJohn.Danielson@Sun.COM if (ddi_get_soft_state(mapp->dam_da, i) == NULL) 24711068SJohn.Danielson@Sun.COM continue; 24811068SJohn.Danielson@Sun.COM 24911068SJohn.Danielson@Sun.COM ASSERT(DAM_IN_REPORT(mapp, i) == 0); 25011068SJohn.Danielson@Sun.COM 25111068SJohn.Danielson@Sun.COM if (DAM_IS_STABLE(mapp, i)) { 25211068SJohn.Danielson@Sun.COM dam_addr_deactivate(mapp, i); 25311068SJohn.Danielson@Sun.COM } else { 25411068SJohn.Danielson@Sun.COM ddi_strid_free(mapp->dam_addr_hash, i); 25511068SJohn.Danielson@Sun.COM ddi_soft_state_free(mapp->dam_da, i); 25611068SJohn.Danielson@Sun.COM } 25711068SJohn.Danielson@Sun.COM } 25811068SJohn.Danielson@Sun.COM ddi_strid_fini(&mapp->dam_addr_hash); 25911068SJohn.Danielson@Sun.COM ddi_soft_state_fini(&mapp->dam_da); 26011068SJohn.Danielson@Sun.COM kstat_delete(mapp->dam_kstatsp); 26110696SDavid.Hollister@Sun.COM } 26210696SDavid.Hollister@Sun.COM bitset_fini(&mapp->dam_active_set); 26310696SDavid.Hollister@Sun.COM bitset_fini(&mapp->dam_stable_set); 26410696SDavid.Hollister@Sun.COM bitset_fini(&mapp->dam_report_set); 26510696SDavid.Hollister@Sun.COM mutex_destroy(&mapp->dam_lock); 26610696SDavid.Hollister@Sun.COM cv_destroy(&mapp->dam_cv); 26710696SDavid.Hollister@Sun.COM if (mapp->dam_name) 26810696SDavid.Hollister@Sun.COM kmem_free(mapp->dam_name, strlen(mapp->dam_name) + 1); 26910696SDavid.Hollister@Sun.COM kmem_free(mapp, sizeof (*mapp)); 27010696SDavid.Hollister@Sun.COM } 27110696SDavid.Hollister@Sun.COM 27210696SDavid.Hollister@Sun.COM /* 27310696SDavid.Hollister@Sun.COM * Wait for map stability. 27410696SDavid.Hollister@Sun.COM * 27510696SDavid.Hollister@Sun.COM * damapp: address map 27610696SDavid.Hollister@Sun.COM */ 27710696SDavid.Hollister@Sun.COM int 27810696SDavid.Hollister@Sun.COM damap_sync(damap_t *damapp) 27910696SDavid.Hollister@Sun.COM { 28011068SJohn.Danielson@Sun.COM #define WAITFOR_FLAGS (DAM_SETADD | DAM_SPEND) 28110696SDavid.Hollister@Sun.COM 28210696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 28310696SDavid.Hollister@Sun.COM int none_active; 28410696SDavid.Hollister@Sun.COM 28510696SDavid.Hollister@Sun.COM ASSERT(mapp); 28610696SDavid.Hollister@Sun.COM 28711068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__map__sync__start, char *, mapp->dam_name, 28811068SJohn.Danielson@Sun.COM dam_t *, mapp); 28910696SDavid.Hollister@Sun.COM 29011068SJohn.Danielson@Sun.COM /* 29111068SJohn.Danielson@Sun.COM * block where waiting for 29211068SJohn.Danielson@Sun.COM * a) stabilization pending or a fullset update pending 29311068SJohn.Danielson@Sun.COM * b) any scheduled timeouts to fire 29411068SJohn.Danielson@Sun.COM * c) the report set to finalize (bitset is null) 29511068SJohn.Danielson@Sun.COM */ 29610696SDavid.Hollister@Sun.COM mutex_enter(&mapp->dam_lock); 29710696SDavid.Hollister@Sun.COM while ((mapp->dam_flags & WAITFOR_FLAGS) || 29810696SDavid.Hollister@Sun.COM (!bitset_is_null(&mapp->dam_report_set)) || (mapp->dam_tid != 0)) { 29911068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__map__sync__waiting, char *, mapp->dam_name, 30011068SJohn.Danielson@Sun.COM dam_t *, mapp); 30110696SDavid.Hollister@Sun.COM cv_wait(&mapp->dam_cv, &mapp->dam_lock); 30210696SDavid.Hollister@Sun.COM } 30310696SDavid.Hollister@Sun.COM 30410696SDavid.Hollister@Sun.COM none_active = bitset_is_null(&mapp->dam_active_set); 30510696SDavid.Hollister@Sun.COM 30610696SDavid.Hollister@Sun.COM mutex_exit(&mapp->dam_lock); 30711068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__map__sync__end, char *, mapp->dam_name, int, 30811068SJohn.Danielson@Sun.COM none_active, dam_t *, mapp); 30910696SDavid.Hollister@Sun.COM 31010696SDavid.Hollister@Sun.COM return (none_active); 31110696SDavid.Hollister@Sun.COM } 31210696SDavid.Hollister@Sun.COM 31310696SDavid.Hollister@Sun.COM /* 31410696SDavid.Hollister@Sun.COM * Get the name of a device address map 31510696SDavid.Hollister@Sun.COM * 31610696SDavid.Hollister@Sun.COM * damapp: address map 31710696SDavid.Hollister@Sun.COM * 31810696SDavid.Hollister@Sun.COM * Returns: name 31910696SDavid.Hollister@Sun.COM */ 32010696SDavid.Hollister@Sun.COM char * 32110696SDavid.Hollister@Sun.COM damap_name(damap_t *damapp) 32210696SDavid.Hollister@Sun.COM { 32310696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 32410696SDavid.Hollister@Sun.COM 32510696SDavid.Hollister@Sun.COM return (mapp ? mapp->dam_name : "UNKNOWN_damap"); 32610696SDavid.Hollister@Sun.COM } 32710696SDavid.Hollister@Sun.COM 32810696SDavid.Hollister@Sun.COM /* 32910696SDavid.Hollister@Sun.COM * Report an address to per-address report 33010696SDavid.Hollister@Sun.COM * 33110696SDavid.Hollister@Sun.COM * damapp: address map handle 33210696SDavid.Hollister@Sun.COM * address: address in ascii string representation 33311068SJohn.Danielson@Sun.COM * addridp: address ID 33410696SDavid.Hollister@Sun.COM * nvl: optional nvlist of configuration-private data 33510696SDavid.Hollister@Sun.COM * addr_priv: optional provider-private (passed to activate/deactivate cb) 33610696SDavid.Hollister@Sun.COM * 33710696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 33810696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 33910696SDavid.Hollister@Sun.COM * DAM_MAPFULL address map exhausted 34010696SDavid.Hollister@Sun.COM */ 34110696SDavid.Hollister@Sun.COM int 34211068SJohn.Danielson@Sun.COM damap_addr_add(damap_t *damapp, char *address, damap_id_t *addridp, 34311068SJohn.Danielson@Sun.COM nvlist_t *nvl, void *addr_priv) 34410696SDavid.Hollister@Sun.COM { 34510696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 34610696SDavid.Hollister@Sun.COM id_t addrid; 34710696SDavid.Hollister@Sun.COM dam_da_t *passp; 34810696SDavid.Hollister@Sun.COM 34911068SJohn.Danielson@Sun.COM if (!mapp || !address || (mapp->dam_rptmode != DAMAP_REPORT_PERADDR)) 35010696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 35110696SDavid.Hollister@Sun.COM 35211068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__add, char *, mapp->dam_name, 35311068SJohn.Danielson@Sun.COM char *, address, dam_t *, mapp); 35411068SJohn.Danielson@Sun.COM 35511068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 35611068SJohn.Danielson@Sun.COM if ((dam_map_alloc(mapp) != DAM_SUCCESS) || 35711068SJohn.Danielson@Sun.COM ((addrid = dam_get_addrid(mapp, address)) == 0)) { 35811068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 35910696SDavid.Hollister@Sun.COM return (DAM_MAPFULL); 36010696SDavid.Hollister@Sun.COM } 36110696SDavid.Hollister@Sun.COM 36210696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 36310696SDavid.Hollister@Sun.COM ASSERT(passp != NULL); 36410696SDavid.Hollister@Sun.COM 36510696SDavid.Hollister@Sun.COM /* 36610696SDavid.Hollister@Sun.COM * If re-reporting the same address (add or remove) clear 36710696SDavid.Hollister@Sun.COM * the existing report 36810696SDavid.Hollister@Sun.COM */ 36910696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, addrid)) { 37011068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__add__jitter, char *, mapp->dam_name, 37111068SJohn.Danielson@Sun.COM char *, address, dam_t *, mapp); 37211068SJohn.Danielson@Sun.COM DAM_INCR_STAT(mapp, dam_jitter); 37311068SJohn.Danielson@Sun.COM dam_addr_report_release(mapp, addrid); 37410696SDavid.Hollister@Sun.COM passp->da_jitter++; 37510696SDavid.Hollister@Sun.COM } 37610696SDavid.Hollister@Sun.COM passp->da_ppriv_rpt = addr_priv; 37710696SDavid.Hollister@Sun.COM if (nvl) 37810696SDavid.Hollister@Sun.COM (void) nvlist_dup(nvl, &passp->da_nvl_rpt, KM_SLEEP); 37910696SDavid.Hollister@Sun.COM 38011068SJohn.Danielson@Sun.COM dam_addr_report(mapp, passp, addrid, RPT_ADDR_ADD); 38111068SJohn.Danielson@Sun.COM if (addridp != NULL) 38211068SJohn.Danielson@Sun.COM *addridp = (damap_id_t)addrid; 38311068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 38410696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 38510696SDavid.Hollister@Sun.COM } 38610696SDavid.Hollister@Sun.COM 38710696SDavid.Hollister@Sun.COM /* 38810696SDavid.Hollister@Sun.COM * Report removal of address from per-address report 38910696SDavid.Hollister@Sun.COM * 39010696SDavid.Hollister@Sun.COM * damapp: address map 39110696SDavid.Hollister@Sun.COM * address: address in ascii string representation 39210696SDavid.Hollister@Sun.COM * 39310696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 39410696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 39510696SDavid.Hollister@Sun.COM * DAM_FAILURE General failure 39610696SDavid.Hollister@Sun.COM */ 39710696SDavid.Hollister@Sun.COM int 39810696SDavid.Hollister@Sun.COM damap_addr_del(damap_t *damapp, char *address) 39910696SDavid.Hollister@Sun.COM { 40010696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 40110696SDavid.Hollister@Sun.COM id_t addrid; 40210696SDavid.Hollister@Sun.COM dam_da_t *passp; 40310696SDavid.Hollister@Sun.COM 40411068SJohn.Danielson@Sun.COM if (!mapp || !address || (mapp->dam_rptmode != DAMAP_REPORT_PERADDR)) 40510696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 40610696SDavid.Hollister@Sun.COM 40711068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__del, char *, mapp->dam_name, 40811068SJohn.Danielson@Sun.COM char *, address, dam_t *, mapp); 40911068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 41011068SJohn.Danielson@Sun.COM if (dam_map_alloc(mapp) != DAM_SUCCESS) { 41111068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 41211068SJohn.Danielson@Sun.COM return (DAM_MAPFULL); 41311068SJohn.Danielson@Sun.COM } 41411068SJohn.Danielson@Sun.COM 41511068SJohn.Danielson@Sun.COM /* 41611068SJohn.Danielson@Sun.COM * if reporting the removal of an address which is not in the map 41711068SJohn.Danielson@Sun.COM * return success 41811068SJohn.Danielson@Sun.COM */ 41910696SDavid.Hollister@Sun.COM if (!(addrid = ddi_strid_str2id(mapp->dam_addr_hash, address))) { 42011068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 42110696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 42210696SDavid.Hollister@Sun.COM } 42310696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 42410696SDavid.Hollister@Sun.COM ASSERT(passp); 42510696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, addrid)) { 42611068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__del__jitter, char *, mapp->dam_name, 42711068SJohn.Danielson@Sun.COM char *, address, dam_t *, mapp); 42811068SJohn.Danielson@Sun.COM DAM_INCR_STAT(mapp, dam_jitter); 42911068SJohn.Danielson@Sun.COM dam_addr_report_release(mapp, addrid); 43010696SDavid.Hollister@Sun.COM passp->da_jitter++; 43110696SDavid.Hollister@Sun.COM } 43211068SJohn.Danielson@Sun.COM dam_addr_report(mapp, passp, addrid, RPT_ADDR_DEL); 43311068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 43410696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 43510696SDavid.Hollister@Sun.COM } 43610696SDavid.Hollister@Sun.COM 437*12000SReed.Liu@Sun.COM static int 438*12000SReed.Liu@Sun.COM damap_addrset_flush_locked(damap_t *damapp) 439*12000SReed.Liu@Sun.COM { 440*12000SReed.Liu@Sun.COM dam_t *mapp = (dam_t *)damapp; 441*12000SReed.Liu@Sun.COM int idx; 442*12000SReed.Liu@Sun.COM 443*12000SReed.Liu@Sun.COM ASSERT(mapp); 444*12000SReed.Liu@Sun.COM ASSERT(mutex_owned(&mapp->dam_lock)); 445*12000SReed.Liu@Sun.COM if (mapp->dam_rptmode != DAMAP_REPORT_FULLSET) { 446*12000SReed.Liu@Sun.COM return (DAM_EINVAL); 447*12000SReed.Liu@Sun.COM } 448*12000SReed.Liu@Sun.COM 449*12000SReed.Liu@Sun.COM DTRACE_PROBE2(damap__addrset__flush__locked__enter, char *, 450*12000SReed.Liu@Sun.COM mapp->dam_name, dam_t *, mapp); 451*12000SReed.Liu@Sun.COM if (mapp->dam_flags & DAM_SETADD) { 452*12000SReed.Liu@Sun.COM DTRACE_PROBE2(damap__addrset__flush__locked__reset, char *, 453*12000SReed.Liu@Sun.COM mapp->dam_name, dam_t *, mapp); 454*12000SReed.Liu@Sun.COM 455*12000SReed.Liu@Sun.COM /* 456*12000SReed.Liu@Sun.COM * cancel stabilization timeout 457*12000SReed.Liu@Sun.COM */ 458*12000SReed.Liu@Sun.COM dam_sched_tmo(mapp, 0, NULL); 459*12000SReed.Liu@Sun.COM DAM_INCR_STAT(mapp, dam_jitter); 460*12000SReed.Liu@Sun.COM 461*12000SReed.Liu@Sun.COM /* 462*12000SReed.Liu@Sun.COM * clear pending reports 463*12000SReed.Liu@Sun.COM */ 464*12000SReed.Liu@Sun.COM for (idx = 1; idx < mapp->dam_high; idx++) { 465*12000SReed.Liu@Sun.COM if (DAM_IN_REPORT(mapp, idx)) { 466*12000SReed.Liu@Sun.COM dam_addr_report_release(mapp, idx); 467*12000SReed.Liu@Sun.COM } 468*12000SReed.Liu@Sun.COM } 469*12000SReed.Liu@Sun.COM 470*12000SReed.Liu@Sun.COM bitset_zero(&mapp->dam_report_set); 471*12000SReed.Liu@Sun.COM mapp->dam_flags &= ~DAM_SETADD; 472*12000SReed.Liu@Sun.COM } 473*12000SReed.Liu@Sun.COM 474*12000SReed.Liu@Sun.COM return (DAM_SUCCESS); 475*12000SReed.Liu@Sun.COM } 476*12000SReed.Liu@Sun.COM 47710696SDavid.Hollister@Sun.COM /* 47810696SDavid.Hollister@Sun.COM * Initiate full-set report 47910696SDavid.Hollister@Sun.COM * 48010696SDavid.Hollister@Sun.COM * damapp: address map 48110696SDavid.Hollister@Sun.COM * 48210696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 48310696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 48410696SDavid.Hollister@Sun.COM */ 48510696SDavid.Hollister@Sun.COM int 48610696SDavid.Hollister@Sun.COM damap_addrset_begin(damap_t *damapp) 48710696SDavid.Hollister@Sun.COM { 488*12000SReed.Liu@Sun.COM dam_t *mapp = (dam_t *)damapp; 489*12000SReed.Liu@Sun.COM int rv; 49010696SDavid.Hollister@Sun.COM 491*12000SReed.Liu@Sun.COM if (mapp == NULL) { 49210696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 493*12000SReed.Liu@Sun.COM } 49410696SDavid.Hollister@Sun.COM 49511068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__addrset__begin, char *, mapp->dam_name, dam_t *, 49611068SJohn.Danielson@Sun.COM mapp); 497*12000SReed.Liu@Sun.COM 49811068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 49911068SJohn.Danielson@Sun.COM if (dam_map_alloc(mapp) != DAM_SUCCESS) { 50011068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 501*12000SReed.Liu@Sun.COM 50211068SJohn.Danielson@Sun.COM return (DAM_MAPFULL); 50311068SJohn.Danielson@Sun.COM } 504*12000SReed.Liu@Sun.COM 505*12000SReed.Liu@Sun.COM rv = damap_addrset_flush_locked(damapp); 506*12000SReed.Liu@Sun.COM if (rv == DAM_SUCCESS) { 507*12000SReed.Liu@Sun.COM mapp->dam_flags |= DAM_SETADD; 508*12000SReed.Liu@Sun.COM } 509*12000SReed.Liu@Sun.COM mutex_exit(&mapp->dam_lock); 510*12000SReed.Liu@Sun.COM 511*12000SReed.Liu@Sun.COM return (rv); 512*12000SReed.Liu@Sun.COM } 51311068SJohn.Danielson@Sun.COM 514*12000SReed.Liu@Sun.COM /* 515*12000SReed.Liu@Sun.COM * Cancel full-set report 516*12000SReed.Liu@Sun.COM * 517*12000SReed.Liu@Sun.COM * damapp: address map 518*12000SReed.Liu@Sun.COM * 519*12000SReed.Liu@Sun.COM * Returns: DAM_SUCCESS 520*12000SReed.Liu@Sun.COM * DAM_EINVAL Invalid argument(s) 521*12000SReed.Liu@Sun.COM */ 522*12000SReed.Liu@Sun.COM int 523*12000SReed.Liu@Sun.COM damap_addrset_flush(damap_t *damapp) 524*12000SReed.Liu@Sun.COM { 525*12000SReed.Liu@Sun.COM int rv; 526*12000SReed.Liu@Sun.COM dam_t *mapp = (dam_t *)damapp; 527*12000SReed.Liu@Sun.COM 528*12000SReed.Liu@Sun.COM if (mapp == NULL) { 529*12000SReed.Liu@Sun.COM return (DAM_EINVAL); 53010696SDavid.Hollister@Sun.COM } 531*12000SReed.Liu@Sun.COM 532*12000SReed.Liu@Sun.COM DTRACE_PROBE2(damap__addrset__flush, char *, mapp->dam_name, 533*12000SReed.Liu@Sun.COM dam_t *, mapp); 534*12000SReed.Liu@Sun.COM 535*12000SReed.Liu@Sun.COM mutex_enter(&mapp->dam_lock); 536*12000SReed.Liu@Sun.COM rv = damap_addrset_flush_locked(damapp); 53711068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 538*12000SReed.Liu@Sun.COM 539*12000SReed.Liu@Sun.COM return (rv); 54010696SDavid.Hollister@Sun.COM } 54110696SDavid.Hollister@Sun.COM 54210696SDavid.Hollister@Sun.COM /* 54310696SDavid.Hollister@Sun.COM * Report address to full-set report 54410696SDavid.Hollister@Sun.COM * 54510696SDavid.Hollister@Sun.COM * damapp: address map handle 54610696SDavid.Hollister@Sun.COM * address: address in ascii string representation 54710696SDavid.Hollister@Sun.COM * rindx: index if address stabilizes 54810696SDavid.Hollister@Sun.COM * nvl: optional nvlist of configuration-private data 54910696SDavid.Hollister@Sun.COM * addr_priv: optional provider-private data (passed to activate/release cb) 55010696SDavid.Hollister@Sun.COM * 55110696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 55210696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 55310696SDavid.Hollister@Sun.COM * DAM_MAPFULL address map exhausted 55410696SDavid.Hollister@Sun.COM * DAM_FAILURE General failure 55510696SDavid.Hollister@Sun.COM */ 55610696SDavid.Hollister@Sun.COM int 55710696SDavid.Hollister@Sun.COM damap_addrset_add(damap_t *damapp, char *address, damap_id_t *ridx, 55810696SDavid.Hollister@Sun.COM nvlist_t *nvl, void *addr_priv) 55910696SDavid.Hollister@Sun.COM { 56010696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 56110696SDavid.Hollister@Sun.COM id_t addrid; 56210696SDavid.Hollister@Sun.COM dam_da_t *passp; 56310696SDavid.Hollister@Sun.COM 56411068SJohn.Danielson@Sun.COM if (!mapp || !address || (mapp->dam_rptmode != DAMAP_REPORT_FULLSET)) 56510696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 56610696SDavid.Hollister@Sun.COM 56711068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addrset__add, char *, mapp->dam_name, 56811068SJohn.Danielson@Sun.COM char *, address, dam_t *, mapp); 56910696SDavid.Hollister@Sun.COM 57011068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 57111068SJohn.Danielson@Sun.COM if (!(mapp->dam_flags & DAM_SETADD)) { 57211068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 57311068SJohn.Danielson@Sun.COM return (DAM_FAILURE); 57411068SJohn.Danielson@Sun.COM } 57511068SJohn.Danielson@Sun.COM 57610696SDavid.Hollister@Sun.COM if ((addrid = dam_get_addrid(mapp, address)) == 0) { 57711068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 57810696SDavid.Hollister@Sun.COM return (DAM_MAPFULL); 57910696SDavid.Hollister@Sun.COM } 58010696SDavid.Hollister@Sun.COM 58110696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 58210696SDavid.Hollister@Sun.COM ASSERT(passp); 58310696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, addrid)) { 58411068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addrset__add__jitter, char *, 58511068SJohn.Danielson@Sun.COM mapp->dam_name, char *, address, dam_t *, mapp); 58611068SJohn.Danielson@Sun.COM dam_addr_report_release(mapp, addrid); 58710696SDavid.Hollister@Sun.COM passp->da_jitter++; 58810696SDavid.Hollister@Sun.COM } 58910696SDavid.Hollister@Sun.COM passp->da_ppriv_rpt = addr_priv; 59010696SDavid.Hollister@Sun.COM if (nvl) 59110696SDavid.Hollister@Sun.COM (void) nvlist_dup(nvl, &passp->da_nvl_rpt, KM_SLEEP); 59210696SDavid.Hollister@Sun.COM bitset_add(&mapp->dam_report_set, addrid); 59310696SDavid.Hollister@Sun.COM if (ridx) 59410696SDavid.Hollister@Sun.COM *ridx = (damap_id_t)addrid; 59511068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 59610696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 59710696SDavid.Hollister@Sun.COM } 59810696SDavid.Hollister@Sun.COM 59910696SDavid.Hollister@Sun.COM /* 60010696SDavid.Hollister@Sun.COM * Commit full-set report for stabilization 60110696SDavid.Hollister@Sun.COM * 60210696SDavid.Hollister@Sun.COM * damapp: address map handle 60310696SDavid.Hollister@Sun.COM * flags: (currently 0) 60410696SDavid.Hollister@Sun.COM * 60510696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 60610696SDavid.Hollister@Sun.COM * DAM_EINVAL Invalid argument(s) 60710696SDavid.Hollister@Sun.COM * DAM_FAILURE General failure 60810696SDavid.Hollister@Sun.COM */ 60910696SDavid.Hollister@Sun.COM int 61010696SDavid.Hollister@Sun.COM damap_addrset_end(damap_t *damapp, int flags) 61110696SDavid.Hollister@Sun.COM { 61210696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 61310696SDavid.Hollister@Sun.COM int i; 61410696SDavid.Hollister@Sun.COM 61511068SJohn.Danielson@Sun.COM if (!mapp || (mapp->dam_rptmode != DAMAP_REPORT_FULLSET)) 61610696SDavid.Hollister@Sun.COM return (DAM_EINVAL); 61710696SDavid.Hollister@Sun.COM 61811068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__addrset__end, char *, mapp->dam_name, 61911068SJohn.Danielson@Sun.COM dam_t *, mapp); 62010696SDavid.Hollister@Sun.COM 62111068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 62211068SJohn.Danielson@Sun.COM if (!(mapp->dam_flags & DAM_SETADD)) { 62311068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 62411068SJohn.Danielson@Sun.COM return (DAM_FAILURE); 62511068SJohn.Danielson@Sun.COM } 62611068SJohn.Danielson@Sun.COM 62711068SJohn.Danielson@Sun.COM if (flags & DAMAP_END_RESET) { 62811068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__addrset__end__reset, char *, 62911068SJohn.Danielson@Sun.COM mapp->dam_name, dam_t *, mapp); 63010696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, 0, NULL); 63110696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) 63210696SDavid.Hollister@Sun.COM if (DAM_IN_REPORT(mapp, i)) 63311068SJohn.Danielson@Sun.COM dam_addr_report_release(mapp, i); 63410696SDavid.Hollister@Sun.COM } else { 63510696SDavid.Hollister@Sun.COM mapp->dam_last_update = gethrtime(); 63611068SJohn.Danielson@Sun.COM dam_sched_tmo(mapp, mapp->dam_stabletmo, dam_addrset_stable_cb); 63710696SDavid.Hollister@Sun.COM } 63811068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 63910696SDavid.Hollister@Sun.COM return (DAM_SUCCESS); 64010696SDavid.Hollister@Sun.COM } 64110696SDavid.Hollister@Sun.COM 64210696SDavid.Hollister@Sun.COM /* 64310696SDavid.Hollister@Sun.COM * Return nvlist registered with reported address 64410696SDavid.Hollister@Sun.COM * 64510696SDavid.Hollister@Sun.COM * damapp: address map handle 64611068SJohn.Danielson@Sun.COM * addrid: address ID 64710696SDavid.Hollister@Sun.COM * 64810696SDavid.Hollister@Sun.COM * Returns: nvlist_t * provider supplied via damap_addr{set}_add()) 64910696SDavid.Hollister@Sun.COM * NULL 65010696SDavid.Hollister@Sun.COM */ 65110696SDavid.Hollister@Sun.COM nvlist_t * 65210696SDavid.Hollister@Sun.COM damap_id2nvlist(damap_t *damapp, damap_id_t addrid) 65310696SDavid.Hollister@Sun.COM { 65410696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 65510696SDavid.Hollister@Sun.COM dam_da_t *pass; 65610696SDavid.Hollister@Sun.COM 65711068SJohn.Danielson@Sun.COM if (mapp->dam_high && ddi_strid_id2str(mapp->dam_addr_hash, addrid)) { 65811068SJohn.Danielson@Sun.COM if (pass = ddi_get_soft_state(mapp->dam_da, addrid)) 65910696SDavid.Hollister@Sun.COM return (pass->da_nvl); 66010696SDavid.Hollister@Sun.COM } 66110696SDavid.Hollister@Sun.COM return (NULL); 66210696SDavid.Hollister@Sun.COM } 66310696SDavid.Hollister@Sun.COM 66410696SDavid.Hollister@Sun.COM /* 66510696SDavid.Hollister@Sun.COM * Return address string 66610696SDavid.Hollister@Sun.COM * 66710696SDavid.Hollister@Sun.COM * damapp: address map handle 66811068SJohn.Danielson@Sun.COM * addrid: address ID 66910696SDavid.Hollister@Sun.COM * 67010696SDavid.Hollister@Sun.COM * Returns: char * Address string 67110696SDavid.Hollister@Sun.COM * NULL 67210696SDavid.Hollister@Sun.COM */ 67310696SDavid.Hollister@Sun.COM char * 67411068SJohn.Danielson@Sun.COM damap_id2addr(damap_t *damapp, damap_id_t addrid) 67510696SDavid.Hollister@Sun.COM { 67610696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 67710696SDavid.Hollister@Sun.COM 67811068SJohn.Danielson@Sun.COM if (mapp->dam_high) 67911068SJohn.Danielson@Sun.COM return (ddi_strid_id2str(mapp->dam_addr_hash, addrid)); 68011068SJohn.Danielson@Sun.COM else 68111068SJohn.Danielson@Sun.COM return (NULL); 68210696SDavid.Hollister@Sun.COM } 68310696SDavid.Hollister@Sun.COM 68410696SDavid.Hollister@Sun.COM /* 68510696SDavid.Hollister@Sun.COM * Release address reference in map 68610696SDavid.Hollister@Sun.COM * 68710696SDavid.Hollister@Sun.COM * damapp: address map handle 68811068SJohn.Danielson@Sun.COM * addrid: address ID 68910696SDavid.Hollister@Sun.COM */ 69010696SDavid.Hollister@Sun.COM void 69110696SDavid.Hollister@Sun.COM damap_id_rele(damap_t *damapp, damap_id_t addrid) 69210696SDavid.Hollister@Sun.COM { 69310696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 69411068SJohn.Danielson@Sun.COM dam_da_t *passp; 69511068SJohn.Danielson@Sun.COM char *addr; 69610696SDavid.Hollister@Sun.COM 69711068SJohn.Danielson@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, (id_t)addrid); 69811068SJohn.Danielson@Sun.COM ASSERT(passp); 69911068SJohn.Danielson@Sun.COM 70011068SJohn.Danielson@Sun.COM addr = damap_id2addr(damapp, addrid); 70111068SJohn.Danielson@Sun.COM DTRACE_PROBE4(damap__id__rele, char *, mapp->dam_name, char *, addr, 70211068SJohn.Danielson@Sun.COM dam_t *, mapp, int, passp->da_ref); 70311068SJohn.Danielson@Sun.COM 70411068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 70511068SJohn.Danielson@Sun.COM 70611068SJohn.Danielson@Sun.COM /* 70711068SJohn.Danielson@Sun.COM * teardown address if last outstanding reference 70811068SJohn.Danielson@Sun.COM */ 70911068SJohn.Danielson@Sun.COM if (--passp->da_ref == 0) 71011068SJohn.Danielson@Sun.COM dam_addr_release(mapp, (id_t)addrid); 71111068SJohn.Danielson@Sun.COM 71211068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 71310696SDavid.Hollister@Sun.COM } 71410696SDavid.Hollister@Sun.COM 71510696SDavid.Hollister@Sun.COM /* 71610696SDavid.Hollister@Sun.COM * Return current reference count on address reference in map 71710696SDavid.Hollister@Sun.COM * 71810696SDavid.Hollister@Sun.COM * damapp: address map handle 71911068SJohn.Danielson@Sun.COM * addrid: address ID 72010696SDavid.Hollister@Sun.COM * 72110696SDavid.Hollister@Sun.COM * Returns: DAM_SUCCESS 72210696SDavid.Hollister@Sun.COM * DAM_FAILURE 72310696SDavid.Hollister@Sun.COM */ 72410696SDavid.Hollister@Sun.COM int 72511068SJohn.Danielson@Sun.COM damap_id_ref(damap_t *damapp, damap_id_t addrid) 72610696SDavid.Hollister@Sun.COM { 72710696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 72810696SDavid.Hollister@Sun.COM dam_da_t *passp; 72910696SDavid.Hollister@Sun.COM int ref = -1; 73010696SDavid.Hollister@Sun.COM 73111068SJohn.Danielson@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, (id_t)addrid); 73210696SDavid.Hollister@Sun.COM if (passp) 73310696SDavid.Hollister@Sun.COM ref = passp->da_ref; 73411068SJohn.Danielson@Sun.COM 73510696SDavid.Hollister@Sun.COM return (ref); 73610696SDavid.Hollister@Sun.COM } 73710696SDavid.Hollister@Sun.COM 73810696SDavid.Hollister@Sun.COM /* 73910696SDavid.Hollister@Sun.COM * Return next address ID in list 74010696SDavid.Hollister@Sun.COM * 74110696SDavid.Hollister@Sun.COM * damapp: address map handle 74210696SDavid.Hollister@Sun.COM * damap_list: address ID list passed to config|unconfig 74310696SDavid.Hollister@Sun.COM * returned by look by lookup_all 74410696SDavid.Hollister@Sun.COM * last: last ID returned, 0 is start of list 74510696SDavid.Hollister@Sun.COM * 74610696SDavid.Hollister@Sun.COM * Returns: addrid Next ID from the list 74710696SDavid.Hollister@Sun.COM * 0 End of the list 74810696SDavid.Hollister@Sun.COM */ 74910696SDavid.Hollister@Sun.COM damap_id_t 75010696SDavid.Hollister@Sun.COM damap_id_next(damap_t *damapp, damap_id_list_t damap_list, damap_id_t last) 75110696SDavid.Hollister@Sun.COM { 75210696SDavid.Hollister@Sun.COM int i, start; 75310696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 75410696SDavid.Hollister@Sun.COM bitset_t *dam_list = (bitset_t *)damap_list; 75510696SDavid.Hollister@Sun.COM 75610696SDavid.Hollister@Sun.COM if (!mapp || !dam_list) 75710696SDavid.Hollister@Sun.COM return ((damap_id_t)0); 75810696SDavid.Hollister@Sun.COM 75910696SDavid.Hollister@Sun.COM start = (int)last + 1; 76011068SJohn.Danielson@Sun.COM for (i = start; i < mapp->dam_high; i++) { 76111068SJohn.Danielson@Sun.COM if (bitset_in_set(dam_list, i)) { 76210696SDavid.Hollister@Sun.COM return ((damap_id_t)i); 76311068SJohn.Danielson@Sun.COM } 76411068SJohn.Danielson@Sun.COM } 76510696SDavid.Hollister@Sun.COM return ((damap_id_t)0); 76610696SDavid.Hollister@Sun.COM } 76710696SDavid.Hollister@Sun.COM 76810696SDavid.Hollister@Sun.COM /* 76910696SDavid.Hollister@Sun.COM * Set config private data 77010696SDavid.Hollister@Sun.COM * 77110696SDavid.Hollister@Sun.COM * damapp: address map handle 77211068SJohn.Danielson@Sun.COM * addrid: address ID 77310696SDavid.Hollister@Sun.COM * cfg_priv: configuration private data 77410696SDavid.Hollister@Sun.COM * 77510696SDavid.Hollister@Sun.COM */ 77610696SDavid.Hollister@Sun.COM void 77711068SJohn.Danielson@Sun.COM damap_id_priv_set(damap_t *damapp, damap_id_t addrid, void *cfg_priv) 77810696SDavid.Hollister@Sun.COM { 77910696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 78010696SDavid.Hollister@Sun.COM dam_da_t *passp; 78110696SDavid.Hollister@Sun.COM 78211068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 78311068SJohn.Danielson@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, (id_t)addrid); 78410696SDavid.Hollister@Sun.COM if (!passp) { 78511068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 78610696SDavid.Hollister@Sun.COM return; 78710696SDavid.Hollister@Sun.COM } 78810696SDavid.Hollister@Sun.COM passp->da_cfg_priv = cfg_priv; 78911068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 79010696SDavid.Hollister@Sun.COM } 79110696SDavid.Hollister@Sun.COM 79210696SDavid.Hollister@Sun.COM /* 79310696SDavid.Hollister@Sun.COM * Get config private data 79410696SDavid.Hollister@Sun.COM * 79510696SDavid.Hollister@Sun.COM * damapp: address map handle 79611068SJohn.Danielson@Sun.COM * addrid: address ID 79710696SDavid.Hollister@Sun.COM * 79810696SDavid.Hollister@Sun.COM * Returns: configuration private data 79910696SDavid.Hollister@Sun.COM */ 80010696SDavid.Hollister@Sun.COM void * 80111068SJohn.Danielson@Sun.COM damap_id_priv_get(damap_t *damapp, damap_id_t addrid) 80210696SDavid.Hollister@Sun.COM { 80310696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 80410696SDavid.Hollister@Sun.COM dam_da_t *passp; 80510696SDavid.Hollister@Sun.COM void *rv; 80610696SDavid.Hollister@Sun.COM 80711068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 80811068SJohn.Danielson@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, (id_t)addrid); 80910696SDavid.Hollister@Sun.COM if (!passp) { 81011068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 81110696SDavid.Hollister@Sun.COM return (NULL); 81210696SDavid.Hollister@Sun.COM } 81310696SDavid.Hollister@Sun.COM rv = passp->da_cfg_priv; 81411068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 81510696SDavid.Hollister@Sun.COM return (rv); 81610696SDavid.Hollister@Sun.COM } 81710696SDavid.Hollister@Sun.COM 81810696SDavid.Hollister@Sun.COM /* 81910696SDavid.Hollister@Sun.COM * Lookup a single address in the active address map 82010696SDavid.Hollister@Sun.COM * 82110696SDavid.Hollister@Sun.COM * damapp: address map handle 82210696SDavid.Hollister@Sun.COM * address: address string 82310696SDavid.Hollister@Sun.COM * 82410696SDavid.Hollister@Sun.COM * Returns: ID of active/stable address 82510696SDavid.Hollister@Sun.COM * 0 Address not in stable set 82610696SDavid.Hollister@Sun.COM * 82710696SDavid.Hollister@Sun.COM * Future: Allow the caller to wait for stabilize before returning not found. 82810696SDavid.Hollister@Sun.COM */ 82910696SDavid.Hollister@Sun.COM damap_id_t 83010696SDavid.Hollister@Sun.COM damap_lookup(damap_t *damapp, char *address) 83110696SDavid.Hollister@Sun.COM { 83210696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 83310696SDavid.Hollister@Sun.COM id_t addrid = 0; 83410696SDavid.Hollister@Sun.COM dam_da_t *passp = NULL; 83510696SDavid.Hollister@Sun.COM 83611068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__lookup, char *, mapp->dam_name, 83711068SJohn.Danielson@Sun.COM char *, address, dam_t *, mapp); 83811068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 83911068SJohn.Danielson@Sun.COM if (!mapp->dam_high) 84011068SJohn.Danielson@Sun.COM addrid = 0; 84111068SJohn.Danielson@Sun.COM else 84211068SJohn.Danielson@Sun.COM addrid = ddi_strid_str2id(mapp->dam_addr_hash, address); 84310696SDavid.Hollister@Sun.COM if (addrid) { 84410696SDavid.Hollister@Sun.COM if (DAM_IS_STABLE(mapp, addrid)) { 84510696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 84610696SDavid.Hollister@Sun.COM ASSERT(passp); 84710696SDavid.Hollister@Sun.COM if (passp) { 84810696SDavid.Hollister@Sun.COM passp->da_ref++; 84910696SDavid.Hollister@Sun.COM } else { 85010696SDavid.Hollister@Sun.COM addrid = 0; 85110696SDavid.Hollister@Sun.COM } 85210696SDavid.Hollister@Sun.COM } else { 85310696SDavid.Hollister@Sun.COM addrid = 0; 85410696SDavid.Hollister@Sun.COM } 85510696SDavid.Hollister@Sun.COM } 85611068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 85711068SJohn.Danielson@Sun.COM DTRACE_PROBE4(damap__lookup__return, char *, mapp->dam_name, 85811068SJohn.Danielson@Sun.COM char *, address, dam_t *, mapp, int, addrid); 85910696SDavid.Hollister@Sun.COM return ((damap_id_t)addrid); 86010696SDavid.Hollister@Sun.COM } 86110696SDavid.Hollister@Sun.COM 86210696SDavid.Hollister@Sun.COM 86310696SDavid.Hollister@Sun.COM /* 86410696SDavid.Hollister@Sun.COM * Return the list of stable addresses in the map 86510696SDavid.Hollister@Sun.COM * 86610696SDavid.Hollister@Sun.COM * damapp: address map handle 86710696SDavid.Hollister@Sun.COM * id_listp: pointer to list of address IDs in stable map (returned) 86810696SDavid.Hollister@Sun.COM * 86910696SDavid.Hollister@Sun.COM * Returns: # of entries returned in alist 87010696SDavid.Hollister@Sun.COM */ 87110696SDavid.Hollister@Sun.COM int 87210696SDavid.Hollister@Sun.COM damap_lookup_all(damap_t *damapp, damap_id_list_t *id_listp) 87310696SDavid.Hollister@Sun.COM { 87410696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 87510696SDavid.Hollister@Sun.COM int mapsz = mapp->dam_size; 87610696SDavid.Hollister@Sun.COM int n_ids, i; 87710696SDavid.Hollister@Sun.COM bitset_t *bsp; 87811068SJohn.Danielson@Sun.COM char *addrp; 87910696SDavid.Hollister@Sun.COM dam_da_t *passp; 88010696SDavid.Hollister@Sun.COM 88111068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__lookup__all, char *, mapp->dam_name, 88211068SJohn.Danielson@Sun.COM dam_t *, mapp); 88311068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 88411068SJohn.Danielson@Sun.COM if (!mapp->dam_high) { 88511068SJohn.Danielson@Sun.COM *id_listp = (damap_id_list_t)NULL; 88611068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 88711068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__lookup__all__nomap, char *, 88811068SJohn.Danielson@Sun.COM mapp->dam_name, dam_t *, mapp, int, 0); 88911068SJohn.Danielson@Sun.COM return (0); 89011068SJohn.Danielson@Sun.COM } 89110696SDavid.Hollister@Sun.COM bsp = kmem_alloc(sizeof (*bsp), KM_SLEEP); 89210696SDavid.Hollister@Sun.COM bitset_init(bsp); 89310696SDavid.Hollister@Sun.COM bitset_resize(bsp, mapsz); 89410696SDavid.Hollister@Sun.COM bitset_copy(&mapp->dam_active_set, bsp); 89510696SDavid.Hollister@Sun.COM for (n_ids = 0, i = 1; i < mapsz; i++) { 89610696SDavid.Hollister@Sun.COM if (bitset_in_set(bsp, i)) { 89710696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, i); 89810696SDavid.Hollister@Sun.COM ASSERT(passp); 89910696SDavid.Hollister@Sun.COM if (passp) { 90011068SJohn.Danielson@Sun.COM addrp = damap_id2addr(damapp, i); 90111068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__lookup__all__item, char *, 90211068SJohn.Danielson@Sun.COM mapp->dam_name, char *, addrp, dam_t *, 90311068SJohn.Danielson@Sun.COM mapp); 90410696SDavid.Hollister@Sun.COM passp->da_ref++; 90510696SDavid.Hollister@Sun.COM n_ids++; 90610696SDavid.Hollister@Sun.COM } 90710696SDavid.Hollister@Sun.COM } 90810696SDavid.Hollister@Sun.COM } 90910696SDavid.Hollister@Sun.COM if (n_ids) { 91010696SDavid.Hollister@Sun.COM *id_listp = (damap_id_list_t)bsp; 91111068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 91210696SDavid.Hollister@Sun.COM return (n_ids); 91310696SDavid.Hollister@Sun.COM } else { 91410696SDavid.Hollister@Sun.COM *id_listp = (damap_id_list_t)NULL; 91510696SDavid.Hollister@Sun.COM bitset_fini(bsp); 91610696SDavid.Hollister@Sun.COM kmem_free(bsp, sizeof (*bsp)); 91711068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 91810696SDavid.Hollister@Sun.COM return (0); 91910696SDavid.Hollister@Sun.COM } 92010696SDavid.Hollister@Sun.COM } 92110696SDavid.Hollister@Sun.COM 92210696SDavid.Hollister@Sun.COM /* 92310696SDavid.Hollister@Sun.COM * Release the address list returned by damap_lookup_all() 92410696SDavid.Hollister@Sun.COM * 92510696SDavid.Hollister@Sun.COM * mapp: address map handle 92610696SDavid.Hollister@Sun.COM * id_list: list of address IDs returned in damap_lookup_all() 92710696SDavid.Hollister@Sun.COM */ 92810696SDavid.Hollister@Sun.COM void 92910696SDavid.Hollister@Sun.COM damap_id_list_rele(damap_t *damapp, damap_id_list_t id_list) 93010696SDavid.Hollister@Sun.COM { 93110696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)damapp; 93210696SDavid.Hollister@Sun.COM int i; 93310696SDavid.Hollister@Sun.COM 93410696SDavid.Hollister@Sun.COM if (id_list == NULL) 93510696SDavid.Hollister@Sun.COM return; 93610696SDavid.Hollister@Sun.COM 93711068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 93810696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 93910696SDavid.Hollister@Sun.COM if (bitset_in_set((bitset_t *)id_list, i)) 94011068SJohn.Danielson@Sun.COM (void) dam_addr_release(mapp, i); 94110696SDavid.Hollister@Sun.COM } 94211068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 94310696SDavid.Hollister@Sun.COM bitset_fini((bitset_t *)id_list); 94410696SDavid.Hollister@Sun.COM kmem_free((void *)id_list, sizeof (bitset_t)); 94510696SDavid.Hollister@Sun.COM } 94610696SDavid.Hollister@Sun.COM 94710696SDavid.Hollister@Sun.COM /* 94811068SJohn.Danielson@Sun.COM * activate an address that has passed the stabilization interval 94911068SJohn.Danielson@Sun.COM */ 95011068SJohn.Danielson@Sun.COM static void 95111068SJohn.Danielson@Sun.COM dam_addr_activate(dam_t *mapp, id_t addrid) 95211068SJohn.Danielson@Sun.COM { 95311068SJohn.Danielson@Sun.COM dam_da_t *passp; 95411068SJohn.Danielson@Sun.COM int config_rv; 95511068SJohn.Danielson@Sun.COM char *addrstr; 95611068SJohn.Danielson@Sun.COM 95711068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 95811068SJohn.Danielson@Sun.COM bitset_add(&mapp->dam_active_set, addrid); 95911068SJohn.Danielson@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 96011068SJohn.Danielson@Sun.COM ASSERT(passp); 96111068SJohn.Danielson@Sun.COM 96211068SJohn.Danielson@Sun.COM /* 96311068SJohn.Danielson@Sun.COM * copy the reported nvlist and provider private data 96411068SJohn.Danielson@Sun.COM */ 96511068SJohn.Danielson@Sun.COM addrstr = ddi_strid_id2str(mapp->dam_addr_hash, addrid); 96611068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__activate__start, char *, mapp->dam_name, 96711068SJohn.Danielson@Sun.COM char *, addrstr, dam_t *, mapp); 96811068SJohn.Danielson@Sun.COM passp->da_nvl = passp->da_nvl_rpt; 96911068SJohn.Danielson@Sun.COM passp->da_ppriv = passp->da_ppriv_rpt; 97011068SJohn.Danielson@Sun.COM passp->da_ppriv_rpt = NULL; 97111068SJohn.Danielson@Sun.COM passp->da_nvl_rpt = NULL; 97211068SJohn.Danielson@Sun.COM passp->da_last_stable = gethrtime(); 97311068SJohn.Danielson@Sun.COM passp->da_stable_cnt++; 97411068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 97511068SJohn.Danielson@Sun.COM if (mapp->dam_activate_cb) { 97611068SJohn.Danielson@Sun.COM (*mapp->dam_activate_cb)(mapp->dam_activate_arg, addrstr, 97711068SJohn.Danielson@Sun.COM addrid, &passp->da_ppriv_rpt); 97811068SJohn.Danielson@Sun.COM } 97911068SJohn.Danielson@Sun.COM 98011068SJohn.Danielson@Sun.COM /* 98111068SJohn.Danielson@Sun.COM * call the address-specific configuration action as part of 98211068SJohn.Danielson@Sun.COM * activation. 98311068SJohn.Danielson@Sun.COM */ 98411068SJohn.Danielson@Sun.COM config_rv = (*mapp->dam_configure_cb)(mapp->dam_config_arg, mapp, 98511068SJohn.Danielson@Sun.COM addrid); 98611068SJohn.Danielson@Sun.COM if (config_rv != DAM_SUCCESS) { 98711068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 98811068SJohn.Danielson@Sun.COM passp->da_flags |= DA_FAILED_CONFIG; 98911068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 99011068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__activate__config__failure, 99111068SJohn.Danielson@Sun.COM char *, mapp->dam_name, char *, addrstr, dam_t *, mapp); 99211363SReed.Liu@Sun.COM dam_deact_cleanup(mapp, addrid, addrstr, 99311363SReed.Liu@Sun.COM DAMAP_DEACT_RSN_CFG_FAIL); 99411363SReed.Liu@Sun.COM } else { 99511363SReed.Liu@Sun.COM DTRACE_PROBE3(damap__addr__activate__end, char *, 99611363SReed.Liu@Sun.COM mapp->dam_name, char *, addrstr, dam_t *, mapp); 99711068SJohn.Danielson@Sun.COM } 99811068SJohn.Danielson@Sun.COM } 99911068SJohn.Danielson@Sun.COM 100011068SJohn.Danielson@Sun.COM /* 100111068SJohn.Danielson@Sun.COM * deactivate a previously stable address 100211068SJohn.Danielson@Sun.COM */ 100311068SJohn.Danielson@Sun.COM static void 100411068SJohn.Danielson@Sun.COM dam_addr_deactivate(dam_t *mapp, id_t addrid) 100511068SJohn.Danielson@Sun.COM { 100611068SJohn.Danielson@Sun.COM char *addrstr; 100711068SJohn.Danielson@Sun.COM 100811068SJohn.Danielson@Sun.COM addrstr = ddi_strid_id2str(mapp->dam_addr_hash, addrid); 100911068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__deactivate__start, char *, mapp->dam_name, 101011068SJohn.Danielson@Sun.COM char *, addrstr, dam_t *, mapp); 101111068SJohn.Danielson@Sun.COM 101211068SJohn.Danielson@Sun.COM /* 101311068SJohn.Danielson@Sun.COM * call the unconfiguration callback 101411068SJohn.Danielson@Sun.COM */ 101511068SJohn.Danielson@Sun.COM (*mapp->dam_unconfig_cb)(mapp->dam_config_arg, mapp, addrid); 101611363SReed.Liu@Sun.COM dam_deact_cleanup(mapp, addrid, addrstr, DAMAP_DEACT_RSN_GONE); 101711363SReed.Liu@Sun.COM } 101811363SReed.Liu@Sun.COM 101911363SReed.Liu@Sun.COM static void 102011363SReed.Liu@Sun.COM dam_deact_cleanup(dam_t *mapp, id_t addrid, char *addrstr, 102111363SReed.Liu@Sun.COM damap_deact_rsn_t deact_rsn) 102211363SReed.Liu@Sun.COM { 102311363SReed.Liu@Sun.COM dam_da_t *passp; 102411363SReed.Liu@Sun.COM 102511068SJohn.Danielson@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 102611068SJohn.Danielson@Sun.COM ASSERT(passp); 102711068SJohn.Danielson@Sun.COM if (mapp->dam_deactivate_cb) 102811068SJohn.Danielson@Sun.COM (*mapp->dam_deactivate_cb)(mapp->dam_activate_arg, 102911068SJohn.Danielson@Sun.COM ddi_strid_id2str(mapp->dam_addr_hash, addrid), 103011363SReed.Liu@Sun.COM addrid, passp->da_ppriv, deact_rsn); 103111068SJohn.Danielson@Sun.COM 103211068SJohn.Danielson@Sun.COM /* 103311068SJohn.Danielson@Sun.COM * clear the active bit and free the backing info for 103411068SJohn.Danielson@Sun.COM * this address 103511068SJohn.Danielson@Sun.COM */ 103611068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 103711068SJohn.Danielson@Sun.COM bitset_del(&mapp->dam_active_set, addrid); 103811068SJohn.Danielson@Sun.COM passp->da_ppriv = NULL; 103911068SJohn.Danielson@Sun.COM if (passp->da_nvl) 104011068SJohn.Danielson@Sun.COM nvlist_free(passp->da_nvl); 104111068SJohn.Danielson@Sun.COM passp->da_nvl = NULL; 104211068SJohn.Danielson@Sun.COM passp->da_ppriv_rpt = NULL; 104311068SJohn.Danielson@Sun.COM if (passp->da_nvl_rpt) 104411068SJohn.Danielson@Sun.COM nvlist_free(passp->da_nvl_rpt); 104511068SJohn.Danielson@Sun.COM passp->da_nvl_rpt = NULL; 104611068SJohn.Danielson@Sun.COM 104711068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__deactivate__end, char *, mapp->dam_name, 104811068SJohn.Danielson@Sun.COM char *, addrstr, dam_t *, mapp); 104911068SJohn.Danielson@Sun.COM 105011068SJohn.Danielson@Sun.COM (void) dam_addr_release(mapp, addrid); 105111068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 105211068SJohn.Danielson@Sun.COM } 105311068SJohn.Danielson@Sun.COM 105411068SJohn.Danielson@Sun.COM /* 105511068SJohn.Danielson@Sun.COM * taskq callback for multi-thread activation 105611068SJohn.Danielson@Sun.COM */ 105711068SJohn.Danielson@Sun.COM static void 105811068SJohn.Danielson@Sun.COM dam_tq_config(void *arg) 105911068SJohn.Danielson@Sun.COM { 106011068SJohn.Danielson@Sun.COM cfg_tqd_t *tqd = (cfg_tqd_t *)arg; 106111068SJohn.Danielson@Sun.COM 106211068SJohn.Danielson@Sun.COM dam_addr_activate(tqd->tqd_mapp, tqd->tqd_id); 106311068SJohn.Danielson@Sun.COM kmem_free(tqd, sizeof (*tqd)); 106411068SJohn.Danielson@Sun.COM } 106511068SJohn.Danielson@Sun.COM 106611068SJohn.Danielson@Sun.COM /* 106711068SJohn.Danielson@Sun.COM * taskq callback for multi-thread deactivation 106811068SJohn.Danielson@Sun.COM */ 106911068SJohn.Danielson@Sun.COM static void 107011068SJohn.Danielson@Sun.COM dam_tq_unconfig(void *arg) 107111068SJohn.Danielson@Sun.COM { 107211068SJohn.Danielson@Sun.COM cfg_tqd_t *tqd = (cfg_tqd_t *)arg; 107311068SJohn.Danielson@Sun.COM 107411068SJohn.Danielson@Sun.COM dam_addr_deactivate(tqd->tqd_mapp, tqd->tqd_id); 107511068SJohn.Danielson@Sun.COM kmem_free(tqd, sizeof (*tqd)); 107611068SJohn.Danielson@Sun.COM } 107711068SJohn.Danielson@Sun.COM 107811068SJohn.Danielson@Sun.COM /* 107910696SDavid.Hollister@Sun.COM * Activate a set of stabilized addresses 108010696SDavid.Hollister@Sun.COM */ 108110696SDavid.Hollister@Sun.COM static void 108211068SJohn.Danielson@Sun.COM dam_addrset_activate(dam_t *mapp, bitset_t *activate) 108310696SDavid.Hollister@Sun.COM { 108411068SJohn.Danielson@Sun.COM 108511068SJohn.Danielson@Sun.COM int i, nset; 108611068SJohn.Danielson@Sun.COM taskq_t *tqp = NULL; 108711068SJohn.Danielson@Sun.COM cfg_tqd_t *tqd = NULL; 108811068SJohn.Danielson@Sun.COM char tqn[TASKQ_NAMELEN]; 108911068SJohn.Danielson@Sun.COM extern pri_t maxclsyspri; 109010696SDavid.Hollister@Sun.COM 109111068SJohn.Danielson@Sun.COM if (mapp->dam_options & DAMAP_MTCONFIG) { 109211068SJohn.Danielson@Sun.COM /* 109311068SJohn.Danielson@Sun.COM * calculate the # of taskq threads to create 109411068SJohn.Danielson@Sun.COM */ 109511068SJohn.Danielson@Sun.COM for (i = 1, nset = 0; i < mapp->dam_high; i++) 109611068SJohn.Danielson@Sun.COM if (bitset_in_set(activate, i)) 109711068SJohn.Danielson@Sun.COM nset++; 109811068SJohn.Danielson@Sun.COM ASSERT(nset); 109911068SJohn.Danielson@Sun.COM (void) snprintf(tqn, sizeof (tqn), "actv-%s", mapp->dam_name); 110011068SJohn.Danielson@Sun.COM tqp = taskq_create(tqn, nset, maxclsyspri, 1, 110111068SJohn.Danielson@Sun.COM INT_MAX, TASKQ_PREPOPULATE); 110211068SJohn.Danielson@Sun.COM } 110310696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 110411068SJohn.Danielson@Sun.COM if (bitset_in_set(activate, i)) { 110511068SJohn.Danielson@Sun.COM if (!tqp) 110611068SJohn.Danielson@Sun.COM dam_addr_activate(mapp, i); 110711068SJohn.Danielson@Sun.COM else { 110811068SJohn.Danielson@Sun.COM /* 110911068SJohn.Danielson@Sun.COM * multi-threaded activation 111011068SJohn.Danielson@Sun.COM */ 111111068SJohn.Danielson@Sun.COM tqd = kmem_alloc(sizeof (*tqd), KM_SLEEP); 111211068SJohn.Danielson@Sun.COM tqd->tqd_mapp = mapp; 111311068SJohn.Danielson@Sun.COM tqd->tqd_id = i; 111411068SJohn.Danielson@Sun.COM (void) taskq_dispatch(tqp, dam_tq_config, 111511854SChris.Horne@Sun.COM tqd, TQ_SLEEP); 111611068SJohn.Danielson@Sun.COM } 111710696SDavid.Hollister@Sun.COM } 111811068SJohn.Danielson@Sun.COM } 111911068SJohn.Danielson@Sun.COM if (tqp) { 112011068SJohn.Danielson@Sun.COM taskq_wait(tqp); 112111068SJohn.Danielson@Sun.COM taskq_destroy(tqp); 112210696SDavid.Hollister@Sun.COM } 112310696SDavid.Hollister@Sun.COM } 112410696SDavid.Hollister@Sun.COM 112510696SDavid.Hollister@Sun.COM /* 112611068SJohn.Danielson@Sun.COM * Deactivate a set of stabilized addresses 112710696SDavid.Hollister@Sun.COM */ 112810696SDavid.Hollister@Sun.COM static void 112911068SJohn.Danielson@Sun.COM dam_addrset_deactivate(dam_t *mapp, bitset_t *deactivate) 113010696SDavid.Hollister@Sun.COM { 113111068SJohn.Danielson@Sun.COM int i, nset; 113211068SJohn.Danielson@Sun.COM taskq_t *tqp = NULL; 113311068SJohn.Danielson@Sun.COM cfg_tqd_t *tqd = NULL; 113411068SJohn.Danielson@Sun.COM char tqn[TASKQ_NAMELEN]; 113511068SJohn.Danielson@Sun.COM 113611068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__addrset__deactivate, char *, mapp->dam_name, 113711068SJohn.Danielson@Sun.COM dam_t *, mapp); 113810696SDavid.Hollister@Sun.COM 113911068SJohn.Danielson@Sun.COM if (mapp->dam_options & DAMAP_MTCONFIG) { 114011068SJohn.Danielson@Sun.COM /* 114111068SJohn.Danielson@Sun.COM * compute the # of taskq threads to dispatch 114211068SJohn.Danielson@Sun.COM */ 114311068SJohn.Danielson@Sun.COM for (i = 1, nset = 0; i < mapp->dam_high; i++) 114411068SJohn.Danielson@Sun.COM if (bitset_in_set(deactivate, i)) 114511068SJohn.Danielson@Sun.COM nset++; 114611068SJohn.Danielson@Sun.COM (void) snprintf(tqn, sizeof (tqn), "deactv-%s", 114711068SJohn.Danielson@Sun.COM mapp->dam_name); 114811068SJohn.Danielson@Sun.COM tqp = taskq_create(tqn, nset, maxclsyspri, 1, 114911068SJohn.Danielson@Sun.COM INT_MAX, TASKQ_PREPOPULATE); 115011068SJohn.Danielson@Sun.COM } 115110696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 115211068SJohn.Danielson@Sun.COM if (bitset_in_set(deactivate, i)) { 115311068SJohn.Danielson@Sun.COM if (!tqp) { 115411068SJohn.Danielson@Sun.COM dam_addr_deactivate(mapp, i); 115511068SJohn.Danielson@Sun.COM } else { 115611068SJohn.Danielson@Sun.COM tqd = kmem_alloc(sizeof (*tqd), KM_SLEEP); 115711068SJohn.Danielson@Sun.COM tqd->tqd_mapp = mapp; 115811068SJohn.Danielson@Sun.COM tqd->tqd_id = i; 115911068SJohn.Danielson@Sun.COM (void) taskq_dispatch(tqp, 116011854SChris.Horne@Sun.COM dam_tq_unconfig, tqd, TQ_SLEEP); 116111068SJohn.Danielson@Sun.COM } 116210696SDavid.Hollister@Sun.COM } 116310696SDavid.Hollister@Sun.COM } 116411068SJohn.Danielson@Sun.COM 116511068SJohn.Danielson@Sun.COM if (tqp) { 116611068SJohn.Danielson@Sun.COM taskq_wait(tqp); 116711068SJohn.Danielson@Sun.COM taskq_destroy(tqp); 116811068SJohn.Danielson@Sun.COM } 116910696SDavid.Hollister@Sun.COM } 117010696SDavid.Hollister@Sun.COM 117110696SDavid.Hollister@Sun.COM /* 117211068SJohn.Danielson@Sun.COM * Release a previously activated address 117310696SDavid.Hollister@Sun.COM */ 117410696SDavid.Hollister@Sun.COM static void 117511068SJohn.Danielson@Sun.COM dam_addr_release(dam_t *mapp, id_t addrid) 117610696SDavid.Hollister@Sun.COM { 117710696SDavid.Hollister@Sun.COM dam_da_t *passp; 117811068SJohn.Danielson@Sun.COM char *addrstr; 117910696SDavid.Hollister@Sun.COM 118011068SJohn.Danielson@Sun.COM 118111068SJohn.Danielson@Sun.COM ASSERT(mutex_owned(&mapp->dam_lock)); 118210696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 118310696SDavid.Hollister@Sun.COM ASSERT(passp); 118410696SDavid.Hollister@Sun.COM 118511068SJohn.Danielson@Sun.COM addrstr = ddi_strid_id2str(mapp->dam_addr_hash, addrid); 118611068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__release, char *, mapp->dam_name, 118711068SJohn.Danielson@Sun.COM char *, addrstr, dam_t *, mapp); 118810696SDavid.Hollister@Sun.COM 118910696SDavid.Hollister@Sun.COM /* 119011068SJohn.Danielson@Sun.COM * defer releasing the address until outstanding references 119111068SJohn.Danielson@Sun.COM * are released 119210696SDavid.Hollister@Sun.COM */ 119311068SJohn.Danielson@Sun.COM if (passp->da_ref > 1) { 119411068SJohn.Danielson@Sun.COM DTRACE_PROBE4(damap__addr__release__outstanding__refs, 119511068SJohn.Danielson@Sun.COM char *, mapp->dam_name, char *, addrstr, dam_t *, mapp, 119611068SJohn.Danielson@Sun.COM int, passp->da_ref); 119710696SDavid.Hollister@Sun.COM return; 119811068SJohn.Danielson@Sun.COM } 119910696SDavid.Hollister@Sun.COM 120010696SDavid.Hollister@Sun.COM /* 120111068SJohn.Danielson@Sun.COM * allow pending reports to stabilize 120210696SDavid.Hollister@Sun.COM */ 120311068SJohn.Danielson@Sun.COM if (DAM_IN_REPORT(mapp, addrid)) { 120411068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__release__report__pending, 120511068SJohn.Danielson@Sun.COM char *, mapp->dam_name, char *, addrstr, dam_t *, mapp); 120610696SDavid.Hollister@Sun.COM return; 120710696SDavid.Hollister@Sun.COM } 120811068SJohn.Danielson@Sun.COM 120910696SDavid.Hollister@Sun.COM ddi_strid_free(mapp->dam_addr_hash, addrid); 121010696SDavid.Hollister@Sun.COM ddi_soft_state_free(mapp->dam_da, addrid); 121110696SDavid.Hollister@Sun.COM } 121210696SDavid.Hollister@Sun.COM 121310696SDavid.Hollister@Sun.COM /* 121410696SDavid.Hollister@Sun.COM * process stabilized address reports 121510696SDavid.Hollister@Sun.COM */ 121610696SDavid.Hollister@Sun.COM static void 121711068SJohn.Danielson@Sun.COM dam_stabilize_map(void *arg) 121810696SDavid.Hollister@Sun.COM { 121910696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)arg; 122010696SDavid.Hollister@Sun.COM bitset_t delta; 122110696SDavid.Hollister@Sun.COM bitset_t cfg; 122210696SDavid.Hollister@Sun.COM bitset_t uncfg; 122310696SDavid.Hollister@Sun.COM int has_cfg, has_uncfg; 122411068SJohn.Danielson@Sun.COM uint32_t i, n_active; 122511068SJohn.Danielson@Sun.COM 122611068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__stabilize__map, char *, mapp->dam_name, 122711068SJohn.Danielson@Sun.COM dam_t *, mapp); 122810696SDavid.Hollister@Sun.COM 122910696SDavid.Hollister@Sun.COM bitset_init(&delta); 123010696SDavid.Hollister@Sun.COM bitset_resize(&delta, mapp->dam_size); 123110696SDavid.Hollister@Sun.COM bitset_init(&cfg); 123210696SDavid.Hollister@Sun.COM bitset_resize(&cfg, mapp->dam_size); 123310696SDavid.Hollister@Sun.COM bitset_init(&uncfg); 123410696SDavid.Hollister@Sun.COM bitset_resize(&uncfg, mapp->dam_size); 123510696SDavid.Hollister@Sun.COM 123611068SJohn.Danielson@Sun.COM /* 123711068SJohn.Danielson@Sun.COM * determine which addresses have changed during 123811068SJohn.Danielson@Sun.COM * this stabilization cycle 123911068SJohn.Danielson@Sun.COM */ 124011068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 124111068SJohn.Danielson@Sun.COM ASSERT(mapp->dam_flags & DAM_SPEND); 124210696SDavid.Hollister@Sun.COM if (!bitset_xor(&mapp->dam_active_set, &mapp->dam_stable_set, 124310696SDavid.Hollister@Sun.COM &delta)) { 124411068SJohn.Danielson@Sun.COM /* 124511068SJohn.Danielson@Sun.COM * no difference 124611068SJohn.Danielson@Sun.COM */ 124710696SDavid.Hollister@Sun.COM bitset_zero(&mapp->dam_stable_set); 124811068SJohn.Danielson@Sun.COM mapp->dam_flags &= ~DAM_SPEND; 124911068SJohn.Danielson@Sun.COM cv_signal(&mapp->dam_cv); 125011068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 125110696SDavid.Hollister@Sun.COM bitset_fini(&uncfg); 125210696SDavid.Hollister@Sun.COM bitset_fini(&cfg); 125310696SDavid.Hollister@Sun.COM bitset_fini(&delta); 125411068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__stabilize__map__nochange, char *, 125511068SJohn.Danielson@Sun.COM mapp->dam_name, dam_t *, mapp); 125610696SDavid.Hollister@Sun.COM return; 125710696SDavid.Hollister@Sun.COM } 125811068SJohn.Danielson@Sun.COM 125911068SJohn.Danielson@Sun.COM /* 126011068SJohn.Danielson@Sun.COM * compute the sets of addresses to be activated and deactivated 126111068SJohn.Danielson@Sun.COM */ 126210696SDavid.Hollister@Sun.COM has_cfg = bitset_and(&delta, &mapp->dam_stable_set, &cfg); 126310696SDavid.Hollister@Sun.COM has_uncfg = bitset_and(&delta, &mapp->dam_active_set, &uncfg); 126411068SJohn.Danielson@Sun.COM 126511068SJohn.Danielson@Sun.COM /* 126611068SJohn.Danielson@Sun.COM * drop map lock while invoking callouts 126711068SJohn.Danielson@Sun.COM */ 126811068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 126911068SJohn.Danielson@Sun.COM 127011068SJohn.Danielson@Sun.COM /* 127111068SJohn.Danielson@Sun.COM * activate all newly stable addresss 127211068SJohn.Danielson@Sun.COM */ 127311068SJohn.Danielson@Sun.COM if (has_cfg) 127410696SDavid.Hollister@Sun.COM dam_addrset_activate(mapp, &cfg); 127511068SJohn.Danielson@Sun.COM 127611068SJohn.Danielson@Sun.COM /* 127711068SJohn.Danielson@Sun.COM * deactivate addresss which are no longer in the map 127811068SJohn.Danielson@Sun.COM */ 127911068SJohn.Danielson@Sun.COM if (has_uncfg) 128011068SJohn.Danielson@Sun.COM dam_addrset_deactivate(mapp, &uncfg); 128111068SJohn.Danielson@Sun.COM 128211068SJohn.Danielson@Sun.COM 128311068SJohn.Danielson@Sun.COM /* 128411068SJohn.Danielson@Sun.COM * timestamp the last stable time and increment the kstat keeping 128511068SJohn.Danielson@Sun.COM * the # of of stable cycles for the map 128611068SJohn.Danielson@Sun.COM */ 128711068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 128810696SDavid.Hollister@Sun.COM bitset_zero(&mapp->dam_stable_set); 128910696SDavid.Hollister@Sun.COM mapp->dam_last_stable = gethrtime(); 129010696SDavid.Hollister@Sun.COM mapp->dam_stable_cnt++; 129111068SJohn.Danielson@Sun.COM DAM_INCR_STAT(mapp, dam_cycles); 129211068SJohn.Danielson@Sun.COM 129311068SJohn.Danielson@Sun.COM /* 129411068SJohn.Danielson@Sun.COM * determine the number of stable addresses 129511068SJohn.Danielson@Sun.COM * and update the n_active kstat for this map 129611068SJohn.Danielson@Sun.COM */ 129711068SJohn.Danielson@Sun.COM for (i = 1, n_active = 0; i < mapp->dam_high; i++) 129811068SJohn.Danielson@Sun.COM if (bitset_in_set(&mapp->dam_active_set, i)) 129911068SJohn.Danielson@Sun.COM n_active++; 130011068SJohn.Danielson@Sun.COM DAM_SET_STAT(mapp, dam_active, n_active); 130111068SJohn.Danielson@Sun.COM 130211068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__map__stable__end, char *, mapp->dam_name, 130311068SJohn.Danielson@Sun.COM dam_t *, mapp, int, n_active); 130411068SJohn.Danielson@Sun.COM 130511068SJohn.Danielson@Sun.COM mapp->dam_flags &= ~DAM_SPEND; 130611068SJohn.Danielson@Sun.COM cv_signal(&mapp->dam_cv); 130711068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 130810696SDavid.Hollister@Sun.COM bitset_fini(&uncfg); 130910696SDavid.Hollister@Sun.COM bitset_fini(&cfg); 131010696SDavid.Hollister@Sun.COM bitset_fini(&delta); 131110696SDavid.Hollister@Sun.COM } 131210696SDavid.Hollister@Sun.COM 131310696SDavid.Hollister@Sun.COM /* 131410696SDavid.Hollister@Sun.COM * per-address stabilization timeout 131510696SDavid.Hollister@Sun.COM */ 131610696SDavid.Hollister@Sun.COM static void 131710696SDavid.Hollister@Sun.COM dam_addr_stable_cb(void *arg) 131810696SDavid.Hollister@Sun.COM { 131910696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)arg; 132010696SDavid.Hollister@Sun.COM int i; 132110696SDavid.Hollister@Sun.COM dam_da_t *passp; 132210696SDavid.Hollister@Sun.COM int spend = 0; 132310696SDavid.Hollister@Sun.COM int tpend = 0; 132410696SDavid.Hollister@Sun.COM int64_t next_tmov = mapp->dam_stabletmo; 132510696SDavid.Hollister@Sun.COM int64_t tmo_delta; 132611066Srafael.vanoni@sun.com int64_t ts = ddi_get_lbolt64(); 132710696SDavid.Hollister@Sun.COM 132811068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 132910696SDavid.Hollister@Sun.COM if (mapp->dam_tid == 0) { 133011068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__map__addr__stable__cancelled, char *, 133111068SJohn.Danielson@Sun.COM mapp->dam_name, dam_t *, mapp); 133211068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 133310696SDavid.Hollister@Sun.COM return; 133410696SDavid.Hollister@Sun.COM } 133510696SDavid.Hollister@Sun.COM mapp->dam_tid = 0; 133611068SJohn.Danielson@Sun.COM 133710696SDavid.Hollister@Sun.COM /* 133810696SDavid.Hollister@Sun.COM * If still under stabilization, reschedule timeout, 133911068SJohn.Danielson@Sun.COM * otherwise dispatch the task to activate and deactivate the 134011068SJohn.Danielson@Sun.COM * new stable address 134110696SDavid.Hollister@Sun.COM */ 134210696SDavid.Hollister@Sun.COM if (mapp->dam_flags & DAM_SPEND) { 134311068SJohn.Danielson@Sun.COM DAM_INCR_STAT(mapp, dam_overrun); 134410696SDavid.Hollister@Sun.COM mapp->dam_stable_overrun++; 134510696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, mapp->dam_stabletmo, dam_addr_stable_cb); 134611068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__map__addr__stable__overrun, char *, 134711068SJohn.Danielson@Sun.COM mapp->dam_name, dam_t *, mapp); 134811068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 134910696SDavid.Hollister@Sun.COM return; 135010696SDavid.Hollister@Sun.COM } 135110696SDavid.Hollister@Sun.COM 135211068SJohn.Danielson@Sun.COM DAM_SET_STAT(mapp, dam_overrun, 0); 135311068SJohn.Danielson@Sun.COM mapp->dam_stable_overrun = 0; 135411068SJohn.Danielson@Sun.COM 135511068SJohn.Danielson@Sun.COM /* 135611068SJohn.Danielson@Sun.COM * copy the current active set to the stable map 135711068SJohn.Danielson@Sun.COM * for each address being reported, decrement its 135811068SJohn.Danielson@Sun.COM * stabilize deadline, and if stable, add or remove the 135911068SJohn.Danielson@Sun.COM * address from the stable set 136011068SJohn.Danielson@Sun.COM */ 136110696SDavid.Hollister@Sun.COM bitset_copy(&mapp->dam_active_set, &mapp->dam_stable_set); 136210696SDavid.Hollister@Sun.COM for (i = 1; i < mapp->dam_high; i++) { 136310696SDavid.Hollister@Sun.COM if (!bitset_in_set(&mapp->dam_report_set, i)) 136410696SDavid.Hollister@Sun.COM continue; 136510696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, i); 136610696SDavid.Hollister@Sun.COM ASSERT(passp); 136710696SDavid.Hollister@Sun.COM 136810696SDavid.Hollister@Sun.COM /* report has stabilized */ 136910696SDavid.Hollister@Sun.COM if (passp->da_deadline <= ts) { 137010696SDavid.Hollister@Sun.COM bitset_del(&mapp->dam_report_set, i); 137111068SJohn.Danielson@Sun.COM if (passp->da_flags & DA_RELE) 137210696SDavid.Hollister@Sun.COM bitset_del(&mapp->dam_stable_set, i); 137311068SJohn.Danielson@Sun.COM else 137410696SDavid.Hollister@Sun.COM bitset_add(&mapp->dam_stable_set, i); 137510696SDavid.Hollister@Sun.COM spend++; 137610696SDavid.Hollister@Sun.COM continue; 137710696SDavid.Hollister@Sun.COM } 137810696SDavid.Hollister@Sun.COM 137910696SDavid.Hollister@Sun.COM /* 138011068SJohn.Danielson@Sun.COM * not stabilized, determine next map timeout 138110696SDavid.Hollister@Sun.COM */ 138210696SDavid.Hollister@Sun.COM tpend++; 138310696SDavid.Hollister@Sun.COM tmo_delta = passp->da_deadline - ts; 138410696SDavid.Hollister@Sun.COM if (tmo_delta < next_tmov) 138510696SDavid.Hollister@Sun.COM next_tmov = tmo_delta; 138610696SDavid.Hollister@Sun.COM } 138710696SDavid.Hollister@Sun.COM 138810696SDavid.Hollister@Sun.COM /* 138911068SJohn.Danielson@Sun.COM * schedule system_taskq activation of stabilized reports 139010696SDavid.Hollister@Sun.COM */ 139110696SDavid.Hollister@Sun.COM if (spend) { 139211068SJohn.Danielson@Sun.COM if (taskq_dispatch(system_taskq, dam_stabilize_map, 139311854SChris.Horne@Sun.COM mapp, TQ_NOSLEEP | TQ_NOQUEUE)) { 139411068SJohn.Danielson@Sun.COM mapp->dam_flags |= DAM_SPEND; 139511068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__map__addr__stable__start, char *, 139611068SJohn.Danielson@Sun.COM mapp->dam_name, dam_t *, mapp); 139711068SJohn.Danielson@Sun.COM } else { 139810696SDavid.Hollister@Sun.COM tpend++; 139911854SChris.Horne@Sun.COM 140011854SChris.Horne@Sun.COM /* 140111854SChris.Horne@Sun.COM * Avoid waiting the entire stabalization 140211854SChris.Horne@Sun.COM * time again if taskq_diskpatch fails. 140311854SChris.Horne@Sun.COM */ 140411854SChris.Horne@Sun.COM tmo_delta = drv_usectohz( 140511854SChris.Horne@Sun.COM damap_taskq_dispatch_retry_usec); 140611854SChris.Horne@Sun.COM if (tmo_delta < next_tmov) 140711854SChris.Horne@Sun.COM next_tmov = tmo_delta; 140811068SJohn.Danielson@Sun.COM } 140910696SDavid.Hollister@Sun.COM } 141010696SDavid.Hollister@Sun.COM 141110696SDavid.Hollister@Sun.COM /* 141211068SJohn.Danielson@Sun.COM * reschedule the stabilization timer if there are reports 141311068SJohn.Danielson@Sun.COM * still pending 141410696SDavid.Hollister@Sun.COM */ 141510696SDavid.Hollister@Sun.COM if (tpend) 141610696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, (clock_t)next_tmov, dam_addr_stable_cb); 141711068SJohn.Danielson@Sun.COM 141811068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 141910696SDavid.Hollister@Sun.COM } 142010696SDavid.Hollister@Sun.COM 142110696SDavid.Hollister@Sun.COM /* 142211068SJohn.Danielson@Sun.COM * fullset stabilization timeout callback 142310696SDavid.Hollister@Sun.COM */ 142410696SDavid.Hollister@Sun.COM static void 142511068SJohn.Danielson@Sun.COM dam_addrset_stable_cb(void *arg) 142610696SDavid.Hollister@Sun.COM { 142710696SDavid.Hollister@Sun.COM dam_t *mapp = (dam_t *)arg; 142810696SDavid.Hollister@Sun.COM 142911068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 143010696SDavid.Hollister@Sun.COM if (mapp->dam_tid == 0) { 143111068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 143211068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__map__addrset__stable__cancelled, 143311068SJohn.Danielson@Sun.COM char *, mapp->dam_name, dam_t *, mapp); 143410696SDavid.Hollister@Sun.COM return; 143510696SDavid.Hollister@Sun.COM } 143610696SDavid.Hollister@Sun.COM mapp->dam_tid = 0; 143710696SDavid.Hollister@Sun.COM 143810696SDavid.Hollister@Sun.COM /* 143911068SJohn.Danielson@Sun.COM * If map still underoing stabilization reschedule timeout, 144011068SJohn.Danielson@Sun.COM * else dispatch the task to configure the new stable set of 144111068SJohn.Danielson@Sun.COM * addresses. 144210696SDavid.Hollister@Sun.COM */ 144311854SChris.Horne@Sun.COM if ((mapp->dam_flags & DAM_SPEND) || 144411854SChris.Horne@Sun.COM (taskq_dispatch(system_taskq, dam_stabilize_map, mapp, 144511854SChris.Horne@Sun.COM TQ_NOSLEEP | TQ_NOQUEUE) == NULL)) { 144611068SJohn.Danielson@Sun.COM DAM_INCR_STAT(mapp, dam_overrun); 144710696SDavid.Hollister@Sun.COM mapp->dam_stable_overrun++; 144811854SChris.Horne@Sun.COM dam_sched_tmo(mapp, 144911854SChris.Horne@Sun.COM drv_usectohz(damap_taskq_dispatch_retry_usec), 145011854SChris.Horne@Sun.COM dam_addrset_stable_cb); 145111854SChris.Horne@Sun.COM 145211068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__map__addrset__stable__overrun, char *, 145311068SJohn.Danielson@Sun.COM mapp->dam_name, dam_t *, mapp); 145411068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 145511068SJohn.Danielson@Sun.COM return; 145610696SDavid.Hollister@Sun.COM } 145711068SJohn.Danielson@Sun.COM 145811068SJohn.Danielson@Sun.COM DAM_SET_STAT(mapp, dam_overrun, 0); 145911068SJohn.Danielson@Sun.COM mapp->dam_stable_overrun = 0; 146011068SJohn.Danielson@Sun.COM bitset_copy(&mapp->dam_report_set, &mapp->dam_stable_set); 146111068SJohn.Danielson@Sun.COM bitset_zero(&mapp->dam_report_set); 146211068SJohn.Danielson@Sun.COM mapp->dam_flags |= DAM_SPEND; 146311068SJohn.Danielson@Sun.COM mapp->dam_flags &= ~DAM_SETADD; 146411068SJohn.Danielson@Sun.COM DTRACE_PROBE2(damap__map__addrset__stable__start, char *, 146511068SJohn.Danielson@Sun.COM mapp->dam_name, dam_t *, mapp); 146611068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 146710696SDavid.Hollister@Sun.COM } 146810696SDavid.Hollister@Sun.COM 146910696SDavid.Hollister@Sun.COM /* 147011068SJohn.Danielson@Sun.COM * schedule map timeout 'tmo_ms' ticks 147111068SJohn.Danielson@Sun.COM * if map timer is currently running, cancel if tmo_ms == 0 147210696SDavid.Hollister@Sun.COM */ 147310696SDavid.Hollister@Sun.COM static void 147410696SDavid.Hollister@Sun.COM dam_sched_tmo(dam_t *mapp, clock_t tmo_ms, void (*tmo_cb)()) 147510696SDavid.Hollister@Sun.COM { 147610696SDavid.Hollister@Sun.COM timeout_id_t tid; 147710696SDavid.Hollister@Sun.COM 147811068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__sched__tmo, char *, mapp->dam_name, dam_t *, mapp, 147911068SJohn.Danielson@Sun.COM clock_t, tmo_ms); 148011068SJohn.Danielson@Sun.COM 148111068SJohn.Danielson@Sun.COM ASSERT(mutex_owned(&mapp->dam_lock)); 148210696SDavid.Hollister@Sun.COM if ((tid = mapp->dam_tid) != 0) { 148311068SJohn.Danielson@Sun.COM if (tmo_ms == 0) { 148411068SJohn.Danielson@Sun.COM mapp->dam_tid = 0; 148511068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 148611068SJohn.Danielson@Sun.COM (void) untimeout(tid); 148711068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 148811068SJohn.Danielson@Sun.COM } 148911068SJohn.Danielson@Sun.COM } else { 149011068SJohn.Danielson@Sun.COM if (tmo_cb && (tmo_ms != 0)) 149111068SJohn.Danielson@Sun.COM mapp->dam_tid = timeout(tmo_cb, mapp, tmo_ms); 149210696SDavid.Hollister@Sun.COM } 149310696SDavid.Hollister@Sun.COM } 149410696SDavid.Hollister@Sun.COM 149510696SDavid.Hollister@Sun.COM /* 149611068SJohn.Danielson@Sun.COM * report addition or removal of an address 149710696SDavid.Hollister@Sun.COM */ 149810696SDavid.Hollister@Sun.COM static void 149911068SJohn.Danielson@Sun.COM dam_addr_report(dam_t *mapp, dam_da_t *passp, id_t addrid, int rpt_type) 150010696SDavid.Hollister@Sun.COM { 150111068SJohn.Danielson@Sun.COM char *addrstr = damap_id2addr((damap_t *)mapp, addrid); 150211068SJohn.Danielson@Sun.COM 150311068SJohn.Danielson@Sun.COM DTRACE_PROBE4(damap__addr__report, char *, mapp->dam_name, 150411068SJohn.Danielson@Sun.COM char *, addrstr, dam_t *, mapp, int, rpt_type); 150511068SJohn.Danielson@Sun.COM 150611068SJohn.Danielson@Sun.COM ASSERT(mutex_owned(&mapp->dam_lock)); 150710696SDavid.Hollister@Sun.COM ASSERT(!DAM_IN_REPORT(mapp, addrid)); 150810696SDavid.Hollister@Sun.COM passp->da_last_report = gethrtime(); 150910696SDavid.Hollister@Sun.COM mapp->dam_last_update = gethrtime(); 151010696SDavid.Hollister@Sun.COM passp->da_report_cnt++; 151111066Srafael.vanoni@sun.com passp->da_deadline = ddi_get_lbolt64() + mapp->dam_stabletmo; 151211068SJohn.Danielson@Sun.COM if (rpt_type == RPT_ADDR_DEL) 151310696SDavid.Hollister@Sun.COM passp->da_flags |= DA_RELE; 151411068SJohn.Danielson@Sun.COM else if (rpt_type == RPT_ADDR_ADD) 151510696SDavid.Hollister@Sun.COM passp->da_flags &= ~DA_RELE; 151610696SDavid.Hollister@Sun.COM bitset_add(&mapp->dam_report_set, addrid); 151710696SDavid.Hollister@Sun.COM dam_sched_tmo(mapp, mapp->dam_stabletmo, dam_addr_stable_cb); 151810696SDavid.Hollister@Sun.COM } 151910696SDavid.Hollister@Sun.COM 152010696SDavid.Hollister@Sun.COM /* 152110696SDavid.Hollister@Sun.COM * release an address report 152210696SDavid.Hollister@Sun.COM */ 152310696SDavid.Hollister@Sun.COM static void 152411068SJohn.Danielson@Sun.COM dam_addr_report_release(dam_t *mapp, id_t addrid) 152510696SDavid.Hollister@Sun.COM { 152610696SDavid.Hollister@Sun.COM dam_da_t *passp; 152711068SJohn.Danielson@Sun.COM char *addrstr = damap_id2addr((damap_t *)mapp, addrid); 152810696SDavid.Hollister@Sun.COM 152911068SJohn.Danielson@Sun.COM DTRACE_PROBE3(damap__addr__report__release, char *, mapp->dam_name, 153011068SJohn.Danielson@Sun.COM char *, addrstr, dam_t *, mapp); 153111068SJohn.Danielson@Sun.COM 153211068SJohn.Danielson@Sun.COM ASSERT(mutex_owned(&mapp->dam_lock)); 153310696SDavid.Hollister@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 153410696SDavid.Hollister@Sun.COM ASSERT(passp); 153511068SJohn.Danielson@Sun.COM /* 153611068SJohn.Danielson@Sun.COM * clear the report bit 153711068SJohn.Danielson@Sun.COM * if the address has a registered deactivation handler and 153811601SDavid.Hollister@Sun.COM * we are holding a private data pointer and the address has not 153911601SDavid.Hollister@Sun.COM * stabilized, deactivate the address (private data). 154011068SJohn.Danielson@Sun.COM */ 154111068SJohn.Danielson@Sun.COM bitset_del(&mapp->dam_report_set, addrid); 154211601SDavid.Hollister@Sun.COM if (!DAM_IS_STABLE(mapp, addrid) && mapp->dam_deactivate_cb && 154311601SDavid.Hollister@Sun.COM passp->da_ppriv_rpt) { 154411068SJohn.Danielson@Sun.COM mutex_exit(&mapp->dam_lock); 154511068SJohn.Danielson@Sun.COM (*mapp->dam_deactivate_cb)(mapp->dam_activate_arg, 154611068SJohn.Danielson@Sun.COM ddi_strid_id2str(mapp->dam_addr_hash, addrid), 154711601SDavid.Hollister@Sun.COM addrid, passp->da_ppriv_rpt, DAMAP_DEACT_RSN_UNSTBL); 154811068SJohn.Danielson@Sun.COM mutex_enter(&mapp->dam_lock); 154911068SJohn.Danielson@Sun.COM } 155010696SDavid.Hollister@Sun.COM passp->da_ppriv_rpt = NULL; 155110696SDavid.Hollister@Sun.COM if (passp->da_nvl_rpt) 155210696SDavid.Hollister@Sun.COM nvlist_free(passp->da_nvl_rpt); 155310696SDavid.Hollister@Sun.COM } 155410696SDavid.Hollister@Sun.COM 155510696SDavid.Hollister@Sun.COM /* 155610696SDavid.Hollister@Sun.COM * return the map ID of an address 155710696SDavid.Hollister@Sun.COM */ 155810696SDavid.Hollister@Sun.COM static id_t 155910696SDavid.Hollister@Sun.COM dam_get_addrid(dam_t *mapp, char *address) 156010696SDavid.Hollister@Sun.COM { 156110696SDavid.Hollister@Sun.COM damap_id_t addrid; 156210696SDavid.Hollister@Sun.COM dam_da_t *passp; 156310696SDavid.Hollister@Sun.COM 156411068SJohn.Danielson@Sun.COM ASSERT(mutex_owned(&mapp->dam_lock)); 156510696SDavid.Hollister@Sun.COM if ((addrid = ddi_strid_str2id(mapp->dam_addr_hash, address)) == 0) { 156611068SJohn.Danielson@Sun.COM if ((addrid = ddi_strid_alloc(mapp->dam_addr_hash, 156710696SDavid.Hollister@Sun.COM address)) == (damap_id_t)0) { 156810696SDavid.Hollister@Sun.COM return (0); 156910696SDavid.Hollister@Sun.COM } 157010696SDavid.Hollister@Sun.COM if (ddi_soft_state_zalloc(mapp->dam_da, addrid) != 157110696SDavid.Hollister@Sun.COM DDI_SUCCESS) { 157210696SDavid.Hollister@Sun.COM ddi_strid_free(mapp->dam_addr_hash, addrid); 157310696SDavid.Hollister@Sun.COM return (0); 157410696SDavid.Hollister@Sun.COM } 157511068SJohn.Danielson@Sun.COM 157610696SDavid.Hollister@Sun.COM if (addrid >= mapp->dam_high) 157710696SDavid.Hollister@Sun.COM mapp->dam_high = addrid + 1; 157811068SJohn.Danielson@Sun.COM 157911068SJohn.Danielson@Sun.COM /* 158011068SJohn.Danielson@Sun.COM * expand bitmaps if ID has outgrown old map size 158111068SJohn.Danielson@Sun.COM */ 158211068SJohn.Danielson@Sun.COM if (mapp->dam_high > mapp->dam_size) { 158311068SJohn.Danielson@Sun.COM mapp->dam_size = mapp->dam_size + DAM_SIZE_BUMP; 158411068SJohn.Danielson@Sun.COM bitset_resize(&mapp->dam_active_set, mapp->dam_size); 158511068SJohn.Danielson@Sun.COM bitset_resize(&mapp->dam_stable_set, mapp->dam_size); 158611068SJohn.Danielson@Sun.COM bitset_resize(&mapp->dam_report_set, mapp->dam_size); 158711068SJohn.Danielson@Sun.COM } 158811068SJohn.Danielson@Sun.COM 158911068SJohn.Danielson@Sun.COM passp = ddi_get_soft_state(mapp->dam_da, addrid); 159011068SJohn.Danielson@Sun.COM passp->da_ref = 1; 159111068SJohn.Danielson@Sun.COM passp->da_addr = ddi_strid_id2str(mapp->dam_addr_hash, 159211068SJohn.Danielson@Sun.COM addrid); /* for mdb */ 159310696SDavid.Hollister@Sun.COM } 159410696SDavid.Hollister@Sun.COM return (addrid); 159510696SDavid.Hollister@Sun.COM } 159610696SDavid.Hollister@Sun.COM 159710696SDavid.Hollister@Sun.COM /* 159810696SDavid.Hollister@Sun.COM * create and install map statistics 159910696SDavid.Hollister@Sun.COM */ 160010696SDavid.Hollister@Sun.COM static int 160110696SDavid.Hollister@Sun.COM dam_kstat_create(dam_t *mapp) 160210696SDavid.Hollister@Sun.COM { 160310696SDavid.Hollister@Sun.COM kstat_t *mapsp; 160410696SDavid.Hollister@Sun.COM struct dam_kstats *statsp; 160510696SDavid.Hollister@Sun.COM 160610696SDavid.Hollister@Sun.COM mapsp = kstat_create("dam", 0, mapp->dam_name, "damap", 160710696SDavid.Hollister@Sun.COM KSTAT_TYPE_NAMED, 160810696SDavid.Hollister@Sun.COM sizeof (struct dam_kstats) / sizeof (kstat_named_t), 0); 160911068SJohn.Danielson@Sun.COM 161011068SJohn.Danielson@Sun.COM if (mapsp == NULL) 161110696SDavid.Hollister@Sun.COM return (DDI_FAILURE); 161210696SDavid.Hollister@Sun.COM 161310696SDavid.Hollister@Sun.COM statsp = (struct dam_kstats *)mapsp->ks_data; 161411068SJohn.Danielson@Sun.COM kstat_named_init(&statsp->dam_cycles, "cycles", KSTAT_DATA_UINT32); 161511068SJohn.Danielson@Sun.COM kstat_named_init(&statsp->dam_overrun, "overrun", KSTAT_DATA_UINT32); 161611068SJohn.Danielson@Sun.COM kstat_named_init(&statsp->dam_jitter, "jitter", KSTAT_DATA_UINT32); 161711068SJohn.Danielson@Sun.COM kstat_named_init(&statsp->dam_active, "active", KSTAT_DATA_UINT32); 161810696SDavid.Hollister@Sun.COM kstat_install(mapsp); 161910696SDavid.Hollister@Sun.COM mapp->dam_kstatsp = mapsp; 162010696SDavid.Hollister@Sun.COM return (DDI_SUCCESS); 162110696SDavid.Hollister@Sun.COM } 1622