damap.c revision 4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/ddi_timer.h>
#include <sys/sysevent.h>
#include <sys/damap_impl.h>
#ifdef DEBUG
static int damap_debug = 0;
#endif /* DEBUG */
static void dam_activate_taskq(void *);
static void dam_addr_stable_cb(void *);
static void dam_set_stable_cb(void *);
static int dam_kstat_create(dam_t *);
static void dam_kstat_destroy(dam_t *);
if ((mapp)->dam_kstatsp) { \
}
if ((mapp)->dam_kstatsp) { \
}
/*
* Create new device address map
*
* ident: map name (kstat)
* size: max # of map entries
* rptmode: type or mode of reporting
*
* activate_arg: address provider activation-callout private
* activate_cb: address provider activation callback handler
* deactivate_cb: address provider deactivation callback handler
*
* config_arg: configuration-callout private
* config_cb: class configuration callout
* unconfig_cb: class unconfiguration callout
*
* damapp: pointer to map handle (return)
*
* Returns: DAM_SUCCESS
* DAM_EINVAL Invalid argument(s)
* DAM_FAILURE General failure
*/
int
{
void *softstate_p;
DTRACE_PROBE1(damap__create__entry, char *, ident);
return (DAM_EINVAL);
return (DAM_FAILURE);
return (DAM_FAILURE);
}
if (ident)
0);
return (DAM_FAILURE);
}
return (DAM_SUCCESS);
}
/*
* Destroy device address map
*
* damapp: address map
*
* Returns: DAM_SUCCESS
* DAM_EINVAL Invalid argument(s)
* DAM_FAILURE General failure
*/
void
{
int i;
(void) damap_sync(damapp);
/*
* cancel pending timeouts and kill off the taskq
*/
continue;
if (DAM_IN_REPORT(mapp, i))
dam_release_report(mapp, i);
if (DAM_IS_STABLE(mapp, i))
dam_deactivate_addr(mapp, i);
}
}
/*
* Wait for map stability.
*
* damapp: address map
*/
int
{
int none_active;
}
return (none_active);
}
/*
* Get the name of a device address map
*
* damapp: address map
*
* Returns: name
*/
char *
{
}
/*
* Report an address to per-address report
*
* damapp: address map handle
* address: address in ascii string representation
* rindx: index if address stabilizes
* nvl: optional nvlist of configuration-private data
* addr_priv: optional provider-private (passed to activate/deactivate cb)
*
* Returns: DAM_SUCCESS
* DAM_EINVAL Invalid argument(s)
* DAM_MAPFULL address map exhausted
*/
int
void *addr_priv)
{
char *, address);
return (DAM_EINVAL);
return (DAM_MAPFULL);
}
/*
* If re-reporting the same address (add or remove) clear
* the existing report
*/
}
if (nvl)
return (DAM_SUCCESS);
}
/*
* Report removal of address from per-address report
*
* damapp: address map
* address: address in ascii string representation
*
* Returns: DAM_SUCCESS
* DAM_EINVAL Invalid argument(s)
* DAM_FAILURE General failure
*/
int
{
char *, address);
return (DAM_EINVAL);
return (DAM_SUCCESS);
}
}
return (DAM_SUCCESS);
}
/*
* Initiate full-set report
*
* damapp: address map
*
* Returns: DAM_SUCCESS
* DAM_EINVAL Invalid argument(s)
*/
int
{
int i;
return (DAM_EINVAL);
/*
* reset any pending reports
*/
/*
* cancel stabilization timeout
*/
if (DAM_IN_REPORT(mapp, i))
dam_release_report(mapp, i);
}
}
return (DAM_SUCCESS);
}
/*
* Report address to full-set report
*
* damapp: address map handle
* address: address in ascii string representation
* rindx: index if address stabilizes
* nvl: optional nvlist of configuration-private data
*
* Returns: DAM_SUCCESS
* DAM_EINVAL Invalid argument(s)
* DAM_MAPFULL address map exhausted
* DAM_FAILURE General failure
*/
int
{
char *, address);
return (DAM_EINVAL);
return (DAM_FAILURE);
return (DAM_MAPFULL);
}
}
if (nvl)
if (ridx)
return (DAM_SUCCESS);
}
/*
* Commit full-set report for stabilization
*
* damapp: address map handle
* flags: (currently 0)
*
* Returns: DAM_SUCCESS
* DAM_EINVAL Invalid argument(s)
* DAM_FAILURE General failure
*/
int
{
int i;
return (DAM_EINVAL);
return (DAM_FAILURE);
if (flags & DAMAP_RESET) {
if (DAM_IN_REPORT(mapp, i))
dam_release_report(mapp, i);
} else {
}
return (DAM_SUCCESS);
}
/*
* Return nvlist registered with reported address
*
* damapp: address map handle
* aid: address ID
*
* Returns: nvlist_t * provider supplied via damap_addr{set}_add())
* NULL
*/
nvlist_t *
{
}
return (NULL);
}
/*
* Return address string
*
* damapp: address map handle
* aid: address ID
*
* Returns: char * Address string
* NULL
*/
char *
{
}
/*
* Hold address reference in map
*
* damapp: address map handle
* aid: address ID
*
* Returns: DAM_SUCCESS
* DAM_FAILURE
*/
int
{
if (!passp) {
return (DAM_FAILURE);
}
return (DAM_SUCCESS);
}
/*
* Release address reference in map
*
* damapp: address map handle
* aid: address ID
*/
void
{
}
/*
* Return current reference count on address reference in map
*
* damapp: address map handle
* aid: address ID
*
* Returns: DAM_SUCCESS
* DAM_FAILURE
*/
int
{
int ref = -1;
if (passp)
return (ref);
}
/*
* Return next address ID in list
*
* damapp: address map handle
* damap_list: address ID list passed to config|unconfig
* returned by look by lookup_all
* last: last ID returned, 0 is start of list
*
* Returns: addrid Next ID from the list
* 0 End of the list
*/
{
int i, start;
return ((damap_id_t)0);
if (bitset_in_set(dam_list, i))
return ((damap_id_t)i);
return ((damap_id_t)0);
}
/*
* Set config private data
*
* damapp: address map handle
* aid: address ID
* cfg_priv: configuration private data
*
*/
void
{
if (!passp) {
return;
}
}
/*
* Get config private data
*
* damapp: address map handle
* aid: address ID
*
* Returns: configuration private data
*/
void *
{
void *rv;
if (!passp) {
return (NULL);
}
return (rv);
}
/*
* Lookup a single address in the active address map
*
* damapp: address map handle
* address: address string
*
* 0 Address not in stable set
*
* Future: Allow the caller to wait for stabilize before returning not found.
*/
{
if (addrid) {
if (passp) {
} else {
addrid = 0;
}
} else {
addrid = 0;
}
}
return ((damap_id_t)addrid);
}
/*
* Return the list of stable addresses in the map
*
* damapp: address map handle
* id_listp: pointer to list of address IDs in stable map (returned)
*
* Returns: # of entries returned in alist
*/
int
{
int n_ids, i;
if (bitset_in_set(bsp, i)) {
if (passp) {
n_ids++;
}
}
}
if (n_ids) {
return (n_ids);
} else {
return (0);
}
}
/*
* Release the address list returned by damap_lookup_all()
*
* mapp: address map handle
* id_list: list of address IDs returned in damap_lookup_all()
*/
void
{
int i;
return;
(void) dam_release(mapp, i);
}
}
/*
* Activate a set of stabilized addresses
*/
static void
{
char *addrstr;
int i;
n_active++;
if (!bitset_in_set(active_set, i))
continue;
n_active++;
if (mapp->dam_activate_cb) {
(*mapp->dam_activate_cb)(
&passp->da_ppriv_rpt);
}
/*
* copy the reported nvlist and provider private data
*/
passp->da_stable_cnt++;
}
}
/*
* Release a set of stabilized addresses
*/
static void
{
int i;
if (bitset_in_set(release_set, i)) {
int, i);
(void) dam_release(mapp, i);
}
}
}
/*
* release a previously activated address
*/
static void
{
/*
* invoke the deactivation callback to notify
* this address is no longer active
*/
/*
* allow pending reports for this address to stabilize
*/
return;
/*
* defer teardown until outstanding references are released
*/
return;
}
}
/*
* process stabilized address reports
*/
static void
dam_activate_taskq(void *arg)
{
bitset_init(&delta);
bitset_init(&cfg);
bitset_init(&uncfg);
&delta)) {
bitset_fini(&uncfg);
bitset_fini(&cfg);
bitset_fini(&delta);
return;
}
if (has_cfg) {
}
if (has_uncfg) {
}
mapp->dam_stable_cnt++;
bitset_fini(&uncfg);
bitset_fini(&cfg);
bitset_fini(&delta);
}
/*
* per-address stabilization timeout
*/
static void
dam_addr_stable_cb(void *arg)
{
int i;
int spend = 0;
int tpend = 0;
return;
}
/*
* If still under stabilization, reschedule timeout,
* else dispatch the task to activate & deactivate the stable
* set.
*/
return;
}
continue;
/*
* Stabilize each address
*/
if (!passp) {
continue;
}
/* report has stabilized */
} else {
}
spend++;
continue;
}
/*
* not stabilized, determine next (future) map timeout
*/
tpend++;
}
/*
* schedule taskq activation of stabilized reports
*/
if (spend) {
} else
tpend++;
}
/*
* schedule timeout to handle future stabalization of active reports
*/
if (tpend)
}
/*
* fullset stabilization timeout
*/
static void
dam_set_stable_cb(void *arg)
{
return;
}
/*
* If still under stabilization, reschedule timeout,
* else dispatch the task to activate & deactivate the stable
* set.
*/
} else {
}
}
/*
* reschedule map timeout 'tmo_ms' ticks
*/
static void
{
}
}
/*
* record report addition or removal of an address
*/
static void
{
passp->da_report_cnt++;
if (report == RPT_ADDR_DEL)
else if (report == RPT_ADDR_ADD)
}
/*
* release an address report
*/
static void
{
if (passp->da_nvl_rpt)
}
/*
* deactivate a previously stable address
*/
static void
{
return;
if (mapp->dam_deactivate_cb)
(*mapp->dam_deactivate_cb)(
}
/*
* return the map ID of an address
*/
static id_t
{
address)) == (damap_id_t)0) {
return (0);
}
DDI_SUCCESS) {
return (0);
}
}
return (0);
return (addrid);
}
/*
* create and install map statistics
*/
static int
{
struct dam_kstats *statsp;
sizeof (struct dam_kstats) / sizeof (kstat_named_t), 0);
return (DDI_FAILURE);
}
"stable cycle overrun", KSTAT_DATA_UINT32);
"restarted reports", KSTAT_DATA_UINT32);
"# of stable map entries", KSTAT_DATA_UINT32);
return (DDI_SUCCESS);
}
/*
* destroy map stats
*/
static void
{
}