コード例 #1
0
static int send_scpi_cmd(struct scpi_data_buf *scpi_buf, bool high_priority)
{
	struct mbox_chan *chan;
	struct mbox_client cl = {0};
	struct mhu_data_buf *data = scpi_buf->data;
	u32 status;

	cl.dev = the_scpi_device;
	cl.rx_callback = scpi_rx_callback;

	chan = mbox_request_channel(&cl, high_priority);
	if (IS_ERR(chan))
		return PTR_ERR(chan);

	init_completion(&scpi_buf->complete);
	if (mbox_send_message(chan, (void *)data) < 0) {
		status = SCPI_ERR_TIMEOUT;
		goto free_channel;
	}

	wait_for_completion(&scpi_buf->complete);
	status = *(u32 *)(data->rx_buf); /* read first word */

free_channel:
	mbox_free_channel(chan);

	return scpi_to_linux_errno(status);
}
コード例 #2
0
ファイル: scpi_protocol.c プロジェクト: uDude/linux-1
static int
scpi_send_message(u8 cmd, void *tx_buf, unsigned int len, void *rx_buf)
{
	int ret;
	u8 token, chan;
	struct scpi_xfer *msg;
	struct scpi_chan *scpi_chan;

	chan = atomic_inc_return(&scpi_info->next_chan) % scpi_info->num_chans;
	scpi_chan = scpi_info->channels + chan;

	msg = get_scpi_xfer(scpi_chan);
	if (!msg)
		return -ENOMEM;

	token = atomic_inc_return(&scpi_chan->token) & CMD_TOKEN_ID_MASK;

	msg->slot = BIT(SCPI_SLOT);
	msg->cmd = PACK_SCPI_CMD(cmd, token, len);
	msg->tx_buf = tx_buf;
	msg->tx_len = len;
	msg->rx_buf = rx_buf;
	init_completion(&msg->done);

	ret = mbox_send_message(scpi_chan->chan, msg);
	if (ret < 0 || !rx_buf)
		goto out;

	if (!wait_for_completion_timeout(&msg->done, MAX_RX_TIMEOUT))
		ret = -ETIMEDOUT;
	else
		/* first status word */
		ret = le32_to_cpu(msg->status);
out:
	if (ret < 0 && rx_buf) /* remove entry from the list if timed-out */
		scpi_process_cmd(scpi_chan, msg->cmd);

	put_scpi_xfer(msg, scpi_chan);
	/* SCPI error codes > 0, translate them to Linux scale*/
	return ret > 0 ? scpi_to_linux_errno(ret) : ret;
}