码迷,mamicode.com
首页 > 其他好文 > 详细

驱动笔记 - ioctl

时间:2014-11-19 23:39:18      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:blog   io   ar   使用   sp   数据   on   div   log   

#include <linux/ioctl.h>

定义命令
_IO(type,nr) 没有参数的命令
_IOR(type,nr,datatype) 从驱动中读数据
_IOW(type,nr,datatype) 写数据到驱动
_IOWR(type,nr,datatype) 双向传送,type和number成员作为参数被传递
例:
#define MEM_IOC_MAGIC ‘m‘
#define MEM_IOCSET _IOW(MEM_IOC_MAGIC,0,int)
#define MEM_IOCGQSET _IOR(MEM_IOC_MAGIC,1,int)

unlock_ioctl一般使用switch,不匹配的命令通常返回-EINVAl

应用层调用ioctl

#include <linux/ioctl.h>
ioctl(int fd,int command, (char*)argstruct)

参数检测(检测是否有效)
int access_ok(int type, const void *addr, unsigned long size)
一般把addr强制转化为(void __user *)
type:VERIFY_READ或者VERIFY_WRITE
size:操作的大小
返回值:1成功 0失败
access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd))
access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));

不需要检测(函数中自带有检测)
unsigned long copy_from_user (void * to, const void __user * from, unsigned long n) //此函数自带access_ok
unsigned long copy_to_user (void __user * to, const void * from, unsigned long n) //此函数自带access_ok
get_user
put_user

需要检测
__get_user
__get_user(tmp, (int __user *)arg);

__put_user

 

例:

long ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int err = 0,tmp;
	int retval = 0;

	if(_IOC_TYPE(cmd) != MEMDEV_MAGIC)
		return -ENOTTY;
	if(_IOC_NR(cmd) > MEMDEV_MAXNR)
		return -ENOTTY;
	if(_IOC_DIR(cmd) & _IOC_READ)
		err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
	else if(_IOC_DIR(cmd) & _IOC_WRITE)
		err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
	if(err)
		return -EFAULT;

	switch(cmd)
	{
		case MEMDEV_TELL:
			printk(KERN_ALERT "Your call MEMDEV_TELL.\n");
			break;
		case MEMDEV_RECEIVE:
			if(retval = __get_user(tmp, (int __user *)arg) == 0)
			{
				printk(KERN_ALERT "memdev receive number is %d\n",tmp);
			}
			else
				printk(KERN_ALERT "No receive.\n");
			break;
		case MEMDEV_SET:
			tmp = 110;
			if(retval = __put_user(tmp, (int __user *)arg) == 0)
			{
				printk(KERN_ALERT "memdev send number is %d\n", tmp);

			}
			else
				printk(KERN_ALERT "Sent error\n");
			break;
		default:
			return -ENOTTY;
	}
	return retval;
}

  

 

驱动笔记 - ioctl

标签:blog   io   ar   使用   sp   数据   on   div   log   

原文地址:http://www.cnblogs.com/tolimit/p/4109371.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!