Defining ioctl Commands

To define an ioctl command, you’d call one of the following macros: _IO, _IOR, _IOW, or _IOWR. An explanation of each macro is provided in Table 3-1.

Table 3-1. ioctl Command Macros

Macro

Description

_IO

Creates an ioctl command for an I/O operation that transfers no data—in other words, the data argument in d_ioctl will be unused—for example, ejecting removable media

_IOR

Creates an ioctl command for a read operation; read operations transfer data from the device to user space; for example, retrieving error information

_IOW

Creates an ioctl command for a write operation; write operations transfer data to the device from user space; for example, setting a device parameter

_IOWR

Creates an ioctl command for an I/O operation with bidirectional data transfers

_IO, _IOR, _IOW, and _IOWR are defined in the <sys/ioccom.h> header as follows:

#define _IO(g,n)        _IOC(IOC_VOID,  (g), (n), 0)
#define _IOR(g,n,t)     _IOC(IOC_OUT,   (g), (n), sizeof(t))
#define _IOW(g,n,t)     _IOC(IOC_IN,    (g), (n), sizeof(t))
#define _IOWR(g,n,t)    _IOC(IOC_INOUT, (g), (n), sizeof(t))

The g argument, which stands for group, expects an 8-bit magic number. You can choose any number—just use it throughout your driver.

The n argument is the ordinal number. This number is used to differentiate your driver’s ioctl commands from one another.

Finally, the t argument is the type of data transferred during the I/O operation. Obviously, the _IO macro does not have a t argument, because no data transfer occurs.

Generally, ioctl command definitions look like this:

#define FOO_DO_SOMETHING        _IO('F', 1)
#define FOO_GET_SOMETHING       _IOR('F', 2, int)
#define FOO_SET_SOMETHING       _IOW('F', 3, int)
#define FOO_SWITCH_SOMETHING    _IOWR('F', 10, struct foo)

Here, 'F' is the magic number for these ioctl commands. Customarily, the first letter of your driver’s name—in uppercase—is selected as the magic number.

Naturally, all of the ordinal numbers are unique. But they don’t have to be consecutive. You can leave gaps.

Lastly, note that you can pass structures as the t argument. Using a structure is how you’ll pass multiple arguments to an ioctl-based operation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.187.24