summaryrefslogtreecommitdiff
path: root/sound/soc/sof/ipc3.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/ipc3.c')
-rw-r--r--sound/soc/sof/ipc3.c102
1 files changed, 78 insertions, 24 deletions
diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c
index c67767742093..2c5aac31e8b0 100644
--- a/sound/soc/sof/ipc3.c
+++ b/sound/soc/sof/ipc3.c
@@ -223,6 +223,14 @@ static inline void ipc3_log_header(struct device *dev, u8 *text, u32 cmd)
}
#endif
+static void sof_ipc3_dump_payload(struct snd_sof_dev *sdev,
+ void *ipc_data, size_t size)
+{
+ printk(KERN_DEBUG "Size of payload following the header: %zu\n", size);
+ print_hex_dump_debug("Message payload: ", DUMP_PREFIX_OFFSET,
+ 16, 4, ipc_data, size, false);
+}
+
static int sof_ipc3_get_reply(struct snd_sof_dev *sdev)
{
struct snd_sof_ipc_msg *msg = sdev->msg;
@@ -374,6 +382,29 @@ static int sof_ipc3_tx_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_
ret = ipc3_tx_msg_unlocked(ipc, msg_data, msg_bytes, reply_data, reply_bytes);
+ if (sof_debug_check_flag(SOF_DBG_DUMP_IPC_MESSAGE_PAYLOAD)) {
+ size_t payload_bytes, header_bytes;
+ char *payload = NULL;
+
+ /* payload is indicated by non zero msg/reply_bytes */
+ if (msg_bytes > sizeof(struct sof_ipc_cmd_hdr)) {
+ payload = msg_data;
+
+ header_bytes = sizeof(struct sof_ipc_cmd_hdr);
+ payload_bytes = msg_bytes - header_bytes;
+ } else if (reply_bytes > sizeof(struct sof_ipc_reply)) {
+ payload = reply_data;
+
+ header_bytes = sizeof(struct sof_ipc_reply);
+ payload_bytes = reply_bytes - header_bytes;
+ }
+
+ if (payload) {
+ payload += header_bytes;
+ sof_ipc3_dump_payload(sdev, payload, payload_bytes);
+ }
+ }
+
mutex_unlock(&ipc->tx_mutex);
return ret;
@@ -472,6 +503,14 @@ static int sof_ipc3_set_get_data(struct snd_sof_dev *sdev, void *data, size_t da
offset += payload_size;
}
+ if (sof_debug_check_flag(SOF_DBG_DUMP_IPC_MESSAGE_PAYLOAD)) {
+ size_t header_bytes = sizeof(struct sof_ipc_reply);
+ char *payload = (char *)cdata;
+
+ payload += header_bytes;
+ sof_ipc3_dump_payload(sdev, payload, data_bytes - header_bytes);
+ }
+
mutex_unlock(&sdev->ipc->tx_mutex);
kfree(cdata_chunk);
@@ -954,31 +993,21 @@ static void ipc3_trace_message(struct snd_sof_dev *sdev, void *msg_buf)
}
}
-/* DSP firmware has sent host a message */
-static void sof_ipc3_rx_msg(struct snd_sof_dev *sdev)
+void sof_ipc3_do_rx_work(struct snd_sof_dev *sdev, struct sof_ipc_cmd_hdr *hdr, void *msg_buf)
{
ipc3_rx_callback rx_callback = NULL;
- struct sof_ipc_cmd_hdr hdr;
- void *msg_buf;
u32 cmd;
int err;
- /* read back header */
- err = snd_sof_ipc_msg_data(sdev, NULL, &hdr, sizeof(hdr));
- if (err < 0) {
- dev_warn(sdev->dev, "failed to read IPC header: %d\n", err);
- return;
- }
+ ipc3_log_header(sdev->dev, "ipc rx", hdr->cmd);
- if (hdr.size < sizeof(hdr) || hdr.size > SOF_IPC_MSG_MAX_SIZE) {
+ if (hdr->size < sizeof(hdr) || hdr->size > SOF_IPC_MSG_MAX_SIZE) {
dev_err(sdev->dev, "The received message size is invalid: %u\n",
- hdr.size);
+ hdr->size);
return;
}
- ipc3_log_header(sdev->dev, "ipc rx", hdr.cmd);
-
- cmd = hdr.cmd & SOF_GLB_TYPE_MASK;
+ cmd = hdr->cmd & SOF_GLB_TYPE_MASK;
/* check message type */
switch (cmd) {
@@ -1016,6 +1045,36 @@ static void sof_ipc3_rx_msg(struct snd_sof_dev *sdev)
break;
}
+ /* Call local handler for the message */
+ if (rx_callback)
+ rx_callback(sdev, msg_buf);
+
+ /* Notify registered clients */
+ sof_client_ipc_rx_dispatcher(sdev, msg_buf);
+
+ ipc3_log_header(sdev->dev, "ipc rx done", hdr->cmd);
+}
+EXPORT_SYMBOL(sof_ipc3_do_rx_work);
+
+/* DSP firmware has sent host a message */
+static void sof_ipc3_rx_msg(struct snd_sof_dev *sdev)
+{
+ struct sof_ipc_cmd_hdr hdr;
+ void *msg_buf;
+ int err;
+
+ /* read back header */
+ err = snd_sof_ipc_msg_data(sdev, NULL, &hdr, sizeof(hdr));
+ if (err < 0) {
+ dev_warn(sdev->dev, "failed to read IPC header: %d\n", err);
+ return;
+ }
+
+ if (hdr.size < sizeof(hdr)) {
+ dev_err(sdev->dev, "The received message size is invalid\n");
+ return;
+ }
+
/* read the full message */
msg_buf = kmalloc(hdr.size, GFP_KERNEL);
if (!msg_buf)
@@ -1024,18 +1083,13 @@ static void sof_ipc3_rx_msg(struct snd_sof_dev *sdev)
err = snd_sof_ipc_msg_data(sdev, NULL, msg_buf, hdr.size);
if (err < 0) {
dev_err(sdev->dev, "%s: Failed to read message: %d\n", __func__, err);
- } else {
- /* Call local handler for the message */
- if (rx_callback)
- rx_callback(sdev, msg_buf);
-
- /* Notify registered clients */
- sof_client_ipc_rx_dispatcher(sdev, msg_buf);
+ kfree(msg_buf);
+ return;
}
- kfree(msg_buf);
+ sof_ipc3_do_rx_work(sdev, &hdr, msg_buf);
- ipc3_log_header(sdev->dev, "ipc rx done", hdr.cmd);
+ kfree(msg_buf);
}
static int sof_ipc3_set_core_state(struct snd_sof_dev *sdev, int core_idx, bool on)