From d01c7636ffa051297672c55ab6088ae539d221ee Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 16 Jun 2023 12:00:36 +0200 Subject: [PATCH] ASoC: SOF: ipc3: Dump IPC message payload Dump the IPC message payload if BIT(11) of sof_debug is set and the message contains more data than just a header. The header size differs between TX and RX and in case of set_get_data, the header is always the reply header for the message regardless if it is TX or RX. The use of printk(KERN_DEBUG "..."); is on purpose to keep the dmesg output tidy. Reviewed-by: Bard Liao Signed-off-by: Peter Ujfalusi Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230616100039.378150-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index ec1ac0fb2d9f..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);