Recently, I am working on Linux drivers. The. IOCTL part is found to be faulty. My computer is 2.6.32.127 kernel, Which is useless. I put it in the kernel 2.6.36, and the error is. IOCTL does not exist. I checked the definition in the source code and found that 2.6.36 was missing.
INT (* IOCTL) (struct inode *, struct file *, unsigned int, unsigned long );
This line, but only
Long (* unlocked_ioctl) (struct file *, unsigned int, unsigned long );
Long (* compat_ioctl) (struct file *, unsigned int, unsigned long );
Functions related to IOCTL operations
In this case, we can only use long (* unlocked_ioctl) (struct file *, unsigned int, unsigned long); to replace the previous int (* IOCTL) (struct inode *, struct file *, unsigned int, unsigned long); but there is still a problem, that is, their return values are different.
Unlocked_ioctl: Long IOCTL (struct file * filp, unsigned int cmd, unsigned long ARGs );
Old IOCTL: int IOCTL (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long ARGs );
At the same time, unlocked_ioctl removes the "inode" function pointer (which can be obtained anyways through the filp ),
In addition, the 'inode' value that was passed to 'ioctl 'function is available for use with the 'unlocked _ ioctl' function by way of filp-> d_entry-> d_inode:
Long (* unlocked_ioctl) (struct file * filp, unsigned int cmd, unsigned long Arg );
...
Struct inode * inode = filp-> d_entry-> d_inode;
There is a nice explanation of this at http://lwn.net/Articles/119652/
Its specific definitions in several versions are as follows:
File_operations definition in FS. h of 2.6.36
# Define have_compat_ioctl 1
# Define have_unlocked_ioctl 1
Struct file_operations {
Struct module * owner;
Loff_t (* llseek) (struct file *, loff_t, INT );
Ssize_t (* read) (struct file *, char _ User *, size_t, loff_t *);
Ssize_t (* write) (struct file *, const char _ User *, size_t, loff_t *);
Ssize_t (* aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t );
Ssize_t (* aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t );
INT (* readdir) (struct file *, void *, filldir_t );
Unsigned int (* poll) (struct file *, struct poll_table_struct *);
Long (* unlocked_ioctl) (struct file *, unsigned int, unsigned long );
Long (* compat_ioctl) (struct file *, unsigned int, unsigned long );
INT (* MMAP) (struct file *, struct vm_area_struct *);
INT (* open) (struct inode *, struct file *);
INT (* flush) (struct file *, fl_owner_t ID );
INT (* release) (struct inode *, struct file *);
INT (* fsync) (struct file *, int datasync );
INT (* aio_fsync) (struct kiocb *, int datasync );
INT (* fasync) (INT, struct file *, INT );
INT (* Lock) (struct file *, Int, struct file_lock *);
Ssize_t (* sendpage) (struct file *, struct page *, Int, size_t, loff_t *, INT );
Unsigned long (* get_unmapped_area) (struct file *, unsigned long, unsigned long,
Unsigned long, unsigned long );
INT (* check_flags) (INT );
INT (* flock) (struct file *, Int, struct file_lock *);
Ssize_t (* splice_write) (struct pipe_inode_info *, struct file *, loff_t *, size_t,
Unsigned INT );
Ssize_t (* splice_read) (struct file *, loff_t *, struct pipe_inode_info *, size_t,
Unsigned INT );
INT (* setlease) (struct file *, long, struct file_lock **);
};
FS. h of version 2.6.34 is as follows:
1480 //
1481 // note:
1482 // read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl
1483 // can be called without the big kernel lock held in all filesystems.
1484 //
1485 struct file_operations {
1486 struct module * owner;
1487 loff_t (* llseek) (struct file *, loff_t, INT );
1488 ssize_t (* read) (struct file *, char _ User *, size_t, loff_t *);
1489 ssize_t (* write) (struct file *, const char _ User *, size_t, loff_t *);
1490 ssize_t (* aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t );
1491 ssize_t (* aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t );
1492 int (* readdir) (struct file *, void *, filldir_t );
1493 unsigned int (* poll) (struct file *, struct poll_table_struct *);
1494 int (* IOCTL) (struct inode *, struct file *, unsigned int, unsigned long );
1495 long (* unlocked_ioctl) (struct file *, unsigned int, unsigned long );
1496 long (* compat_ioctl) (struct file *, unsigned int, unsigned long );
1497 int (* MMAP) (struct file *, struct vm_area_struct *);
1498 int (* open) (struct inode *, struct file *);
1499 int (* flush) (struct file *, fl_owner_t ID );
1500 int (* release) (struct inode *, struct file *);
1501 int (* fsync) (struct file *, struct dentry *, int datasync );
1502 int (* aio_fsync) (struct kiocb *, int datasync );
1503 int (* fasync) (INT, struct file *, INT );
1504 int (* Lock) (struct file *, Int, struct file_lock *);
1505 ssize_t (* sendpage) (struct file *, struct page *, Int, size_t, loff_t *, INT );
1506 unsigned long (* get_unmapped_area) (struct file *, unsigned long, unsigned long );
1507 int (* check_flags) (INT );
1508 int (* flock) (struct file *, Int, struct file_lock *);
1509 ssize_t (* splice_write) (struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned INT );
1510 ssize_t (* splice_read) (struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned INT );
1511 int (* setlease) (struct file *, long, struct file_lock **);
1512 };
File_operations definition in FS. h of 2.6.32.2
// These macros are for out of kernel modules to test that
// The kernel supports the unlocked_ioctl and compat_ioctl
// Fields in struct file_operations.
# Define have_compat_ioctl 1
# Define have_unlocked_ioctl 1
//
// Note:
// Read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl
// Can be called without the big kernel lock held in all filesystems.
//
Struct file_operations {
Struct module * owner;
Loff_t (* llseek) (struct file *, loff_t, INT );
Ssize_t (* read) (struct file *, char _ User *, size_t, loff_t *);
Ssize_t (* write) (struct file *, const char _ User *, size_t, loff_t *);
Ssize_t (* aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t );
Ssize_t (* aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t );
INT (* readdir) (struct file *, void *, filldir_t );
Unsigned int (* poll) (struct file *, struct poll_table_struct *);
INT (* IOCTL) (struct inode *, struct file *, unsigned int, unsigned long );
Long (* unlocked_ioctl) (struct file *, unsigned int, unsigned long );
Long (* compat_ioctl) (struct file *, unsigned int, unsigned long );
INT (* MMAP) (struct file *, struct vm_area_struct *);
INT (* open) (struct inode *, struct file *);
INT (* flush) (struct file *, fl_owner_t ID );
INT (* release) (struct inode *, struct file *);
INT (* fsync) (struct file *, struct dentry *, int datasync );
INT (* aio_fsync) (struct kiocb *, int datasync );
INT (* fasync) (INT, struct file *, INT );
INT (* Lock) (struct file *, Int, struct file_lock *);
Ssize_t (* sendpage) (struct file *, struct page *, Int, size_t, loff_t *, INT );
Unsigned long (* get_unmapped_area) (struct file *, unsigned long, unsigned long,
Unsigned long, unsigned long );
INT (* check_flags) (INT );
INT (* flock) (struct file *, Int, struct file_lock *);
Ssize_t (* splice_write) (struct pipe_inode_info *, struct file *, loff_t *, size_t,
Unsigned INT );
Ssize_t (* splice_read) (struct file *, loff_t *, struct pipe_inode_info *, size_t,
Unsigned INT );
INT (* setlease) (struct file *, long, struct file_lock **);
};
From: http://blog.sina.com.cn/s/blog_5f8665e70100p46z.html