in adb.c [714:770]
static ssize_t adb_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
int ret = 0;
struct adbdev_state *state = file->private_data;
struct adb_request *req;
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
if (count < 2)
return -EINVAL;
if (count > sizeof(req->reply))
count = sizeof(req->reply);
req = NULL;
spin_lock_irqsave(&state->lock, flags);
add_wait_queue(&state->wait_queue, &wait);
set_current_state(TASK_INTERRUPTIBLE);
for (;;) {
req = state->completed;
if (req != NULL)
state->completed = req->next;
else if (atomic_read(&state->n_pending) == 0)
ret = -EIO;
if (req != NULL || ret != 0)
break;
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
break;
}
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
spin_unlock_irqrestore(&state->lock, flags);
schedule();
spin_lock_irqsave(&state->lock, flags);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&state->wait_queue, &wait);
spin_unlock_irqrestore(&state->lock, flags);
if (ret)
return ret;
ret = req->reply_len;
if (ret > count)
ret = count;
if (ret > 0 && copy_to_user(buf, req->reply, ret))
ret = -EFAULT;
kfree(req);
return ret;
}