From: Peter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx> Add the implementation for the get_reply callback to copy the reply message from mailbox to msg->reply_data buffer. The implementation is equivalent to the currently used code in ipc.c Signed-off-by: Peter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx> Reviewed-by: Daniel Baluta <daniel.baluta@xxxxxxx> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx> Signed-off-by: Ranjani Sridharan <ranjani.sridharan@xxxxxxxxxxxxxxx> --- sound/soc/sof/ipc3.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index 9aa263b4af0a..2ecd3bb061f3 100644 --- a/sound/soc/sof/ipc3.c +++ b/sound/soc/sof/ipc3.c @@ -217,6 +217,60 @@ static inline void ipc3_log_header(struct device *dev, u8 *text, u32 cmd) } #endif +static int sof_ipc3_get_reply(struct snd_sof_dev *sdev) +{ + struct snd_sof_ipc_msg *msg = sdev->msg; + struct sof_ipc_reply *reply; + int ret = 0; + + /* get the generic reply */ + reply = msg->reply_data; + snd_sof_dsp_mailbox_read(sdev, sdev->host_box.offset, reply, sizeof(*reply)); + + if (reply->error < 0) + return reply->error; + + if (!reply->hdr.size) { + /* Reply should always be >= sizeof(struct sof_ipc_reply) */ + if (msg->reply_size) + dev_err(sdev->dev, + "empty reply received, expected %zu bytes\n", + msg->reply_size); + else + dev_err(sdev->dev, "empty reply received\n"); + + return -EINVAL; + } + + if (msg->reply_size > 0) { + if (reply->hdr.size == msg->reply_size) { + ret = 0; + } else if (reply->hdr.size < msg->reply_size) { + dev_dbg(sdev->dev, + "reply size (%u) is less than expected (%zu)\n", + reply->hdr.size, msg->reply_size); + + msg->reply_size = reply->hdr.size; + ret = 0; + } else { + dev_err(sdev->dev, + "reply size (%u) exceeds the buffer size (%zu)\n", + reply->hdr.size, msg->reply_size); + ret = -EINVAL; + } + + /* + * get the full message if reply->hdr.size <= msg->reply_size + * and the reply->hdr.size > sizeof(struct sof_ipc_reply) + */ + if (!ret && msg->reply_size > sizeof(*reply)) + snd_sof_dsp_mailbox_read(sdev, sdev->host_box.offset, + msg->reply_data, msg->reply_size); + } + + return ret; +} + /* wait for IPC message reply */ static int ipc3_wait_tx_done(struct snd_sof_ipc *ipc, void *reply_data) { @@ -453,4 +507,5 @@ const struct sof_ipc_ops ipc3_ops = { .tx_msg = sof_ipc3_tx_msg, .set_get_data = sof_ipc3_set_get_data, + .get_reply = sof_ipc3_get_reply, }; -- 2.25.1