eq: make fir to receive large blobs in parts

Use ctrl data message id to receive and send large binary
blobs over ipc. When first message arrives, reserve memory
for the whole blob.

Signed-off-by: Jaska Uimonen <jaska.uimonen@intel.com>
This commit is contained in:
Jaska Uimonen 2019-02-06 09:43:58 +02:00 committed by Liam Girdwood
parent 0c232c86e4
commit c53d745e0a
1 changed files with 55 additions and 27 deletions

View File

@ -334,7 +334,7 @@ static int eq_fir_setup(struct comp_data *cd, int nch)
return 0;
/* Allocate all FIR channels data in a big chunk and clear it */
cd->fir_delay = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, size_sum);
cd->fir_delay = rballoc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, size_sum);
if (!cd->fir_delay) {
trace_eq_error("eq_fir_setup() error: alloc failed, size = %u",
size_sum);
@ -421,7 +421,7 @@ static struct comp_dev *eq_fir_new(struct sof_ipc_comp *comp)
* the EQ is configured later in run-time the size is zero.
*/
if (bs) {
cd->config = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, bs);
cd->config = rballoc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, bs);
if (!cd->config) {
rfree(dev);
rfree(cd);
@ -491,7 +491,8 @@ static int fir_cmd_get_data(struct comp_dev *dev,
struct sof_ipc_ctrl_data *cdata, int max_size)
{
struct comp_data *cd = comp_get_drvdata(dev);
unsigned char *dst, *src;
size_t offset;
size_t bs;
int ret = 0;
@ -499,17 +500,29 @@ static int fir_cmd_get_data(struct comp_dev *dev,
case SOF_CTRL_CMD_BINARY:
trace_eq("fir_cmd_get_data(), SOF_CTRL_CMD_BINARY");
max_size -= sizeof(struct sof_ipc_ctrl_data) +
sizeof(struct sof_abi_hdr);
/* Copy back to user space */
if (cd->config) {
src = (unsigned char *)cd->config;
dst = (unsigned char *)cdata->data->data;
bs = cd->config->size;
if (bs > SOF_EQ_FIR_MAX_SIZE || bs == 0 ||
bs > max_size)
return -EINVAL;
ret = memcpy_s(cdata->data->data,
((struct sof_abi_hdr *)
(cdata->data))->size,
cd->config, bs);
cdata->elems_remaining = 0;
offset = 0;
if (bs > max_size) {
bs = (cdata->msg_index + 1) * max_size > bs ?
bs - cdata->msg_index * max_size :
max_size;
offset = cdata->msg_index * max_size;
cdata->elems_remaining = cd->config->size -
offset;
}
cdata->num_elems = bs;
trace_eq("fir_cmd_get_data(), blob size %zu "
"msg index %u max size %u offset %zu", bs,
cdata->msg_index, max_size, offset);
memcpy(dst, src + offset, bs);
cdata->data->abi = SOF_ABI_VERSION;
cdata->data->size = bs;
} else {
@ -531,8 +544,8 @@ static int fir_cmd_set_data(struct comp_dev *dev,
{
struct comp_data *cd = comp_get_drvdata(dev);
struct sof_ipc_ctrl_value_comp *compv;
struct sof_eq_fir_config *cfg;
size_t bs;
unsigned char *dst, *src;
uint32_t offset;
int i;
int ret = 0;
@ -580,28 +593,43 @@ static int fir_cmd_set_data(struct comp_dev *dev,
return -EBUSY;
}
/* Copy new config, find size from header */
trace_eq("fir_cmd_set_data(): blob size: %u msg_index %u",
cdata->num_elems + cdata->elems_remaining,
cdata->msg_index);
if (cdata->num_elems + cdata->elems_remaining >
SOF_EQ_FIR_MAX_SIZE)
return -EINVAL;
if (cdata->msg_index == 0) {
/* Check and free old config */
eq_fir_free_parameters(&cd->config);
/* Copy new config, find size from header */
cfg = (struct sof_eq_fir_config *)cdata->data->data;
bs = cfg->size;
trace_eq("fir_cmd_set_data(): blob size: %u", bs);
if (bs > SOF_EQ_FIR_MAX_SIZE || bs == 0)
return -EINVAL;
/* Allocate buffer for copy of the blob. */
cd->config = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, bs);
cd->config = rballoc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM,
cdata->num_elems +
cdata->elems_remaining);
if (!cd->config) {
trace_eq_error("fir_cmd_set_data() error: "
"buffer allocation failed");
return -EINVAL;
}
offset = 0;
} else {
offset = cd->config->size - cdata->elems_remaining -
cdata->num_elems;
}
dst = (unsigned char *)cd->config;
src = (unsigned char *)cdata->data->data;
/* Just copy the configuration. The EQ will be initialized in
* prepare().
*/
ret = memcpy_s(cd->config, bs, cfg, bs);
memcpy(dst + offset, src, cdata->num_elems);
/* we can check data when elems_remaining == 0 */
break;
default:
trace_eq_error("fir_cmd_set_data() error: invalid cdata->cmd");