Reputation: 18552
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
Upvotes: 9
Views: 12104
Reputation: 134
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.
Upvotes: 8
Reputation: 145829
When you call ioctl
you pass a file descriptor. You got the file descriptor from opening a device file like /dev/tty0
:
$ ls -l /dev/tty0
crw--w---- 1 root tty 4, 0 Mar 6 10:47 /dev/tty0
$
The number 4
here is the device major number which is encoded into the driver module the kernel has to use.
Upvotes: 1
Reputation: 2621
The kernel will know which ioctl
function to call because of the file descriptor.
To be able to call an ioctl() from userspace you will have to open a file to get the fd
, tipically a /dev/[some_device] whose driver will implement the file_operations struct, as you pointed out.
Upvotes: 1
Reputation: 47493
device_ioctl
is a function pointer. The kernel simply takes fd
as an index to an array of struct file_operations
and calls the .ioctl
of the corresponding element. The kernel never needs to knows what the function itself is which device it refers to.
This is the basis of "Everything is a file", which is Unix's moto.
Upvotes: 3