called at the application layer in the case of the IOCTL () function, the second parameter of the function is cmd, such as a downward use:
RET = IOCTL (PPP_DEV_FD, Pppiocgidle, IP);
look at the format of cmd:
and then there's the research.
throughthe cmd of the IOCTL () function, which is issued with commands that require the underlying response. The size of the cmd command is 32 bits, divided into 4 parts:Bit31~bit30:The "Read and write" area, which is to distinguish between reading a command or writing a command; Bit29~bit16: the "Data size" area, which represents the amount of memory transferred by the ARG variable in the IOCTL ().
BIT15~BIT8:"Magic number”(also known as the "magic number") area, which is used to differentiate from the IOCTL commands of other device drivers. Bit7~bit0: The "difference ordinal" area, which is a command sequence ordinal that distinguishes commands.
For example, for the Pppiocgidle command above,
#define _ior (type,nr,size) _ioc (_ioc_read, (Type), (NR), (_ioc_typecheck (size)))
_ioc_read: This is the read command, defined as follows:
/* * Direction bits. */#define _ioc_none0u#define _ioc_write1u#define _ioc_read2u
_ioc_typecheck:/ * Provoke compile error for invalid uses of size argument * /
/* Provoke compile error for invalid uses of size argument */#define _ioc_sizebits14extern unsigned int __invalid_size_arg UMENT_FOR_IOC, #define _ioc_typecheck (t) (sizeof (t) = sizeof (t[1) && sizeof (T) < (1 << _ioc_ sizebits))? sizeof (t): __INVALID_SIZE_ARGUMENT_FOR_IOC)
_ioc_sizebits is defined as 14 because the size field occupies 14 bits in 32 bits (bit29~bit16)
Therefore, thepppiocgidle command is equivalent to:
#define PPPIOCGIDLE <---> (2 << 30) | (' t ' << 8) | (<< 0) | (Size << 16)
Refer to the Linux kernel file:
include/asm-generic/ioctl.h
#ifndef _asm_generic_ioctl_h#define _asm_generic_ioctl_h/* IOCTL command encoding:32 bits total, command in lower , * size of the parameter structure in the lower bits of the * upper. * Encoding the size of the parameter structure in the IOCTL request * are useful for catching programs compiled with an old ve Rsions * and to avoid overwriting user space outside the user buffer area. * The highest 2 bits is reserved for indicating the ' access mode '. * Note:this limits the max parameter size to 16kb-1! *//* * The following is for compatibility across the various Linux * platforms. The generic IOCTL numbering scheme doesn ' t really enforce * a type field. De facto, however, the top 8 bits of the lower * bits is indeed used as a type field, so we might just as well make * This is explicit here. Sure to use the decoding macros * below. */#define _ioc_nrbits8#define _ioc_typebits8#define _ioc_sizebits14#define _ioc_dirbits2#define _IOC_NRMASK (1 << _ioc_nrbits)-1) #define _IOC_TYPEMASK ((1 << _ioc_typebits)-1) #define _IOC_SIZEMASK ((1 << _ioc_ Sizebits)-1) #define _IOC_DIRMASK ((1 << _ioc_dirbits)-1) #define _ioc_nrshift0#define _ioc_typeshift (_ioc_ nrshift+_ioc_nrbits) #define _IOC_SIZESHIFT (_ioc_typeshift+_ioc_typebits) #define _IOC_DIRSHIFT (_ioc_sizeshift+_ ioc_sizebits)/* * Direction bits. */#define _ioc_none0u#define _ioc_write1u#define _ioc_read2u#define _ioc (dir,type,nr,size) ((dir) << _IOC_ Dirshift) | ((type) << _ioc_typeshift) | ((NR) << _ioc_nrshift) | ((size) << _ioc_sizeshift)) /* Provoke compile error for invalid uses of size argument */extern unsigned int __invalid_size_argument_for_ioc; #define _ Ioc_typecheck (t) (sizeof (t) = sizeof (t[1) && sizeof (T) < (1 << _ioc_sizebits))? sizeof (t): __INVALID_SIZE_ARGUMENT_FOR_IOC)/* Used to create numbers */#define _IO (TYPE,NR) _ioc (_ioc_none, (Type), (NR) , 0) #define _ior (type,nr,size) _ioc (_ioc_read, (Type), (NR), (_Ioc_typecheck (size))) #define _IOW (type,nr,size) _ioc (_ioc_write, (Type), (NR), (_ioc_typecheck (size))) #define _IOWR ( type,nr,size) _ioc (_ioc_read|_ioc_write, (Type), (NR), (_ioc_typecheck (size))) #define _ior_bad (Type,nr,size) _ioc (_ Ioc_read, (Type), (NR), sizeof (size)) #define _IOW_BAD (type,nr,size) _ioc (_ioc_write, (Type), (NR), sizeof (size)) # Define _iowr_bad (Type,nr,size) _ioc (_ioc_read|_ioc_write, (Type), (NR), sizeof (size))/*/used to decode IOCTL numbers. */#define _IOC_DIR (NR) (((NR) >> _ioc_dirshift) & _ioc_dirmask) #define _ioc_type (NR) (((NR) >> _ioc_ Typeshift) & _ioc_typemask) #define _IOC_NR (NR) (((NR) >> _ioc_nrshift) & _ioc_nrmask #define _ioc_size (NR ) (((NR) >> _ioc_sizeshift) & _ioc_sizemask)/* ... and for the drivers/sound files ... */#define IOC_IN (_ioc_write << _ioc_dirshift) #define IOC_OUT (_ioc_read << _ioc_dirshift) #define Ioc_inout ((_ioc_write|_ioc_read) << _ioc_dirshift) #define IOCSIZE_MASK (_ioc_sizemask << _ioc_sizeshift) #defineIocsize_shift (_ioc_sizeshift) #endif/* _asm_generic_ioctl_h */
The IOCTL () function command word generation in Linux