static ssize_t hsc_write()

in clients/hsi_char.c [471:523]


static ssize_t hsc_write(struct file *file, const char __user *buf, size_t len,
						loff_t *ppos __maybe_unused)
{
	struct hsc_channel *channel = file->private_data;
	struct hsi_msg *msg;
	ssize_t ret;

	if ((len == 0) || !IS_ALIGNED(len, sizeof(u32)))
		return -EINVAL;
	if (len > max_data_size)
		len = max_data_size;
	if (channel->ch >= channel->cl->tx_cfg.num_hw_channels)
		return -ECHRNG;
	if (test_and_set_bit(HSC_CH_WRITE, &channel->flags))
		return -EBUSY;
	msg = hsc_get_first_msg(channel, &channel->free_msgs_list);
	if (!msg) {
		clear_bit(HSC_CH_WRITE, &channel->flags);
		return -ENOSPC;
	}
	if (copy_from_user(sg_virt(msg->sgt.sgl), (void __user *)buf, len)) {
		ret = -EFAULT;
		goto out;
	}
	hsc_msg_len_set(msg, len);
	msg->complete = hsc_tx_completed;
	msg->destructor = hsc_tx_msg_destructor;
	ret = hsi_async_write(channel->cl, msg);
	if (ret < 0)
		goto out;

	ret = wait_event_interruptible(channel->tx_wait,
					!list_empty(&channel->tx_msgs_queue));
	if (ret < 0) {
		clear_bit(HSC_CH_WRITE, &channel->flags);
		hsi_flush(channel->cl);
		return -EINTR;
	}

	msg = hsc_get_first_msg(channel, &channel->tx_msgs_queue);
	if (msg) {
		if (msg->status == HSI_STATUS_ERROR)
			ret = -EIO;
		else
			ret = hsc_msg_len_get(msg);

		hsc_add_tail(channel, msg, &channel->free_msgs_list);
	}
out:
	clear_bit(HSC_CH_WRITE, &channel->flags);

	return ret;
}