Usage and Analysis of _ IO, _ ior, _ Iow, and _ IOWR Macros in Linux kernel drivers

Source: Internet
Author: User

 

In the driver, the variable cmd transmitted by the ioctl () function is the value that the application uses to differentiate the content that the device driver requests to process. In addition to distinguishing numbers, CMD also contains several types of information that can be useful for processing. CMD is 32-bit in size and consists of four fields:
Bit31 ~ Bit30 two-bit is the "differential read/write" area, which is used to distinguish whether to read or write commands.
Bit29 ~ The 14-bit bit15 value is in the "data size" area, indicating the memory size transmitted by the ARG variable in IOCTL.
Bit20 ~ The 8-bit bit08 value is the magic number (also known as "magic number") area, which is used to distinguish it from the ioctl command of the driver of other devices.
Bit07 ~ The bit00 8-bit is the "differential serial number" area, which is the command sequence number for distinguishing commands.
The value in the "differentiated read/write zone" in the command code may be _ ioc_none (0 value), indicating no data transmission, _ ioc_read (read), _ ioc_write (write ), _ ioc_read | _ ioc_write (bidirectional ).
The kernel defines the _ IO (), _ ior (), Iow (), and _ IOWR () macros to help generate the above cmd. The following describes the implementation of _ IO (). Others are similar:

You can see the definition of _ IO () in ASM-generic/IOCTL. h.:

# DEFINE _ IO (type, NR) _ IOC (_ ioc_none, (type), (NR), 0)

Let's look at the definition of _ IOC ().:

# DEFINE _ IOC (Dir, type, NR, size )\
(DIR) <_ ioc_dirshift) | \
(Type) <_ ioc_typeshift) | \
(NR) <_ ioc_nrshift) | \
(Size) <_ ioc_sizeshift ))

It can be seen that the final result of _ IO () is composed of four parameters in _ IOC.
Let's look at the definition of _ ioc_dirshit.:

# DEFINE _ ioc_dirshift (_ ioc_sizeshift + _ ioc_sizebits)

_ Ioc_sizeshift Definition:

# DEFINE _ ioc_sizeshift (_ ioc_typeshift + _ ioc_typebits)

_ Ioc_typeslif Definition:

# DEFINE _ ioc_typeshift (_ ioc_nrshift + _ ioc_nrbits)

_ Ioc_nrshift Definition:

# DEFINE _ ioc_nrshift 0

_ Ioc_nrbits Definition:

# DEFINE _ ioc_nrbits 8

_ Ioc_typebits Definition:

# DEFINE _ ioc_typebits 8

From the above definition, we can push it up.:

Introduction

_ Ioc_typeshift = 8

_ Ioc_sizeshift = 16

_ Ioc_dirshift = 30

Therefore, the (DIR) <_ ioc_dirshift table shifts the value of Dir 30 to the left, that is, to bit31 ~ Bit30: Get the direction (read/write) attribute;
(Size) <_ ioc_sizeshift) shifts left to 16 bits to obtain the "data size" area;
(Type) <_ ioc_typeshift) shift left to 8 digits to get "Magic Zone ";
(NR) <_ ioc_nrshift) shifts left 0 (bit7 ~ Bit0 ).
In this way, the macro value of _ IO () is obtained.

The usage formats of these macros are as follows::

  • _ IO (magic number, base );
  • _ Ior (magic number, base, variable type)
  • _ Iow (magic number, base, variable type)
  • _ IOWR (magic number, base, variable type)

Magic number)
Magic number range: 0 ~ 255. Generally, the English character ""~ "Z" or ""~ "Z. The device driver obtains the magic number from the passed command, and then compares it with the magic number it processes. If it is the same, it will not process it if it is different. The magic number is the initial auxiliary state for false use. The device driver can use _ ioc_type (CMD) to obtain the magic number. It is best to set different magic numbers for drivers of different devices, but they are not required to be absolute. They can also be used by drivers of other devices.
Number of bases (serial numbers)
The base number is used to differentiate various commands. Generally, the value increments from 0 and can be reused on the same device driver. For example, the device driver can distinguish between reading and writing commands by using the same base number. The reason is that the device driver uses switch when distinguishing commands and directly uses the command variable cmd value. The macro value of the created command is composed of multiple fields. Therefore, different commands are considered to have the same base number. To obtain the base number from the command, the device driver uses the following macro:
_ Ioc_nr (CMD)
Generally, the case value in the switch uses the command itself.
Variable type
The variable type uses the ARG variable to specify the size of the transmitted data, but instead of directly inputting the data, it is substituted into the variable or the type of the variable. The reason is that the macro creation command contains sizeof () compile the command. For example, the _ ior () macro is defined:

Reference

# DEFINE _ ior (type, NR, size) _ IOC (_ ioc_read, (type), (NR), (_ ioc_typecheck (size )))

The definition of _ ioc_typecheck () is:

Reference

# DEFINE _ ioc_typecheck (t) (sizeof (t ))

To obtain the corresponding value from the transmitted command, the device driver must use the following macro functions:
_ Ioc_size (CMD)

_ IO macro

This macro function does not have any variables that can be transferred, but is used to send commands. For example:

Reference

# Define test_drv_reset _ IO ('Q', 0)

In this case, the ARG variable transmitted by the application is omitted or substituted into 0. When this macro is used in an application, for example:

IOCTL (Dev, test_dev_reset, 0) or IOCTL (Dev, test_drv_reset ).
This is because the effective factor of the variable is the variable factor. When used only as commands, it is not necessary to determine the output or input of data on the device. Therefore, the device driver does not have to handle the large-size options of the device file.

_ Ior macro
This function is used to create a command to read data from a device. For example, the following conventions can be used:

Reference

# Define test_dev_read _ IRQ ('Q', 1, INT)

This indicates that the size of data read by the application from the device is int. The following macro is used to determine the read/write status of the cmd command sent to the device driver:
_ Ioc_dir (CMD)
When running this macro, the return value type is as follows:

  • _ Ioc_none: No attribute
  • _ Ioc_read: readable attribute
  • _ Ioc_write: writable attribute
  • _ Ioc_read | _ ioc_write: readable, writable attribute

When this command is used, the ARG variable value of IOCTL () of the application specifies the cache (struct) address when reading data on the device driver.
_ Iow macro
The command is used to write data to the standby database. The remaining content is the same as _ ior. Generally, when this command is used, the ARG variable value of IOCTL () specifies the cache (struct) address when data is written to the device driver.
_ IOWR macro
Command Used to create a device to read and write data. The other content is the same as _ ior. Generally, when this command is used, the ARG variable value of IOCTL () specifies the cache (struct) address when data is written or read from the device driver.
_ Ior (), _ Iow (), iorw ():
# 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 )))

In the driver, the variable cmd transmitted by the ioctl () function is the value that the application uses to differentiate the content that the device driver requests to process. In addition to distinguishing numbers, CMD also contains several types of information that can be useful for processing. CMD is 32-bit in size and consists of four fields:
Bit31 ~ Bit30 two-bit is the "differential read/write" area, which is used to distinguish whether to read or write commands.
Bit29 ~ The 14-bit bit15 value is in the "data size" area, indicating the memory size transmitted by the ARG variable in IOCTL.
Bit20 ~ The 8-bit bit08 value is the magic number (also known as "magic number") area, which is used to distinguish it from the ioctl command of the driver of other devices.
Bit07 ~ The bit00 8-bit is the "differential serial number" area, which is the command sequence number for distinguishing commands.
The value in the "differentiated read/write zone" in the command code may be _ ioc_none (0 value), indicating no data transmission, _ ioc_read (read), _ ioc_write (write ), _ ioc_read | _ ioc_write (bidirectional ).
The kernel defines the _ IO (), _ ior (), Iow (), and _ IOWR () macros to help generate the above cmd. The following describes the implementation of _ IO (). Others are similar:

You can see the definition of _ IO () in ASM-generic/IOCTL. h.:

# DEFINE _ IO (type, NR) _ IOC (_ ioc_none, (type), (NR), 0)

Let's look at the definition of _ IOC ().:

# DEFINE _ IOC (Dir, type, NR, size )\
(DIR) <_ ioc_dirshift) | \
(Type) <_ ioc_typeshift) | \
(NR) <_ ioc_nrshift) | \
(Size) <_ ioc_sizeshift ))

It can be seen that the final result of _ IO () is composed of four parameters in _ IOC.
Let's look at the definition of _ ioc_dirshit.:

# DEFINE _ ioc_dirshift (_ ioc_sizeshift + _ ioc_sizebits)

_ Ioc_sizeshift Definition:

# DEFINE _ ioc_sizeshift (_ ioc_typeshift + _ ioc_typebits)

_ Ioc_typeslif Definition:

# DEFINE _ ioc_typeshift (_ ioc_nrshift + _ ioc_nrbits)

_ Ioc_nrshift Definition:

# DEFINE _ ioc_nrshift 0

_ Ioc_nrbits Definition:

# DEFINE _ ioc_nrbits 8

_ Ioc_typebits Definition:

# DEFINE _ ioc_typebits 8

From the above definition, we can push it up.:

Introduction

_ Ioc_typeshift = 8

_ Ioc_sizeshift = 16

_ Ioc_dirshift = 30

Therefore, the (DIR) <_ ioc_dirshift table shifts the value of Dir 30 to the left, that is, to bit31 ~ Bit30: Get the direction (read/write) attribute;
(Size) <_ ioc_sizeshift) shifts left to 16 bits to obtain the "data size" area;
(Type) <_ ioc_typeshift) shift left to 8 digits to get "Magic Zone ";
(NR) <_ ioc_nrshift) shifts left 0 (bit7 ~ Bit0 ).
In this way, the macro value of _ IO () is obtained.

The usage formats of these macros are as follows::

  • _ IO (magic number, base );
  • _ Ior (magic number, base, variable type)
  • _ Iow (magic number, base, variable type)
  • _ IOWR (magic number, base, variable type)

Magic number)
Magic number range: 0 ~ 255. Generally, the English character ""~ "Z" or ""~ "Z. The device driver obtains the magic number from the passed command, and then compares it with the magic number it processes. If it is the same, it will not process it if it is different. The magic number is the initial auxiliary state for false use. The device driver can use _ ioc_type (CMD) to obtain the magic number. It is best to set different magic numbers for drivers of different devices, but they are not required to be absolute. They can also be used by drivers of other devices.
Number of bases (serial numbers)
The base number is used to differentiate various commands. Generally, the value increments from 0 and can be reused on the same device driver. For example, the device driver can distinguish between reading and writing commands by using the same base number. The reason is that the device driver uses switch when distinguishing commands and directly uses the command variable cmd value. The macro value of the created command is composed of multiple fields. Therefore, different commands are considered to have the same base number. To obtain the base number from the command, the device driver uses the following macro:
_ Ioc_nr (CMD)
Generally, the case value in the switch uses the command itself.
Variable type
The variable type uses the ARG variable to specify the size of the transmitted data, but instead of directly inputting the data, it is substituted into the variable or the type of the variable. The reason is that the macro creation command contains sizeof () compile the command. For example, the _ ior () macro is defined:

Reference

# DEFINE _ ior (type, NR, size) _ IOC (_ ioc_read, (type), (NR), (_ ioc_typecheck (size )))

The definition of _ ioc_typecheck () is:

Reference

# DEFINE _ ioc_typecheck (t) (sizeof (t ))

To obtain the corresponding value from the transmitted command, the device driver must use the following macro functions:
_ Ioc_size (CMD)

_ IO macro

This macro function does not have any variables that can be transferred, but is used to send commands. For example:

Reference

# Define test_drv_reset _ IO ('Q', 0)

In this case, the ARG variable transmitted by the application is omitted or substituted into 0. When this macro is used in an application, for example:

IOCTL (Dev, test_dev_reset, 0) or IOCTL (Dev, test_drv_reset ).
This is because the effective factor of the variable is the variable factor. When used only as commands, it is not necessary to determine the output or input of data on the device. Therefore, the device driver does not have to handle the large-size options of the device file.

_ Ior macro
This function is used to create a command to read data from a device. For example, the following conventions can be used:

Reference

# Define test_dev_read _ IRQ ('Q', 1, INT)

This indicates that the size of data read by the application from the device is int. The following macro is used to determine the read/write status of the cmd command sent to the device driver:
_ Ioc_dir (CMD)
When running this macro, the return value type is as follows:

  • _ Ioc_none: No attribute
  • _ Ioc_read: readable attribute
  • _ Ioc_write: writable attribute
  • _ Ioc_read | _ ioc_write: readable, writable attribute

When this command is used, the ARG variable value of IOCTL () of the application specifies the cache (struct) address when reading data on the device driver.
_ Iow macro
The command is used to write data to the standby database. The remaining content is the same as _ ior. Generally, when this command is used, the ARG variable value of IOCTL () specifies the cache (struct) address when data is written to the device driver.
_ IOWR macro
Command Used to create a device to read and write data. The other content is the same as _ ior. Generally, when this command is used, the ARG variable value of IOCTL () specifies the cache (struct) address when data is written or read from the device driver.
_ Ior (), _ Iow (), iorw ():
# 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 )))

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.