Skip to content

Commit bbbde78

Browse files
committed
ASoC: SOF: ipc4-control: Keep the payload size up to date
When the bytes data is read from the firmware, the size of the payload can be different than what it was previously. For example when the topology did not contained payload data at all for the control, the data size was 0. For get operation allow maximum size of payload to be read and then update the sizes according to the completed message. Similarly, keep the size in sync when updating the data in firmware. With the change we will be able to read data from firmware for bytes controls which did not had initial payload defined in topology. Fixes: a062c88 ("ASoC: SOF: ipc4-control: Add support for bytes control get and put") Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent 49dccfd commit bbbde78

1 file changed

Lines changed: 19 additions & 4 deletions

File tree

sound/soc/sof/ipc4-control.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,13 +426,21 @@ static int sof_ipc4_set_get_bytes_data(struct snd_sof_dev *sdev,
426426
msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(data->type);
427427

428428
msg->data_ptr = data->data;
429-
msg->data_size = data->size;
429+
if (set)
430+
msg->data_size = data->size;
431+
else
432+
msg->data_size = scontrol->max_size - sizeof(*data);
430433

431434
ret = sof_ipc4_set_get_kcontrol_data(scontrol, set, lock);
432-
if (ret < 0)
435+
if (ret < 0) {
433436
dev_err(sdev->dev, "Failed to %s for %s\n",
434437
set ? "set bytes update" : "get bytes",
435438
scontrol->name);
439+
} else if (!set) {
440+
/* Update the sizes according to the received payload data */
441+
data->size = msg->data_size;
442+
scontrol->size = sizeof(*cdata) + sizeof(*data) + data->size;
443+
}
436444

437445
msg->data_ptr = NULL;
438446
msg->data_size = 0;
@@ -448,6 +456,7 @@ static int sof_ipc4_bytes_put(struct snd_sof_control *scontrol,
448456
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
449457
struct sof_abi_hdr *data = cdata->data;
450458
size_t size;
459+
int ret;
451460

452461
if (scontrol->max_size > sizeof(ucontrol->value.bytes.data)) {
453462
dev_err_ratelimited(scomp->dev,
@@ -469,9 +478,12 @@ static int sof_ipc4_bytes_put(struct snd_sof_control *scontrol,
469478
/* copy from kcontrol */
470479
memcpy(data, ucontrol->value.bytes.data, size);
471480

472-
sof_ipc4_set_get_bytes_data(sdev, scontrol, true, true);
481+
ret = sof_ipc4_set_get_bytes_data(sdev, scontrol, true, true);
482+
if (!ret)
483+
/* Update the cdata size */
484+
scontrol->size = sizeof(*cdata) + size;
473485

474-
return 0;
486+
return ret;
475487
}
476488

477489
static int sof_ipc4_bytes_get(struct snd_sof_control *scontrol,
@@ -581,6 +593,9 @@ static int sof_ipc4_bytes_ext_put(struct snd_sof_control *scontrol,
581593
return -EFAULT;
582594
}
583595

596+
/* Update the cdata size */
597+
scontrol->size = sizeof(*cdata) + header.length;
598+
584599
return sof_ipc4_set_get_bytes_data(sdev, scontrol, true, true);
585600
}
586601

0 commit comments

Comments
 (0)