ASoC: SOF: ipc: Use msg->reply_data directly in snd_sof_ipc_get_reply()
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Wed, 30 Mar 2022 20:19:23 +0000 (13:19 -0700)
committerMark Brown <broonie@kernel.org>
Mon, 4 Apr 2022 07:39:08 +0000 (08:39 +0100)
Instead of using a local reply to first read out the header from the
mailbox then memcpy it or read it again to msg->reply_data, read it
directly to it's final place from the start.

If we received an error we do not need to do a memcpy anymore.
If the reply is reporting a success then we don not need to read the reply
again from the mailbox if the reply_size equals to the already read header
size.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20220330201926.1330402-9-ranjani.sridharan@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/ipc.c

index c722ca0b00a645eb12237601e6f2119e30d3294a..46c40dfd9f2bb51853753e944f0736a6e56da37b 100644 (file)
@@ -393,7 +393,7 @@ EXPORT_SYMBOL(sof_ipc_tx_message_no_pm);
 void snd_sof_ipc_get_reply(struct snd_sof_dev *sdev)
 {
        struct snd_sof_ipc_msg *msg = sdev->msg;
-       struct sof_ipc_reply reply;
+       struct sof_ipc_reply *reply;
        int ret = 0;
 
        /*
@@ -407,13 +407,12 @@ void snd_sof_ipc_get_reply(struct snd_sof_dev *sdev)
        }
 
        /* get the generic reply */
-       snd_sof_dsp_mailbox_read(sdev, sdev->host_box.offset, &reply,
-                                sizeof(reply));
+       reply = msg->reply_data;
+       snd_sof_dsp_mailbox_read(sdev, sdev->host_box.offset, reply, sizeof(*reply));
 
-       if (reply.error < 0) {
-               memcpy(msg->reply_data, &reply, sizeof(reply));
-               ret = reply.error;
-       } else if (!reply.hdr.size) {
+       if (reply->error < 0) {
+               ret = reply->error;
+       } else if (!reply->hdr.size) {
                /* Reply should always be >= sizeof(struct sof_ipc_reply) */
                if (msg->reply_size)
                        dev_err(sdev->dev,
@@ -424,24 +423,27 @@ void snd_sof_ipc_get_reply(struct snd_sof_dev *sdev)
 
                ret = -EINVAL;
        } else if (msg->reply_size > 0) {
-               if (reply.hdr.size == msg->reply_size) {
+               if (reply->hdr.size == msg->reply_size) {
                        ret = 0;
-               } else if (reply.hdr.size < msg->reply_size) {
+               } 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);
+                               reply->hdr.size, msg->reply_size);
 
-                       msg->reply_size = reply.hdr.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);
+                               reply->hdr.size, msg->reply_size);
                        ret = -EINVAL;
                }
 
-               /* get the full message if reply.hdr.size <= msg->reply_size */
-               if (!ret)
+               /*
+                * 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);
        }