Take the 2-minute tour ×

Suppose I have defined the following.

#define MY_IOCTL_CMD1 _IOR(MAGIC_NUMBER, 0x01, arg1)
#define MY_IOCTL_CMD2 _IOW(MAGIC_NUMBER, 0x02, arg2)
#define MY_COMPAT_IOCTL_CMD1 _IOR(MAGIC_NUMBER, 0x01, compat_arg1)
#define MY_COMPAT_IOCTL_CMD2 _IOW(MAGIC_NUMBER, 0x02, compat_arg2)

Now when we do ioctl from user space, we usually do

ioctl(fd, MY_IOCTL_CMD1, &arg1)

Q: Do we really need to have an ioctl with MY_COMPAT_IOCTL_CMD1 as request?

In the devide code I have handlers defined as follows. ioctl: device_ioctl

compat_ioctl: device_compat_ioctl

Can anybody please provide some explanations around this?

share|improve this question

migrated from unix.stackexchange.com Jun 8 '11 at 12:40


1 Answer 1

This compat stuff is for running a 32-bit program in a 64-bit kernel. When you call the ioctl(fd, MY_IOCTL_CMD1, &arg1) from a 32-bit program on a 64-bit kernel, the kernel will divert the ioctl to the .compat_ioctl function in the file_operations struct. This compat_ioctl function is responsible for copying the user argument arg1 as if it were compat_arg1, which uses the 32-bit layout. The compat_arg1 typedef is defined in the kernel so that when compiled for 64-bit, the structure is exactly the same layout as the arg1 compiled for 32-bit.

The definition of MY_IOCTL_CMD1 will take the sizeof arg1 into account when creating the cmd id. When you compile a program for a 32-bit machine, the value for MY_IOCTL_CMD1 will be different than if you compiled it for a 64-bit machine. The 32-bit MY_IOCTL_CMD1 should have the same value as the 64-bit MY_COMPAT_IOCTL_CMD1 in the kernel, however.

There's never a need to use compat_arg1 or MY_COMPAT_IOCTL_CMD1 in a user-space application. Those are only for code compiled in the kernel.

share|improve this answer

Your Answer


