MKIOCB(9F) Kernel Functions for Drivers MKIOCB(9F)
NAME
mkiocb - allocates a STREAMS ioctl block for M_IOCTL messages in the
kernel.
SYNOPSIS
#include <sys/stream.h>
mblk_t *mkiocb(
uint_t command);
INTERFACE LEVEL
illumos DDI specific (illumos 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 allocate (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 follows:
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, interrupt, or kernel
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 previously 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 GuideWARNINGS
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.
May 21, 2022 MKIOCB(9F)