mkiocb(9F)




NAME

     mkiocb - allocates a STREAMS ioctl block  for  M_IOCTL  mes-
     sages in the kernel.


SYNOPSIS

     #include <sys/stream.h>

     mblk_t *mkiocb(uint_t command);


INTERFACE LEVEL

     Solaris DDI specific (Solaris DDI).


PARAMETERS

     command
            ioctl command for the ioc_cmd field.


DESCRIPTION

     STREAMS modules or drivers might need to issue an ioctl to a
     lower module or driver. The mkiocb() function tries to allo-
     cate (using allocb(9F))  a  STREAMS  M_IOCTL  message  block
     (iocblk(9S)).   Buffer allocation fails only when the system
     is  out  of  memory.  If  no  buffer   is   available,   the
     qbufcall(9F)  function  can  help  a  module recover from an
     allocation failure.

     The mkiocb function returns  a  mblk_t  structure  which  is
     large  enough to hold any of the ioctl messages (iocblk(9S),
     copyreq(9S) or copyresp(9S)), and has the following  special
     properties:

          b_wptr
                Set to b_rptr + sizeof(struct iocblk).

          b_cont
                Set to NULL.

          b_datap->db_type
                Set to M_IOCTL.

     The fields in the iocblk structure are initialized  as  fol-
     lows:

          ioc_cmd
                Set to the command value passed in.

          ioc_id
                Set to a unique identifier.

          ioc_cr
                Set to point to a credential  structure  encoding
                the  maximum  system privilege and which does not
                need to be freed in any fashion.

          ioc_count
                Set to 0.

          ioc_rval
                Set to 0.

          ioc_error
                Set to 0.

          ioc_flags
                Set to IOC_NATIVE to reflect that this is  native
                to the running kernel.


RETURN VALUES

     Upon success, the mkiocb() function returns a pointer to the
     allocated mblk_t of type M_IOCTL.

     On failure, it returns a null pointer.


CONTEXT

     The mkiocb() function can be called from user  or  interrupt
     context.


EXAMPLES

     Example 1: M_IOCTL Allocation

     The first example shows an M_IOCTL allocation with the ioctl
     command  TEST_CMD.  If  the  iocblk(9S) cannot be allocated,
     NULL is returned, indicating an allocation failure (line 5).
     In  line  11,  the  putnext(9F) function is used to send the
     message downstream.

      1  test_function(queue_t *q, test_info_t *testinfo)
      2  {
      3   mblk_t *mp;
      4
      5   if ((mp = mkiocb(TEST_CMD)) == NULL)
      6       return (0);
      7
      8       /* save off ioctl ID value */
      9       testinfo->xx_iocid = ((struct iocblk *)mp->b_rptr)->ioc_id;
     10
     11       putnext(q, mp);       /* send message downstream */
     12       return (1);
     13  }

     Example 2: The ioctl ID Value

     During the read service routine,  the  ioctl  ID  value  for
     M_IOCACK  or M_IOCNAK should equal the ioctl that was previ-
     ously sent by this module before processing.

      1  test_lrsrv(queue_t *q)
      2  {
      3      ...
      4
      5      switch (DB_TYPE(mp)) {
      6      case M_IOCACK:
      7      case M_IOCNAK:
      8          /* Does this match the ioctl that this module sent */
      9          ioc = (struct iocblk*)mp->b_rptr;
     10          if (ioc->ioc_id == testinfo->xx_iocid) {
     11              /* matches, so process the message */
     12              ...
     13              freemsg(mp);
     14          }
     15          break;
     16      }
     17      ...
     18  }

     Example 3: An iocblk Allocation Which Fails

     The next example shows an  iocblk  allocation  which  fails.
     Since  the  open  routine is in user context, the caller may
     block using qbufcall(9F) until memory is available.

      1  test_open(queue_t *q, dev_t devp, int oflag, int sflag, cred_t *credp)
      2  {
      3       while ((mp = mkiocb(TEST_IOCTL)) == NULL) {
      4            int id;
      5
      6            id = qbufcall(q, sizeof (union ioctypes), BPRI_HI,
      7                dummy_callback, 0);
      8            /* Handle interrupts */
      9            if (!qwait_sig(q)) {
     10                qunbufcall(q, id);
     11                return (EINTR);
     12            }
     13       }
     14       putnext(q, mp);
     15  }


SEE ALSO

     allocb(9F),   putnext(9F),   qbufcall(9F),    qwait_sig(9F),
     copyreq(9S), copyresp(9S), iocblk(9S)

     Writing Device Drivers

     STREAMS Programming Guide


WARNINGS

     It is the module's responsibility to remember the  ID  value
     of  the  M_IOCTL that was allocated. This will ensure proper
     cleanup and ID matching when the  M_IOCACK  or  M_IOCNAK  is
     received.


Man(1) output converted with man2html