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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With