in uio.c [565:618]
static ssize_t uio_read(struct file *filep, char __user *buf,
size_t count, loff_t *ppos)
{
struct uio_listener *listener = filep->private_data;
struct uio_device *idev = listener->dev;
DECLARE_WAITQUEUE(wait, current);
ssize_t retval = 0;
s32 event_count;
if (count != sizeof(s32))
return -EINVAL;
add_wait_queue(&idev->wait, &wait);
do {
mutex_lock(&idev->info_lock);
if (!idev->info || !idev->info->irq) {
retval = -EIO;
mutex_unlock(&idev->info_lock);
break;
}
mutex_unlock(&idev->info_lock);
set_current_state(TASK_INTERRUPTIBLE);
event_count = atomic_read(&idev->event);
if (event_count != listener->event_count) {
__set_current_state(TASK_RUNNING);
if (copy_to_user(buf, &event_count, count))
retval = -EFAULT;
else {
listener->event_count = event_count;
retval = count;
}
break;
}
if (filep->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
break;
}
if (signal_pending(current)) {
retval = -ERESTARTSYS;
break;
}
schedule();
} while (1);
__set_current_state(TASK_RUNNING);
remove_wait_queue(&idev->wait, &wait);
return retval;
}