STRUCT_INIT(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
Solaris DDI specific (Solaris DDI).
PARAMETERS
The macros take the following parameters:
structname
The structure name (as would appear after the C key-
word ``struct'') of the native form.
umodel
A bit field containing either ILP32 model bit
(DATAMODEL_ILP32), or the LP64 model get
(DATAMODEL_LP64). In an ioctl(9E), these bits will be
present in the flag parameter; in a devmap(9E), they
will be present in the model parameter mmap(9E) and
can call ddi_mmap_get_model(9F) 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 mac-
ros.
field The field name within the structure contain substruc-
tures. If the structures contain substructures,
unions, or arrays, then field can be whether complex
expression could occur after the first ``.'' or ``-
>''.
DESCRIPTION
The above macros allow a device driver to access data con-
sumed 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, the
macros that declare and initialize structure handles and the
macros that operate on these structures using the structure
handles.
Declaration and Initialization Macros
The macros STRUCT_DECL() and STRUCT_HANDLE() declare struc-
ture 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 dev-
ice 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 must be called before any access is
made through the macros that operate on these struc-
tures. When used in an ioctl(9E) routine umodel is
the flag parameter; in adevmap(9E) routine umodel is
the model parameter and in a mmap(9E) routine, is the
return value of ddi_mmap_get_model(9F). This macro is
intended for handles created with STRUCT_DECL() only.
STRUCT_HANDLE(structname, handle)
Declares a ``structure handle'' handle but unlike
STRUCT_DECL() does not allocate an instance of "struct
".
void STRUCT_SET_HANDLE(handle, model_t umodel, void *addr)
Initializes to point to the native form instance at
addr, it also sets the data model for handle to umo-
del. 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 con-
taining the user-mode programs data. When used in an
ioctl(9E) umodel is the flag parameter, in a
devmap(9E) routine is the model parameter and in a
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.
It will return the size depending upon the data model
associated with handle. If the data model stored by
STRUCT_INIT() or STRUCT_SET_HANDLE() was
DATAMODEL_ILP32, it will return the size of the ILP32
form, else it will return the size of the native form.
STRUCT_FGET(handle, field)
Returns the contents of field in the structure
described by handle according to the data model asso-
ciated 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 will cast caddr32_t to a (void *) when it is
accessed. Failure to use this macro for a pointer will
lead 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 any
other expression, but rather only as a statement.
STRUCT_FSETP(handle, field, val)
Returns a pointer to the in the structure described by
handle.
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 charac-
ter 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)
{
mblk_t *data; /* message block descriptor */
STRUCT_HANDLE(strbuf, sb);
/* copyin the data */
if (mi_copy_state(q, mp, &data) == -1) {
return;
}
STRUCT_SET_HANDLE(sb,((struct iocblk *)msgp->b_rptr)->ioc_flag,
(void *)data->b_rptr);
if (STRUCT_FGET(sb, maxlen) < (int)sizeof (ipa_t)) {
mi_copy_done(q, msgp, EINVAL);
return;
}
}
SEE ALSO
devmap(9E), ioctl(9E), mmap(9E),ddi_mmap_get_model(9F)
Writing Device Drivers
STREAMS Programming Guide
Man(1) output converted with
man2html