ioctl驱动方法有和用户空间版本不同的原型:
int(*ioctl)(structinode*inode,structfile*filp,unsignedintcmd,unsignedlongarg);
2、阻塞I/O
阻塞进程,使它进入睡眠直到请求可继续。
当一个进程被置为睡眠,它被标识为处于一个特殊的状态并且从调度器的运行队列中去除,直到发生某些事情改变了那个状态。一个睡着的进程将不被任何CPU调度,因此不会运行,一个睡着的进程已被搁置到系统的一边,等待以后发生事件。
3、参考和总结
#include<linux/ioctl.h>
声明用来定义ioctl命令的宏定义.当前被<linux/fs.h>包含.
_IOC_NRBITS
_IOC_TYPEBITS
_IOC_SIZEBITS
_IOC_DIRBITS
ioctl命令的不同位段所使用的位数.还有4个宏来指定MASK和4个指定SHIFT,但是它们
主要是给内部使用._IOC_SIZEBIT是一个要检查的重要的值,因为它跨体系改变.
_IOC_NONE
_IOC_READ
_IOC_WRITE
"方向"位段可能的值."read"和"write"是不同的位并且可相或来指定read/write.这些值是基
于0的.
_IOC(dir,type,nr,size)
_IO(type,nr)
_IOR(type,nr,size)
_IOW(type,nr,size)
_IOWR(type,nr,size)
用来创建ioclt命令的宏定义.
_IOC_DIR(nr)
_IOC_TYPE(nr)
_IOC_NR(nr)
_IOC_SIZE(nr)
用来解码一个命令的宏定义.特别地,_IOC_TYPE(nr)是_IOC_READ和_IOC_WRITE的
OR结合.
#include<asm/uaccess.h>
intaccess_ok(inttype,constvoid*addr,unsignedlongsize);
检查一个用户空间的指针是可用的.access_ok返回一个非零值,如果应当允许存取.
VERIFY_READ
VERIFY_WRITE
access_ok中type参数的可能取值.VERIFY_WRITE是VERIFY_READ的超集.
#include<asm/uaccess.h>
intput_user(datum,ptr);
intget_user(local,ptr);
int__put_user(datum,ptr);
int__get_user(local,ptr);
用来存储或获取一个数据到或从用户空间的宏.传送的字节数依赖sizeof(*ptr).常规的版本
调用access_ok,而常规版本(__put_user和__get_user)假定access_ok已经被调用了.
#include<linux/capability.h>
定义各种CAP_符号,描述一个用户空间进程可有的能力.
intcapable(intcapability);
返回非零值如果进程有给定的能力.
#include<linux/wait.h>
typedefstruct{/*...*/}wait_queue_head_t;
voidinit_waitqueue_head(wait_queue_head_t*queue);
DECLARE_WAIT_QUEUE_HEAD(queue);
Linux等待队列的定义类型.一个wait_queue_head_t必须被明确在运行时使用
init_waitqueue_head或者编译时使用DEVLARE_WAIT_QUEUE_HEAD进行初始化.
voidwait_event(wait_queue_head_tq,intcondition);
intwait_event_interruptible(wait_queue_head_tq,intcondition);
intwait_event_timeout(wait_queue_head_tq,intcondition,inttime);
intwait_event_interruptible_timeout(wait_queue_head_tq,intcondition,inttime);
使进程在给定队列上睡眠,直到给定条件值为真值.
voidwake_up(structwait_queue**q);
voidwake_up_interruptible(structwait_queue**q);
voidwake_up_nr(structwait_queue**q,intnr);
voidwake_up_interruptible_nr(structwait_queue**q,intnr);
voidwake_up_all(structwait_queue**q);
voidwake_up_interruptible_all(structwait_queue**q);
voidwake_up_interruptible_sync(structwait_queue**q);
唤醒在队列q上睡眠的进程._interruptible的形式只唤醒可中断的进程.正常地,只有一个互斥等待者被唤醒,但是这个行为可被_nr或者_all形式所改变._sync版本在返回之前不重新调度CPU.
#include<linux/sched.h>
set_current_state(intstate);
设置当前进程的执行状态.TASK_RUNNING意味着它已经运行,而睡眠状态是
TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE.
voidschedule(void);
选择一个可运行的进程从运行队列中.被选中的进程可是当前进程或者另外一个.
typedefstruct{/*...*/}wait_queue_t;
init_waitqueue_entry(wait_queue_t*entry,structtask_struct*task);
wait_queue_t类型用来放置一个进程到一个等待队列.
voidprepare_to_wait(wait_queue_head_t*queue,wait_queue_t*wait,intstate);
voidprepare_to_wait_exclusive(wait_queue_head_t*queue,wait_queue_t*wait,intstate);
voidfinish_wait(wait_queue_head_t*queue,wait_queue_t*wait);
帮忙函数,可用来编码一个手工睡眠.
voidsleep_on(wiat_queue_head_t*queue);
voidinterruptible_sleep_on(wiat_queue_head_t*queue);
老式的不推荐的函数,它们无条件地使当前进程睡眠.
#include<linux/poll.h>
voidpoll_wait(structfile*filp,wait_queue_head_t*q,poll_table*p);
将当前进程放入一个等待队列,不立刻调度.它被设计来被设备驱动的poll方法使用.
intfasync_helper(structinode*inode,structfile*filp,intmode,structfasync_struct**fa);
一个"帮忙者",来实现fasync设备方法.mode参数是传递给方法的相同的值,而fa指针指向一个设备特定的fasync_struct*.
voidkill_fasync(structfasync_struct*fa,intsig,intband);
如果这个驱动支持异步通知,这个函数可用来发送一个信号到登记在fa中的进程.
intnonseekable_open(structinode*inode,structfile*filp);
loff_tno_llseek(structfile*file,loff_toffset,intwhence);
nonseekable_open应当在任何不支持移位的设备的open方法中被调用.这样的设备应当使
用no_llseek作为它们的llseek方法.