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


Solaris DDI specific (Solaris 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(5) 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)