static ssize_t sbefifo_user_write()

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;
}