Here is the ioctl
call in user space:
int ioctl(int fd, int cmd, ...);
As far as I know, when we want to perfrom IO operations, we define our own ioctl
function with a set of requests (commands), assign our ioctl
to a file_operations structure like this:
struct file_operations fops = {
.read = device_read,
.write = device_write,
.ioctl = device_ioctl, // device_ioctl is our function
.open = device_open,
.release = device_release,
};
And the device_ioctl
function is defined differently compared to the user space interface:
static long device_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
I think based on the file descriptor, the kernel can get the appropriate file structure and calls the device's ioctl
.
This is just a guess because I cannot find it the generic function definition where the kernel selects appropriate ioctl
function based on the file descriptor fd
passed into the generic ioctl
interface? There are only 3 ioctl
definitions I can find, but apparently those are just the devices' definitions, not the kernel: ioctl
Look in the Linux source code, fs/ioctl.c (http://lxr.free-electrons.com/source/fs/ioctl.c)
There you will see the syscall for ioctl:
SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
This in turns calls do_vfs_ioctl(), which calls vfs_ioctl() which then calls the unlocked_ioctl function defined for that filesystem in the file_operations structure.
This will be your device_ioctl function that you registered.