STRUCT_SIZE(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