in fsi-sbefifo.c [853:914]
static ssize_t sbefifo_user_write(struct file *file, const char __user *buf,
size_t len, loff_t *offset)
{
struct sbefifo_user *user = file->private_data;
struct sbefifo *sbefifo;
int rc = len;
if (!user)
return -EINVAL;
sbefifo = user->sbefifo;
if (len > SBEFIFO_MAX_USER_CMD_LEN)
return -EINVAL;
if (len & 3)
return -EINVAL;
mutex_lock(&user->file_lock);
/* Can we use the pre-allocate buffer ? If not, allocate */
if (len <= PAGE_SIZE)
user->pending_cmd = user->cmd_page;
else
user->pending_cmd = vmalloc(len);
if (!user->pending_cmd) {
rc = -ENOMEM;
goto bail;
}
/* Copy the command into the staging buffer */
if (copy_from_user(user->pending_cmd, buf, len)) {
rc = -EFAULT;
goto bail;
}
/* Check for the magic reset command */
if (len == 4 && be32_to_cpu(*(__be32 *)user->pending_cmd) ==
SBEFIFO_RESET_MAGIC) {
/* Clear out any pending command */
user->pending_len = 0;
/* Trigger reset request */
rc = mutex_lock_interruptible(&sbefifo->lock);
if (rc)
goto bail;
rc = sbefifo_request_reset(user->sbefifo);
mutex_unlock(&sbefifo->lock);
if (rc == 0)
rc = 4;
goto bail;
}
/* Update the staging buffer size */
user->pending_len = len;
bail:
if (!user->pending_len)
sbefifo_release_command(user);
mutex_unlock(&user->file_lock);
/* And that's it, we'll issue the command on a read */
return rc;
}