/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 (c) 1999 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* DDI nodeid management ...
*/
#include <sys/ddi_impldefs.h>
#include <sys/ddi_implfuncs.h>
/*
* Keep a sorted free list of available nodeids.
* Allocating a nodeid won't cause memory allocation.
* Freeing a nodeid does cause memory allocation.
*/
struct available {
};
/*
* The initial seed of available nodeids: 1 .. 0x10000000
* 0, -1 (DEVI_PSEUDO_NODEID) and -2 (DEVI_SID_NODEID) are illegal values
* and may not be used. Although this code is fully capable of dealing
* with a full 32-bit range of nodeids, we use a low numeric range of
* nodeids as an optimization to avoid overlap with promif nodeids.
*/
};
/*
* head of the available list ...
*/
/*
* A single lock for the list ...
*/
/*
* Helper functions to manage the list ...
*/
static struct available *
{
}
static void
{
}
/*
* Unlink a node from the list ... the lock must be held.
*/
static void
{
else
}
/*
* Insert fp before np ... the lock must be held.
*/
static void
{
else
}
/*
* Add fp to the end of the list ... the lock must be held.
*/
static void
{
return;
}
/* empty */;
}
/*
* If this entry and the next entry are consecutive, coalesce the
* two entries into a single entry ... the lock must be held.
* If the entry can be coalesced, the extra entry is freed.
*/
static void
{
return;
}
}
void
impl_ddi_init_nodeid(void)
{
/*
* Copy the seed into kmem_alloc-ed memory so we don't have to
* worry about not freeing it later.
*/
}
int
{
int x;
int unlinked = 0;
*nodeid = 0;
return (DDI_FAILURE);
}
unlinked = 1;
}
if (unlinked)
ASSERT(x != 0);
ASSERT(x != DEVI_PSEUDO_NODEID);
ASSERT(x != DEVI_SID_NODEID);
*nodeid = x;
return (DDI_SUCCESS);
}
void
impl_ddi_free_nodeid(int n)
{
ASSERT(n != 0);
ASSERT(n != DEVI_PSEUDO_NODEID);
ASSERT(n != DEVI_SID_NODEID);
/*
* Allocate memory wihout holding the lock in case we need it.
* If we don't use it, we'll free it.
*/
/*
* Insert nodeid in the appropriate place in our sorted available
* list. Maintain the list as we do it.
*/
/*
* Add to the beginning of this entry?
*/
return;
}
/*
* Add to end of this entry? (If yes, try to coalesce
* this entry with the next entry.)
*/
return;
}
/*
* Does it belong before this entry? (new entry)
*/
return;
}
"nodeid %x already free", n);
}
/*
* Add a new list item to the end of the list ...
*/
}
/*
* Remove (take) nodeid n off of the available list.
* Returns 0 if successful or -1 if it fails.
*
* A failure indicates we were called with KM_NOSLEEP and we
* couldn't allocate memory when we needed to.
*/
int
{
int unlinked = 0;
ASSERT(n != 0);
ASSERT(n != DEVI_PSEUDO_NODEID);
ASSERT(n != DEVI_SID_NODEID);
/*
* If this nodeid is not within the range of nodeids we
* manage, we simply succeed. The initial seed may be
* setup so that promif nodeids fall outside our range.
*/
return (0);
/*
* Allocate memory wihout holding the lock in case we need it.
* If we don't use it, we'll free it.
*/
/*
* Find nodeid in our list, if it exists, 'take' it.
*/
/*
* If it's less than this entry, it's not available...
*/
break;
/*
* If it's the first entry in this list item, take it ...
*/
++unlinked;
}
if (fp)
if (unlinked)
return (0);
}
/*
* If it's the last entry in this list item, take it ...
* The count can't be 1 otherwise it would have matched
* the beginning of list case, above.
*/
if (fp)
return (0);
}
/*
* Is it in the middle of this entry? If it is, we'll
* have to split np into two items, removing nodeid
* from the middle of the list item.
*/
/*
* We were called with KM_NOSLEEP and
* were unable to allocate memory.
*/
return (-1);
}
/*
* Split np, removing nodeid from the middle of
* this entry. We already know it isn't on either
* end of of this entry, so we know we have to split it.
*/
return (0);
}
}
/*
* Apparently the nodeid is not available ...
*/
if (fp)
"be unique\n", nodeid);
return (0);
}