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 @@
#include "sof-audio.h"
#include "ops.h"
static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_type);
static void ipc_stream_message(struct snd_sof_dev *sdev, u32 msg_cmd);
typedef void (*ipc_rx_callback)(struct snd_sof_dev *sdev, void *msg_buf);
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.
......@@ -477,44 +479,30 @@ void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id)
}
EXPORT_SYMBOL(snd_sof_ipc_reply);
static void ipc_comp_notification(struct snd_sof_dev *sdev,
struct sof_ipc_cmd_hdr *hdr)
static void ipc_comp_notification(struct snd_sof_dev *sdev, void *msg_buf)
{
struct sof_ipc_cmd_hdr *hdr = msg_buf;
u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
struct sof_ipc_ctrl_data *cdata;
int ret;
switch (msg_type) {
case SOF_IPC_COMP_GET_VALUE:
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;
default:
dev_err(sdev->dev, "error: unhandled component message %#x\n", msg_type);
return;
}
snd_sof_control_notify(sdev, cdata);
err:
kfree(cdata);
snd_sof_control_notify(sdev, msg_buf);
}
/* DSP firmware has sent host a message */
void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
{
ipc_rx_callback rx_callback = NULL;
struct sof_ipc_cmd_hdr hdr;
u32 cmd, type;
void *msg_buf;
u32 cmd;
int err;
/* read back header */
......@@ -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);
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);
cmd = hdr.cmd & SOF_GLB_TYPE_MASK;
type = hdr.cmd & SOF_CMD_TYPE_MASK;
/* check message type */
switch (cmd) {
......@@ -551,20 +544,35 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
case SOF_IPC_GLB_PM_MSG:
break;
case SOF_IPC_GLB_COMP_MSG:
ipc_comp_notification(sdev, &hdr);
rx_callback = ipc_comp_notification;
break;
case SOF_IPC_GLB_STREAM_MSG:
/* need to pass msg id into the function */
ipc_stream_message(sdev, hdr.cmd);
rx_callback = ipc_stream_message;
break;
case SOF_IPC_GLB_TRACE_MSG:
ipc_trace_message(sdev, type);
rx_callback = ipc_trace_message;
break;
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;
}
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);
}
EXPORT_SYMBOL(snd_sof_ipc_msgs_rx);
......@@ -573,19 +581,14 @@ EXPORT_SYMBOL(snd_sof_ipc_msgs_rx);
* 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;
int ret;
struct sof_ipc_cmd_hdr *hdr = msg_buf;
u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
switch (msg_type) {
case SOF_IPC_TRACE_DMA_POSITION:
/* read back full message */
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);
snd_sof_trace_update_pos(sdev, msg_buf);
break;
default:
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)
}
/* 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 */
u32 msg_type = msg_cmd & SOF_CMD_TYPE_MASK;
u32 msg_id = SOF_IPC_MESSAGE_ID(msg_cmd);
struct sof_ipc_cmd_hdr *hdr = msg_buf;
u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
u32 msg_id = SOF_IPC_MESSAGE_ID(hdr->cmd);
switch (msg_type) {
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