Commit ab3a2189 authored by Peter Ujfalusi's avatar Peter Ujfalusi Committed by Mark Brown

ASoC: SOF: ipc: Read and pass the whole message to handlers for IPC events

Change the parameter list for the firmware initiated message (IPC event)
handler functions to:
handler(struct snd_sof_dev *sdev, void *full_msg);

Allocate memory and read the whole message in snd_sof_ipc_msgs_rx() then
pass the pointer to the function handling the message.
Do this only if we actually have a function which is tasked to process the
given type.
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20220210150525.30756-4-peter.ujfalusi@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 5fdc1242
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
#include "sof-audio.h" #include "sof-audio.h"
#include "ops.h" #include "ops.h"
static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_type); typedef void (*ipc_rx_callback)(struct snd_sof_dev *sdev, void *msg_buf);
static void ipc_stream_message(struct snd_sof_dev *sdev, u32 msg_cmd);
static void ipc_trace_message(struct snd_sof_dev *sdev, void *msg_buf);
static void ipc_stream_message(struct snd_sof_dev *sdev, void *msg_buf);
/* /*
* IPC message Tx/Rx message handling. * IPC message Tx/Rx message handling.
...@@ -477,44 +479,30 @@ void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id) ...@@ -477,44 +479,30 @@ void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id)
} }
EXPORT_SYMBOL(snd_sof_ipc_reply); EXPORT_SYMBOL(snd_sof_ipc_reply);
static void ipc_comp_notification(struct snd_sof_dev *sdev, static void ipc_comp_notification(struct snd_sof_dev *sdev, void *msg_buf)
struct sof_ipc_cmd_hdr *hdr)
{ {
struct sof_ipc_cmd_hdr *hdr = msg_buf;
u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK; u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
struct sof_ipc_ctrl_data *cdata;
int ret;
switch (msg_type) { switch (msg_type) {
case SOF_IPC_COMP_GET_VALUE: case SOF_IPC_COMP_GET_VALUE:
case SOF_IPC_COMP_GET_DATA: case SOF_IPC_COMP_GET_DATA:
cdata = kmalloc(hdr->size, GFP_KERNEL);
if (!cdata)
return;
/* read back full message */
ret = snd_sof_ipc_msg_data(sdev, NULL, cdata, hdr->size);
if (ret < 0) {
dev_err(sdev->dev,
"error: failed to read component event: %d\n", ret);
goto err;
}
break; break;
default: default:
dev_err(sdev->dev, "error: unhandled component message %#x\n", msg_type); dev_err(sdev->dev, "error: unhandled component message %#x\n", msg_type);
return; return;
} }
snd_sof_control_notify(sdev, cdata); snd_sof_control_notify(sdev, msg_buf);
err:
kfree(cdata);
} }
/* DSP firmware has sent host a message */ /* DSP firmware has sent host a message */
void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev) void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
{ {
ipc_rx_callback rx_callback = NULL;
struct sof_ipc_cmd_hdr hdr; struct sof_ipc_cmd_hdr hdr;
u32 cmd, type; void *msg_buf;
u32 cmd;
int err; int err;
/* read back header */ /* read back header */
...@@ -523,10 +511,15 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev) ...@@ -523,10 +511,15 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
dev_warn(sdev->dev, "failed to read IPC header: %d\n", err); dev_warn(sdev->dev, "failed to read IPC header: %d\n", err);
return; return;
} }
if (hdr.size < sizeof(hdr)) {
dev_err(sdev->dev, "The received message size is invalid\n");
return;
}
ipc_log_header(sdev->dev, "ipc rx", hdr.cmd); ipc_log_header(sdev->dev, "ipc rx", hdr.cmd);
cmd = hdr.cmd & SOF_GLB_TYPE_MASK; cmd = hdr.cmd & SOF_GLB_TYPE_MASK;
type = hdr.cmd & SOF_CMD_TYPE_MASK;
/* check message type */ /* check message type */
switch (cmd) { switch (cmd) {
...@@ -551,20 +544,35 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev) ...@@ -551,20 +544,35 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
case SOF_IPC_GLB_PM_MSG: case SOF_IPC_GLB_PM_MSG:
break; break;
case SOF_IPC_GLB_COMP_MSG: case SOF_IPC_GLB_COMP_MSG:
ipc_comp_notification(sdev, &hdr); rx_callback = ipc_comp_notification;
break; break;
case SOF_IPC_GLB_STREAM_MSG: case SOF_IPC_GLB_STREAM_MSG:
/* need to pass msg id into the function */ rx_callback = ipc_stream_message;
ipc_stream_message(sdev, hdr.cmd);
break; break;
case SOF_IPC_GLB_TRACE_MSG: case SOF_IPC_GLB_TRACE_MSG:
ipc_trace_message(sdev, type); rx_callback = ipc_trace_message;
break; break;
default: default:
dev_err(sdev->dev, "error: unknown DSP message 0x%x\n", cmd); dev_err(sdev->dev, "%s: Unknown DSP message: 0x%x\n", __func__, cmd);
break; break;
} }
if (rx_callback) {
/* read the full message as we have rx handler for it */
msg_buf = kmalloc(hdr.size, GFP_KERNEL);
if (!msg_buf)
return;
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
rx_callback(sdev, msg_buf);
kfree(msg_buf);
}
ipc_log_header(sdev->dev, "ipc rx done", hdr.cmd); ipc_log_header(sdev->dev, "ipc rx done", hdr.cmd);
} }
EXPORT_SYMBOL(snd_sof_ipc_msgs_rx); EXPORT_SYMBOL(snd_sof_ipc_msgs_rx);
...@@ -573,19 +581,14 @@ EXPORT_SYMBOL(snd_sof_ipc_msgs_rx); ...@@ -573,19 +581,14 @@ EXPORT_SYMBOL(snd_sof_ipc_msgs_rx);
* IPC trace mechanism. * IPC trace mechanism.
*/ */
static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_type) static void ipc_trace_message(struct snd_sof_dev *sdev, void *msg_buf)
{ {
struct sof_ipc_dma_trace_posn posn; struct sof_ipc_cmd_hdr *hdr = msg_buf;
int ret; u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
switch (msg_type) { switch (msg_type) {
case SOF_IPC_TRACE_DMA_POSITION: case SOF_IPC_TRACE_DMA_POSITION:
/* read back full message */ snd_sof_trace_update_pos(sdev, msg_buf);
ret = snd_sof_ipc_msg_data(sdev, NULL, &posn, sizeof(posn));
if (ret < 0)
dev_warn(sdev->dev, "failed to read trace position: %d\n", ret);
else
snd_sof_trace_update_pos(sdev, &posn);
break; break;
default: default:
dev_err(sdev->dev, "error: unhandled trace message %#x\n", msg_type); dev_err(sdev->dev, "error: unhandled trace message %#x\n", msg_type);
...@@ -667,11 +670,11 @@ static void ipc_xrun(struct snd_sof_dev *sdev, u32 msg_id) ...@@ -667,11 +670,11 @@ static void ipc_xrun(struct snd_sof_dev *sdev, u32 msg_id)
} }
/* stream notifications from DSP FW */ /* stream notifications from DSP FW */
static void ipc_stream_message(struct snd_sof_dev *sdev, u32 msg_cmd) static void ipc_stream_message(struct snd_sof_dev *sdev, void *msg_buf)
{ {
/* get msg cmd type and msd id */ struct sof_ipc_cmd_hdr *hdr = msg_buf;
u32 msg_type = msg_cmd & SOF_CMD_TYPE_MASK; u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
u32 msg_id = SOF_IPC_MESSAGE_ID(msg_cmd); u32 msg_id = SOF_IPC_MESSAGE_ID(hdr->cmd);
switch (msg_type) { switch (msg_type) {
case SOF_IPC_STREAM_POSITION: case SOF_IPC_STREAM_POSITION:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment