in most_cdev.c [182:227]
static ssize_t comp_write(struct file *filp, const char __user *buf,
size_t count, loff_t *offset)
{
int ret;
size_t to_copy, left;
struct mbo *mbo = NULL;
struct comp_channel *c = filp->private_data;
mutex_lock(&c->io_mutex);
while (c->dev && !ch_get_mbo(c, &mbo)) {
mutex_unlock(&c->io_mutex);
if ((filp->f_flags & O_NONBLOCK))
return -EAGAIN;
if (wait_event_interruptible(c->wq, ch_has_mbo(c) || !c->dev))
return -ERESTARTSYS;
mutex_lock(&c->io_mutex);
}
if (unlikely(!c->dev)) {
ret = -ENODEV;
goto unlock;
}
to_copy = min(count, c->cfg->buffer_size - c->mbo_offs);
left = copy_from_user(mbo->virt_address + c->mbo_offs, buf, to_copy);
if (left == to_copy) {
ret = -EFAULT;
goto unlock;
}
c->mbo_offs += to_copy - left;
if (c->mbo_offs >= c->cfg->buffer_size ||
c->cfg->data_type == MOST_CH_CONTROL ||
c->cfg->data_type == MOST_CH_ASYNC) {
kfifo_skip(&c->fifo);
mbo->buffer_length = c->mbo_offs;
c->mbo_offs = 0;
most_submit_mbo(mbo);
}
ret = to_copy - left;
unlock:
mutex_unlock(&c->io_mutex);
return ret;
}