ioctl的疑问解决办法

ioctl的疑问
驱动部分:

C/C++ code

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;    
}

测试程序:

C/C++ code

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,希望高手指点下
网上搜索了下,有人说

引用

第二个参数不要用2。可以用linux/ioctl.h里面提供的IOC宏

2好像被2.6的内核干掉了。以前我喜欢直接用0x01, 0x02,后来全改成IOW/IOR了


在别人地盘混 怎么能不守规矩
老实从了__IOW _IOR 吧


ioctl的cmd不是想怎么定义就怎么定义的 得按规矩来
内核有一个自定义头文件 用户层也得有一个相同的自定义头文件
每一个头文件都必须使用__IOW _IOR来定义这些cmd

如果你随便定义一个cmd 很可能就跟linux内核中这类驱动已经定义好的cmd重复
于是就优先被这类驱动默认的ioctl处理函数截获了,只有这类驱动默认的ioctl处理函数不认识的cmd,才轮得到你自定义的ioctl


听说比较新的版本ioctl接口发生了变化了,不过好久没搞驱动了,忘了。


不知道你的版本
以3.0.4为例
fs/ioctl.c 
(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) -> do_vfs_ioctl

C/C++ code

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);

[b]case FIGETBSZ:[/b]
return put_user(inode->i_sb->s_blocksize, argp);

[b]default:[/b]
if (S_ISREG(inode->i_mode))
error = file_ioctl(filp, cmd, arg);
else
error =[b] vfs_ioctl[/b](filp, cmd, arg);
break;
}
return error;
}

ioctl的疑问解决办法

相关文章:

你感兴趣的文章:

标签云: