static int scpi_execute_cmd(struct scpi_data_buf *scpi_buf) { struct mhu_data_buf *data; bool high_priority; if (!scpi_buf || !scpi_buf->data) return -EINVAL; data = scpi_buf->data; high_priority = high_priority_chan_supported(data->cmd); data->cmd = PACK_SCPI_CMD(data->cmd, scpi_buf->client_id, data->tx_size); data->cl_data = scpi_buf; return send_scpi_cmd(scpi_buf, high_priority); }
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; }