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: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Link: https://lore.kernel.org/r/20220210150525.30756-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
5fdc124245
commit
ab3a2189a3
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user