Kernel Functions for Drivers ddisoftstate(9F)
NAME
ddisoftstate, ddigetsoftstate, ddisoftstatefini,
ddisoftstatefree, ddisoftstateinit,
ddisoftstatezalloc - driver soft state utility routines
SYNOPSIS
#include
#include
void *ddigetsoftstate(void *state, int item);
void ddisoftstatefini(void **statep);
void ddisoftstatefree(void *state, int item);
int ddisoftstateinit(void **statep, sizet size, sizet nitems);
int ddisoftstatezalloc(void *state, int item);
INTERFACE LEVEL
Solaris DI specific (Solaris DI).
PARAMETERS
statep Address of the opaque state pointer which will be
initialized by ddisoftstateinit() to point to
implementation dependent data.
size Size of the item which will be allocated by sub-
sequent calls to ddisoftstatezalloc().
nitems A hint of the number of items which will be
preallocated; zero is allowed.
state An opaque pointer to implementation-dependent
data that describes the soft state.
item The item number for the state structure; usually
the instance number of the associated devinfo
node.
SunOS 5.11 Last change: 16 Jan 2006 1
Kernel Functions for Drivers ddisoftstate(9F)
DESCRIPTION
Most device drivers maintain state information with each
instance of the device they control; for example, a soft
copy of a device control register, a mutex that must be held
while accessing a piece of hardware, a partition table, or a
unit structure. These utility routines are intended to help
device drivers manage the space used by the driver to hold
such state information.
For example, if the driver holds the state of each instance
in a single state structure, these routines can be used to
dynamically allocate and deallocate a separate structure for
each instance of the driver as the instance is attached and
detached.
To use the routines, the driver writer needs to declare a
state pointer, statep, which the implementation uses as a
place to hang a set of per-driver structures; everything
else is managed by these routines.
The routine ddisoftstateinit() is usually called in the
driver's init(9E) routine to initialize the state pointer,
set the size of the soft state structure, and to allow the
driver to pre-allocate a given number of such structures if
required.
The routine ddisoftstatezalloc() is usually called in the
driver's attach(9E) routine. The routine is passed an item
number which is used to refer to the structure in subsequent
calls to ddigetsoftstate() and ddisoftstatefree(). The
item number is usually just the instance number of the
devinfo node, obtained with ddigetinstance(9F). The rou-
tine attempts to allocate space for the new structure, and
if the space allocation was successful, DISUCES is
returned to the caller. Returned memory is zeroed.
A pointer to the space previously allocated for a soft state
structure can be obtained by calling ddigetsoftstate()
with the appropriate item number.
The space used by a given soft state structure can be
returned to the system using ddisoftstatefree(). This
routine is usually called from the driver's detach(9E) entry
point.
SunOS 5.11 Last change: 16 Jan 2006 2
Kernel Functions for Drivers ddisoftstate(9F)
The space used by all the soft state structures allocated on
a given state pointer, together with the housekeeping infor-
mation used by the implementation can be returned to the
system using ddisoftstatefini(). This routine can be
called from the driver's fini(9E) routine.
The ddisoftstatezalloc(), ddisoftstatefree() and
ddigetsoftstate() routines coordinate access to the
underlying data structures in an MT-safe fashion, thus no
additional locks should be necessary.
RETURN VALUES
ddigetsoftstate()
NUL The requested state structure was not allocated
at the time of the call.
pointer The pointer to the state structure.
ddisoftstateinit()
0 The allocation was successful.
EINVAL Either the size parameter was zero, or the statep
parameter was invalid.
ddisoftstatezalloc()
DISUCES The allocation was successful.
DIFAILURE The routine failed to allocate the storage
required; either the state parameter was
invalid, the item number was negative, or an
attempt was made to allocate an item number
that was already allocated.
CONTEXT
The ddisoftstateinit() and ddisoftstatealloc() func-
tions can be called from user or kernel context only, since
they may internally call kmemzalloc(9F) with the KMSLEP
flag.
SunOS 5.11 Last change: 16 Jan 2006 3
Kernel Functions for Drivers ddisoftstate(9F)
The ddisoftstatefini(), ddisoftstatefree() and
ddigetsoftstate() routines can be called from any driver
context.
EXAMPLES
Example 1 Creating and Removing Data Structures
The following example shows how the routines described above
can be used in terms of the driver entry points of a
character-only driver. The example concentrates on the por-
tions of the code that deal with creating and removing the
driver's data structures.
typedef struct {
volatile caddrt *csr; /* device registers */
kmutext csrmutex; /* protects 'csr' field */
unsigned int state;
devinfot *dip; /* back pointer to devinfo */
} devstatet;
static void *statep;
int
init(void)
{
int error;
error = ddisoftstateinit(&statep, sizeof (devstatet), 0);
if (error != 0)
return (error);
if ((error = modinstall(&modlinkage)) != 0)
ddisoftstatefini(&statep);
return (error);
}
int
fini(void)
{
int error;
if ((error = modremove(&modlinkage)) != 0)
return (error);
ddisoftstatefini(&statep);
return (0);
}
static int
xxattach(devinfot *dip, ddiattachcmdt cmd)
{
int instance;
devstatet *softc;
SunOS 5.11 Last change: 16 Jan 2006 4
Kernel Functions for Drivers ddisoftstate(9F)
switch (cmd) {
case DIATACH:
instance = ddigetinstance(dip);
if (ddisoftstatezalloc(statep, instance) != DISUCES)
return (DIFAILURE);
softc = ddigetsoftstate(statep, instance);
softc->dip = dip;
...
return (DISUCES);
default:
return (DIFAILURE);
}
}
static int
xxdetach(devinfot *dip, ddidetachcmdt cmd)
{
int instance;
switch (cmd) {
case DIDETACH:
instance = ddigetinstance(dip);
...
ddisoftstatefree(statep, instance);
return (DISUCES);
default:
return (DIFAILURE);
}
}
static int
xxopen(devt *devp, int flag, int otyp, credt *credp)
{
devstatet *softc;
int instance;
instance = getminor(*devp);
if ((softc = ddigetsoftstate(statep, instance)) == NUL)
return (ENXIO);
...
softc->state = XINUSE;
...
return (0);
}
SEE ALSO
fini(9E), init(9E), attach(9E), detach(9E),
ddigetinstance(9F), getminor(9F), kmemzalloc(9F)
SunOS 5.11 Last change: 16 Jan 2006 5
Kernel Functions for Drivers ddisoftstate(9F)
Writing Device Drivers
WARNINGS
There is no attempt to validate the item parameter given to
ddisoftstatezalloc() other than it must be a positive
signed integer. Therefore very large item numbers may cause
the driver to hang forever waiting for virtual memory
resources that can never be satisfied.
NOTES
If necessary, a hierarchy of state structures can be con-
structed by embedding state pointers in higher order state
structures.
DIAGNOSTICS
All of the messages described below usually indicate bugs in
the driver and should not appear in normal operation of the
system.
WARNING: ddisoftstatezalloc: bad handle
WARNING: ddisoftstatefree: bad handle
WARNING: ddisoftstatefini: bad handle
The implementation-dependent information kept in the state
variable is corrupt.
WARNING: ddisoftstatefree: null handle
WARNING: ddisoftstatefini: null handle
The routine has been passed a null or corrupt state pointer.
Check that ddisoftstateinit() has been called.
WARNING: ddisoftstatefree: item %d not in range [0..%d]
The routine has been asked to free an item which was never
allocated. The message prints out the invalid item number
and the acceptable range.
SunOS 5.11 Last change: 16 Jan 2006 6
|