STRUCT_DECL(9F) Kernel Functions for Drivers STRUCT_DECL(9F)
NAME
STRUCT_DECL, SIZEOF_PTR, SIZEOF_STRUCT, STRUCT_BUF, STRUCT_FADDR,
STRUCT_FGET, STRUCT_FGETP, STRUCT_FSET, STRUCT_FSETP, STRUCT_HANDLE,
STRUCT_INIT, STRUCT_SIZE, STRUCT_SET_HANDLE - 32-bit application data
access macros
SYNOPSIS
#include <sys/ddi.h>
#include <sys/sunddi.h>
STRUCT_DECL(
structname,
handle);
STRUCT_HANDLE(
structname,
handle);
void STRUCT_INIT(
handle,
model_t umodel);
void STRUCT_SET_HANDLE(
handle,
model_t umodel,
void *addr);
STRUCT_FGET(
handle,
field);
STRUCT_FGETP(
handle,
field);
STRUCT_FSET(
handle,
field,
val);
STRUCT_FSETP(
handle,
field,
val);
<typeof field> *STRUCT_FADDR(
handle,
field);
struct structname *STRUCT_BUF(
handle);
size_t SIZEOF_STRUCT(
structname,
umodel);
size_t SIZEOF_PTR(
umodel);
size_t STRUCT_SIZE(
handle);
INTERFACE LEVEL
illumos DDI specific (illumos DDI).
PARAMETERS
The macros take the following parameters:
structname The structure name that appears
after the
C keyword
struct of the native form.
umodel A bit field that contains either the
ILP32 model bit
(
DATAMODEL_ILP32), or the
LP64 model bit
(
DATAMODEL_LP64). In an
ioctl(9E), these bits are
present in the flag parameter. In a
devmap(9E), the
bits are present in the model parameter
mmap(9E). The
ddi_mmap_get_model(9F) can be called to get the data
model of the current thread.
handle The variable name used to refer to a particular
instance of a structure which is handled by these
macros.
field The field name within the structure that can contain
substructures. If the structures contain substructures,
unions, or arrays, the
field can be whatever complex
expression would naturally follow the first . or ->.
DESCRIPTION
The above macros allow a device driver to access data consumed from a
32-bit application regardless whether the driver was compiled to the
ILP32 or LP64 data model. These macros effectively hide the
difference between the data model of the user application and the
driver.
The macros can be broken up into two main categories described in the
following sections.
Declaration and Initialization Macros
The macros
STRUCT_DECL() and
STRUCT_HANDLE() declare structure
handles on the stack, whereas the macros
STRUCT_INIT() and
STRUCT_SET_HANDLE() initialize the structure handles to point to an
instance of the native form structure.
The macros
STRUCT_HANDLE() and
STRUCT_SET_HANDLE() are used to
declare and initialize a structure handle to an existing data
structure, for example, ioctls within a STREAMS module.
The macros
STRUCT_DECL() and
STRUCT_INIT(), on the other hand, are
used in modules which declare and initialize a structure handle to a
data structure allocated by
STRUCT_DECL(), that is, any standard
character or block device driver
ioctl(9E) routine that needs to copy
in data from a user-mode program.
STRUCT_DECL(structname, handle) Declares a structure handle for a struct and allocates an
instance of its native form on the stack. It is assumed that the
native form is larger than or equal to the ILP32 form.
handle is
a variable name and is declared as a variable by this macro.
void STRUCT_INIT(handle, model_t umodel) Initializes
handle to point to the instance allocated by
STRUCT_DECL(). It also sets data model for
handle to
umodel and
it must be called before any access is made through the macros
that operate on these structures. When used in an
ioctl(9E) routine,
umodel is the flag parameter. In a
devmap(9E) routine,
umodel is the model parameter. In a
mmap(9E) routine,
umodel is
the return value of
ddi_mmap_get_model(9F). This macro is
intended only for handles created with
STRUCT_DECL().
STRUCT_HANDLE(structname, handle) Declares a structure handle
handle but, unlike
STRUCT_DECL(), it
does not allocate an instance of "struct".
void STRUCT_SET_HANDLE(handle, model_t umodel, void *addr) Initializes handle to point to the native form instance at
addr.
It also sets the data model for
handle to
umodel. This is
intended for handles created with
STRUCT_HANDLE(). Fields cannot
be referenced via the
handle until this macro has been invoked.
Typically,
addr is the address of the native form structure
containing the user-mode programs data. When used in an
ioctl(9E),
umodel is the flag parameter. In a
devmap(9E) routine,
umodel is the model parameter. In an
mmap(9E) routine,
umodel is
the return value of
ddi_mmap_get_model(9F).
Operation Macros
size_t STRUCT_SIZE(handle) Returns size of the structure referred to by
handle, depending on
the data model associated with
handle. If the data model stored
by
STRUCT_INIT() or
STRUCT_SET_HANDLE() is
DATAMODEL_ILP32, the
size of the
ILP32 form is returned. Otherwise, the size of the
native form is returned.
STRUCT_FGET(handle, field) Returns the contents of
field in the structure described by
handle according to the data model associated with
handle.
STRUCT_FGETP(handle, field) This is the same as
STRUCT_FGET() except that the
field in
question is a pointer of some kind. This macro casts caddr32_t to
a (void *) when it is accessed. Failure to use this macro for a
pointer leads to compiler warnings or failures.
STRUCT_FSET(handle, field, val) Assigns
val to the (non-pointer) in the structure described by
handle. It should not be used within another expression, but only
as a statement.
STRUCT_FSETP(handle, field, val) This is the equivalent of STRUCT_FGETP() for STRUCT_FGET(), with
the same exceptions. Like STRUCT_FSET, STRUCT_FSETP should not be
used within another expression, but only as a statement.
struct structname *STRUCT_BUF(handle) Returns a pointer to the native mode instance of the structure
described by
handle.
Macros Not Using Handles
size_t SIZEOF_STRUCT(structname, umodel) Returns size of
structname based on
umodel.
size_t SIZEOF_PTR(umodel) Returns the size of a pointer based on
umodel.
EXAMPLES
Example 1: Copying a Structure
The following example uses an
ioctl(9E) on a regular character device
that copies a data structure that looks like this into the kernel:
struct opdata {
size_t size;
uint_t flag;
};
Example 2: Defining a Structure
This data structure definition describes what the
ioctl(9E) would
look like in a 32-bit application using fixed width types.
#if defined(_MULTI_DATAMODEL)
struct opdata32 {
size32_t size;
uint32_t flag;
};
#endif
Example 3: Using STRUCT_DECL() and STRUCT_INIT()
Note: This example uses the
STRUCT_DECL() and
STRUCT_INIT() macros to
declare and initialize the structure handle.
int
xxioctl(dev_t dev, int cmd, intptr_t arg, int mode,
cred_t *cr, int *rval_p);
{
STRUCT_DECL(opdata, op);
if (cmd != OPONE)
return (ENOTTY);
STRUCT_INIT(op, mode);
if (copyin((void *)data,
STRUCT_BUF(op), STRUCT_SIZE(op)))
return (EFAULT);
if (STRUCT_FGET(op, flag) != FACTIVE ||
STRUCT_FGET(op, size) > sizeof (device_state))
return (EINVAL);
xxdowork(device_state, STRUCT_FGET(op, size));
return (0);
}
This piece of code is an excerpt from a STREAMS module that handles
ioctl(9E) data (M_IOCDATA) messages and uses the data structure
defined above. This code has been written to run in the ILP32
environment only.
Example 4: Using STRUCT_HANDLE() and STRUCT_SET_HANDLE()
The next example illustrates the use of the
STRUCT_HANDLE() and
STRUCT_SET_HANDLE() macros which declare and initialize the structure
handle to point to an already existing instance of the structure.
The above code example can be converted to run in the LP64
environment using the
STRUCT_HANDLE() and
STRUCT_SET_HANDLE() as
follows:
struct strbuf {
int maxlen; /* no. of bytes in buffer */
int len; /* no. of bytes returned */
caddr_t buf; /* pointer to data */
};
static void
wput_iocdata(queue_t *q, mblk_t *msgp)
{
struct copyresp *cp = (struct copyresp *)msgp->b_rptr;
STRUCT_HANDLE(strbuf, sb);
if (msgp->b_cont->b_cont != NULL) {
msgp->b_cont = msgpullup(msgp->b_cont, -1);
if (msgp->b_cont == NULL) {
miocnak(q, msgp, 0, ENOSR);
return;
}
}
STRUCT_SET_HANDLE(sb, cp->cp_flag, (void *)msgp->b_cont->b_rptr);
if (STRUCT_FGET(sb, maxlen) < (int)sizeof (ipa_t)) {
miocnak(q, msgp, 0, ENOSR);
return;
}
...
miocack(q, msgp, 0, 0);
}
ATTRIBUTES
See
attributes(7) for descriptions of the following attributes:
+--------------------+-----------------+
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
+--------------------+-----------------+
|Interface Stability | Evolving |
+--------------------+-----------------+
SEE ALSO
devmap(9E),
ioctl(9E),
mmap(9E),
ddi_mmap_get_model(9F) Writing Device Drivers STREAMS Programming Guide May 20, 2006 STRUCT_DECL(9F)