[PATCH 06/15] ASoC: SOF: ipc3: Implement the get_reply IPC ops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux