非阻塞I/O的应用程序通常会使用poll()、select()甚至是epoll()系统调用进行设备的非阻塞访问。无论是哪一种系统调用对应的都是设备驱动中的poll()函数。
驱动中poll函数原型:
unsigned int (*poll) (struct file *filp, struct poll_table_struct *wait)
第一个参数是file结构体指针。
第二个参数为轮询表指针。
驱动中的poll函数通常需要完成两件事情:
① 将可能会引起设备文件状态变化的等待队列头,添加poll_table_struct中
② 返回一个操作码,表示是否能对设备进行非阻塞访问、写访问等
下面以书中P202的代码为例:
static unsigned int xxx_poll(struct file *filp, poll_table *wait)
{
unsigned int mask = 0;
struct xxx_dev *dev = filp->private_data;
...
poll_wait(filp, &dev->r_wait, wait);
poll_wait(filp, &dev->w_wait, wait);
if(...) { /*数据可读*/
mask |= POLLIN | POLLRDNORM; /*返回数据可读标识码*/
}
if(...) { /*数据可写*/
mask |= POLLOUT | POLLWRNORM; /*返回数据可写标识码*/
}
...
return mask;
}
① struct xxx_dev *dev = filp->private_data; 通过私有数据获取设备结构体指针
② poll_wait(filp, &dev->r_wait, wait);
poll_wait(filp, &dev->r_wait, wait); 完成第一件事将会引起设备文件状态变化的等待队列头添加到轮询表中
③ 如果可读,返回数据可读标识码。如果可写,返回数据可写标识码。