当前位置: 技术问答>linux和unix
ioctl的疑问
来源: 互联网 发布时间:2017-01-27
本文导语: 驱动部分: MODULE_LICENSE("GPL"); #define TEST_ENA 0x00 #define TEST_SET_TIME 0x01 #define TEST_SET_DATE 0x02 #define TEST_SET_CH0_PIXEL 0x03 int test_ioctl(struct inode...
驱动部分:
测试程序:
结果发现ioctl在i=2的时候,不会调用test_ioctl,其他时候均没有问题,返回值是0,希望高手指点下
网上搜索了下,有人说
MODULE_LICENSE("GPL");
#define TEST_ENA 0x00
#define TEST_SET_TIME 0x01
#define TEST_SET_DATE 0x02
#define TEST_SET_CH0_PIXEL 0x03
int test_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
unsigned int __user *argp=(unsigned int __user *)arg;
unsigned char tmp_uchar;
printk("CMD=%d",cmd);
switch (cmd)
{
case TEST_ENA :
break;
case TEST_SET_TIME :
break;
case TEST_SET_DATE:
break;
case TEST_SET_CH0_PIXEL :
break;
default:
break;
}//end switch
return 0;
}
测试程序:
int main(void)
{
int wdt_fd = -1;
int ret,nTimeout=20;
int i;
Osd_Date osd_date;
wdt_fd = open("/dev/ti_test",O_WRONLY);
if(wdt_fd == -1)
{
printf("CEM Open error!!n");
}
i=2;
ret=ioctl(wdt_fd, i ,&nTimeout);
printf("ret=%d n",ret);
return 0;
}
结果发现ioctl在i=2的时候,不会调用test_ioctl,其他时候均没有问题,返回值是0,希望高手指点下
网上搜索了下,有人说
|
不知道你的版本
以3.0.4为例
fs/ioctl.c
(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) -> do_vfs_ioctl
FIGETBSZ 就是为2的cmd ,没有被系统占用的cmd ,才可能轮到你自己定义的ioctl处理
file_ioctl --> vfs_ioctl -->
static long vfs_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
int error = -ENOTTY;
if (!filp->f_op || !filp->f_op->unlocked_ioctl)
goto out;
error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
if (error == -ENOIOCTLCMD)
error = -EINVAL;
out:
return error;
}
以3.0.4为例
fs/ioctl.c
(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) -> do_vfs_ioctl
int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
unsigned long arg)
{
int error = 0;
int __user *argp = (int __user *)arg;
struct inode *inode = filp->f_path.dentry->d_inode;
switch (cmd) {
case FIOCLEX:
set_close_on_exec(fd, 1);
break;
case FIONCLEX:
set_close_on_exec(fd, 0);
break;
case FIONBIO:
error = ioctl_fionbio(filp, argp);
break;
case FIOASYNC:
error = ioctl_fioasync(fd, filp, argp);
break;
case FIOQSIZE:
if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
S_ISLNK(inode->i_mode)) {
loff_t res = inode_get_bytes(inode);
error = copy_to_user(argp, &res, sizeof(res)) ?
-EFAULT : 0;
} else
error = -ENOTTY;
break;
case FIFREEZE:
error = ioctl_fsfreeze(filp);
break;
case FITHAW:
error = ioctl_fsthaw(filp);
break;
case FS_IOC_FIEMAP:
return ioctl_fiemap(filp, arg);
case FIGETBSZ:
return put_user(inode->i_sb->s_blocksize, argp);
default:
if (S_ISREG(inode->i_mode))
error = file_ioctl(filp, cmd, arg);
else
error = vfs_ioctl(filp, cmd, arg);
break;
}
return error;
}
FIGETBSZ 就是为2的cmd ,没有被系统占用的cmd ,才可能轮到你自己定义的ioctl处理
file_ioctl --> vfs_ioctl -->
static long vfs_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
int error = -ENOTTY;
if (!filp->f_op || !filp->f_op->unlocked_ioctl)
goto out;
error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
if (error == -ENOIOCTLCMD)
error = -EINVAL;
out:
return error;
}
|
在别人地盘混 怎么能不守规矩
老实从了__IOW _IOR 吧
老实从了__IOW _IOR 吧
|
ioctl的cmd不是想怎么定义就怎么定义的 得按规矩来
内核有一个自定义头文件 用户层也得有一个相同的自定义头文件
每一个头文件都必须使用__IOW _IOR来定义这些cmd
如果你随便定义一个cmd 很可能就跟linux内核中这类驱动已经定义好的cmd重复
于是就优先被这类驱动默认的ioctl处理函数截获了,只有这类驱动默认的ioctl处理函数不认识的cmd,才轮得到你自定义的ioctl
内核有一个自定义头文件 用户层也得有一个相同的自定义头文件
每一个头文件都必须使用__IOW _IOR来定义这些cmd
如果你随便定义一个cmd 很可能就跟linux内核中这类驱动已经定义好的cmd重复
于是就优先被这类驱动默认的ioctl处理函数截获了,只有这类驱动默认的ioctl处理函数不认识的cmd,才轮得到你自定义的ioctl
|
听说比较新的版本ioctl接口发生了变化了,不过好久没搞驱动了,忘了。
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。