Skip to content

Commit 9477684

Browse files
committed
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>
1 parent cabd476 commit 9477684

1 file changed

Lines changed: 44 additions & 41 deletions

File tree

sound/soc/sof/ipc.c

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
#include "sof-audio.h"
1919
#include "ops.h"
2020

21-
static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_type);
22-
static void ipc_stream_message(struct snd_sof_dev *sdev, u32 msg_cmd);
21+
typedef void (*ipc_rx_callback)(struct snd_sof_dev *sdev, void *msg_buf);
22+
23+
static void ipc_trace_message(struct snd_sof_dev *sdev, void *msg_buf);
24+
static void ipc_stream_message(struct snd_sof_dev *sdev, void *msg_buf);
2325

2426
/*
2527
* IPC message Tx/Rx message handling.
@@ -461,44 +463,30 @@ void snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id)
461463
}
462464
EXPORT_SYMBOL(snd_sof_ipc_reply);
463465

464-
static void ipc_comp_notification(struct snd_sof_dev *sdev,
465-
struct sof_ipc_cmd_hdr *hdr)
466+
static void ipc_comp_notification(struct snd_sof_dev *sdev, void *msg_buf)
466467
{
468+
struct sof_ipc_cmd_hdr *hdr = msg_buf;
467469
u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
468-
struct sof_ipc_ctrl_data *cdata;
469-
int ret;
470470

471471
switch (msg_type) {
472472
case SOF_IPC_COMP_GET_VALUE:
473473
case SOF_IPC_COMP_GET_DATA:
474-
cdata = kmalloc(hdr->size, GFP_KERNEL);
475-
if (!cdata)
476-
return;
477-
478-
/* read back full message */
479-
ret = snd_sof_ipc_msg_data(sdev, NULL, cdata, hdr->size);
480-
if (ret < 0) {
481-
dev_err(sdev->dev,
482-
"error: failed to read component event: %d\n", ret);
483-
goto err;
484-
}
485474
break;
486475
default:
487476
dev_err(sdev->dev, "error: unhandled component message %#x\n", msg_type);
488477
return;
489478
}
490479

491-
snd_sof_control_notify(sdev, cdata);
492-
493-
err:
494-
kfree(cdata);
480+
snd_sof_control_notify(sdev, msg_buf);
495481
}
496482

497483
/* DSP firmware has sent host a message */
498484
void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
499485
{
486+
ipc_rx_callback rx_callback = NULL;
500487
struct sof_ipc_cmd_hdr hdr;
501-
u32 cmd, type;
488+
void *msg_buf;
489+
u32 cmd;
502490
int err;
503491

504492
/* read back header */
@@ -507,10 +495,15 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
507495
dev_warn(sdev->dev, "failed to read IPC header: %d\n", err);
508496
return;
509497
}
498+
499+
if (hdr.size < sizeof(hdr)) {
500+
dev_err(sdev->dev, "The received message size is invalid\n");
501+
return;
502+
}
503+
510504
ipc_log_header(sdev->dev, "ipc rx", hdr.cmd);
511505

512506
cmd = hdr.cmd & SOF_GLB_TYPE_MASK;
513-
type = hdr.cmd & SOF_CMD_TYPE_MASK;
514507

515508
/* check message type */
516509
switch (cmd) {
@@ -535,20 +528,35 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
535528
case SOF_IPC_GLB_PM_MSG:
536529
break;
537530
case SOF_IPC_GLB_COMP_MSG:
538-
ipc_comp_notification(sdev, &hdr);
531+
rx_callback = ipc_comp_notification;
539532
break;
540533
case SOF_IPC_GLB_STREAM_MSG:
541-
/* need to pass msg id into the function */
542-
ipc_stream_message(sdev, hdr.cmd);
534+
rx_callback = ipc_stream_message;
543535
break;
544536
case SOF_IPC_GLB_TRACE_MSG:
545-
ipc_trace_message(sdev, type);
537+
rx_callback = ipc_trace_message;
546538
break;
547539
default:
548-
dev_err(sdev->dev, "error: unknown DSP message 0x%x\n", cmd);
540+
dev_err(sdev->dev, "%s: Unknown DSP message: 0x%x\n", __func__, cmd);
549541
break;
550542
}
551543

544+
if (rx_callback) {
545+
/* read the full message as we have rx handler for it */
546+
msg_buf = kmalloc(hdr.size, GFP_KERNEL);
547+
if (!msg_buf)
548+
return;
549+
550+
err = snd_sof_ipc_msg_data(sdev, NULL, msg_buf, hdr.size);
551+
if (err < 0)
552+
dev_err(sdev->dev, "%s: Failed to read message: %d\n",
553+
__func__, err);
554+
else
555+
rx_callback(sdev, msg_buf);
556+
557+
kfree(msg_buf);
558+
}
559+
552560
ipc_log_header(sdev->dev, "ipc rx done", hdr.cmd);
553561
}
554562
EXPORT_SYMBOL(snd_sof_ipc_msgs_rx);
@@ -557,19 +565,14 @@ EXPORT_SYMBOL(snd_sof_ipc_msgs_rx);
557565
* IPC trace mechanism.
558566
*/
559567

560-
static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_type)
568+
static void ipc_trace_message(struct snd_sof_dev *sdev, void *msg_buf)
561569
{
562-
struct sof_ipc_dma_trace_posn posn;
563-
int ret;
570+
struct sof_ipc_cmd_hdr *hdr = msg_buf;
571+
u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
564572

565573
switch (msg_type) {
566574
case SOF_IPC_TRACE_DMA_POSITION:
567-
/* read back full message */
568-
ret = snd_sof_ipc_msg_data(sdev, NULL, &posn, sizeof(posn));
569-
if (ret < 0)
570-
dev_warn(sdev->dev, "failed to read trace position: %d\n", ret);
571-
else
572-
snd_sof_trace_update_pos(sdev, &posn);
575+
snd_sof_trace_update_pos(sdev, msg_buf);
573576
break;
574577
default:
575578
dev_err(sdev->dev, "error: unhandled trace message %#x\n", msg_type);
@@ -651,11 +654,11 @@ static void ipc_xrun(struct snd_sof_dev *sdev, u32 msg_id)
651654
}
652655

653656
/* stream notifications from DSP FW */
654-
static void ipc_stream_message(struct snd_sof_dev *sdev, u32 msg_cmd)
657+
static void ipc_stream_message(struct snd_sof_dev *sdev, void *msg_buf)
655658
{
656-
/* get msg cmd type and msd id */
657-
u32 msg_type = msg_cmd & SOF_CMD_TYPE_MASK;
658-
u32 msg_id = SOF_IPC_MESSAGE_ID(msg_cmd);
659+
struct sof_ipc_cmd_hdr *hdr = msg_buf;
660+
u32 msg_type = hdr->cmd & SOF_CMD_TYPE_MASK;
661+
u32 msg_id = SOF_IPC_MESSAGE_ID(hdr->cmd);
659662

660663
switch (msg_type) {
661664
case SOF_IPC_STREAM_POSITION:

0 commit comments

Comments
 (0)