From 171f648aeb526c71166eb3591f0d206ae465f543 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 5 May 2025 14:34:15 +0200 Subject: [PATCH 1/2] audio: (cosmetic) simplify multiple return statements Avoid using "ret" variables where the value can be returned directly. Signed-off-by: Guennadi Liakhovetski --- src/audio/crossover/crossover.c | 9 +++------ src/audio/eq_iir/eq_iir_ipc4.c | 5 ++--- src/audio/module_adapter/module/generic.c | 6 +++--- src/audio/module_adapter/module_adapter_ipc3.c | 6 ++---- src/audio/multiband_drc/multiband_drc_ipc4.c | 5 ++--- 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/audio/crossover/crossover.c b/src/audio/crossover/crossover.c index e98379389633..2afc3aadb0ec 100644 --- a/src/audio/crossover/crossover.c +++ b/src/audio/crossover/crossover.c @@ -531,7 +531,6 @@ static int crossover_prepare(struct processing_module *mod, struct comp_dev *dev = mod->dev; struct comp_buffer *source, *sink; int channels; - int ret = 0; comp_info(dev, "crossover_prepare()"); @@ -550,11 +549,8 @@ static int crossover_prepare(struct processing_module *mod, if (cd->source_format != audio_stream_get_frm_fmt(&sink->stream)) { comp_err(dev, "crossover_prepare(): Source fmt %d and sink fmt %d are different.", cd->source_format, audio_stream_get_frm_fmt(&sink->stream)); - ret = -EINVAL; + return -EINVAL; } - - if (ret < 0) - return ret; } comp_info(dev, "crossover_prepare(), source_format=%d, sink_formats=%d, nch=%d", @@ -570,7 +566,8 @@ static int crossover_prepare(struct processing_module *mod, } if (cd->config) { - ret = crossover_setup(mod, channels); + int ret = crossover_setup(mod, channels); + if (ret < 0) { comp_err(dev, "crossover_prepare(), setup failed"); return ret; diff --git a/src/audio/eq_iir/eq_iir_ipc4.c b/src/audio/eq_iir/eq_iir_ipc4.c index 94e984e8a4ac..324102be98e5 100644 --- a/src/audio/eq_iir/eq_iir_ipc4.c +++ b/src/audio/eq_iir/eq_iir_ipc4.c @@ -105,7 +105,7 @@ static int eq_iir_params(struct processing_module *mod) struct comp_dev *dev = mod->dev; struct comp_buffer *sinkb; enum sof_ipc_frame valid_fmt, frame_fmt; - int i, ret; + int i; comp_dbg(dev, "eq_iir_params()"); comp_params = *params; @@ -125,8 +125,7 @@ static int eq_iir_params(struct processing_module *mod) component_set_nearest_period_frames(dev, comp_params.rate); sinkb = comp_dev_get_first_data_consumer(dev); - ret = buffer_set_params(sinkb, &comp_params, true); - return ret; + return buffer_set_params(sinkb, &comp_params, true); } void eq_iir_set_passthrough_func(struct comp_data *cd, diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index 5f6dc96fe236..e15f823ccf2b 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -177,7 +177,6 @@ int module_prepare(struct processing_module *mod, struct sof_source **sources, int num_of_sources, struct sof_sink **sinks, int num_of_sinks) { - int ret = 0; struct module_data *md = &mod->priv; struct comp_dev *dev = mod->dev; const struct module_interface *const ops = dev->drv->adapter_ops; @@ -191,7 +190,8 @@ int module_prepare(struct processing_module *mod, return -EPERM; #endif if (ops->prepare) { - ret = ops->prepare(mod, sources, num_of_sources, sinks, num_of_sinks); + int ret = ops->prepare(mod, sources, num_of_sources, sinks, num_of_sinks); + if (ret) { comp_err(dev, "module_prepare() error %d: module specific prepare failed, comp_id %d", ret, dev_comp_id(dev)); @@ -213,7 +213,7 @@ int module_prepare(struct processing_module *mod, #endif comp_dbg(dev, "module_prepare() done"); - return ret; + return 0; } int module_process_legacy(struct processing_module *mod, diff --git a/src/audio/module_adapter/module_adapter_ipc3.c b/src/audio/module_adapter/module_adapter_ipc3.c index b54b0f41388e..3f64bd99971f 100644 --- a/src/audio/module_adapter/module_adapter_ipc3.c +++ b/src/audio/module_adapter/module_adapter_ipc3.c @@ -321,7 +321,6 @@ int module_adapter_sink_src_prepare(struct comp_dev *dev) struct processing_module *mod = comp_mod(dev); struct comp_buffer *sink_buffer; struct comp_buffer *source_buffer; - int ret; int i; /* acquire all sink and source buffers, get handlers to sink/source API */ @@ -340,7 +339,6 @@ int module_adapter_sink_src_prepare(struct comp_dev *dev) mod->num_of_sources = i; /* Prepare module */ - ret = module_prepare(mod, mod->sources, mod->num_of_sources, mod->sinks, mod->num_of_sinks); - - return ret; + return module_prepare(mod, mod->sources, mod->num_of_sources, mod->sinks, + mod->num_of_sinks); } diff --git a/src/audio/multiband_drc/multiband_drc_ipc4.c b/src/audio/multiband_drc/multiband_drc_ipc4.c index 1cb6ab7aea3c..1c6029ecf2a0 100644 --- a/src/audio/multiband_drc/multiband_drc_ipc4.c +++ b/src/audio/multiband_drc/multiband_drc_ipc4.c @@ -80,7 +80,7 @@ int multiband_drc_params(struct processing_module *mod) struct comp_dev *dev = mod->dev; struct comp_buffer *sinkb; enum sof_ipc_frame valid_fmt, frame_fmt; - int i, ret; + int i; comp_dbg(dev, "multiband_drc_params()"); @@ -101,8 +101,7 @@ int multiband_drc_params(struct processing_module *mod) component_set_nearest_period_frames(dev, comp_params.rate); sinkb = comp_dev_get_first_data_consumer(dev); - ret = buffer_set_params(sinkb, &comp_params, true); - return ret; + return buffer_set_params(sinkb, &comp_params, true); } From 7d23caaff6f8f32734525e9a6b8d5873f5b2e955 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 5 May 2025 14:38:15 +0200 Subject: [PATCH 2/2] audio: don't rely on correct IPC order If the host sends IPCs to the DSP in wrong order, .prepare() can be called without correctly initialised buffers. Add checks everywhere where this can cause NULL dereference. Signed-off-by: Guennadi Liakhovetski --- src/audio/aria/aria.c | 8 ++++++-- src/audio/asrc/asrc.c | 9 ++++++++- src/audio/crossover/crossover.c | 7 ++++++- src/audio/crossover/crossover_ipc4.c | 1 + src/audio/dcblock/dcblock.c | 8 ++++++-- src/audio/dcblock/dcblock_ipc4.c | 2 ++ src/audio/drc/drc.c | 14 ++++++++++---- src/audio/eq_fir/eq_fir.c | 11 ++++++++--- src/audio/eq_fir/eq_fir_ipc4.c | 2 ++ src/audio/eq_iir/eq_iir.c | 11 ++++++++--- src/audio/eq_iir/eq_iir_ipc3.c | 2 ++ src/audio/eq_iir/eq_iir_ipc4.c | 2 ++ src/audio/google/google_ctc_audio_processing.c | 5 +++++ src/audio/igo_nr/igo_nr.c | 5 +++++ src/audio/mfcc/mfcc.c | 4 ++++ src/audio/mixer/mixer.c | 5 +++++ src/audio/module_adapter/module/waves/waves.c | 5 +++++ src/audio/multiband_drc/multiband_drc.c | 4 ++++ src/audio/multiband_drc/multiband_drc_ipc4.c | 4 ++++ src/audio/rtnr/rtnr.c | 11 +++++++++-- src/audio/selector/selector.c | 4 ++++ src/audio/smart_amp/smart_amp.c | 4 ++++ src/audio/tdfb/tdfb.c | 11 ++++++++--- src/audio/tdfb/tdfb_ipc4.c | 2 ++ src/audio/tone.c | 9 ++++++++- src/audio/volume/volume.c | 8 ++++++-- src/audio/volume/volume_ipc4.c | 5 ++++- src/ipc/ipc-helper.c | 8 ++++++++ src/samples/audio/smart_amp_test_ipc3.c | 4 ++++ 29 files changed, 150 insertions(+), 25 deletions(-) diff --git a/src/audio/aria/aria.c b/src/audio/aria/aria.c index b9f321a5c807..32c13edc8a5a 100644 --- a/src/audio/aria/aria.c +++ b/src/audio/aria/aria.c @@ -190,9 +190,13 @@ static int aria_prepare(struct processing_module *mod, comp_info(dev, "aria_prepare()"); source = comp_dev_get_first_data_producer(dev); - aria_set_stream_params(source, mod); - sink = comp_dev_get_first_data_consumer(dev); + if (!source || !sink) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } + + aria_set_stream_params(source, mod); aria_set_stream_params(sink, mod); if (audio_stream_get_valid_fmt(&source->stream) != SOF_IPC_FRAME_S24_4LE || diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index df4f8d39f3cb..e8106d5112c9 100644 --- a/src/audio/asrc/asrc.c +++ b/src/audio/asrc/asrc.c @@ -399,6 +399,10 @@ static int asrc_params(struct processing_module *mod) sourceb = comp_dev_get_first_data_producer(dev); sinkb = comp_dev_get_first_data_consumer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } /* update the source/sink buffer formats. Sink rate will be modified below */ asrc_update_buffer_format(sourceb, cd); @@ -549,7 +553,10 @@ static int asrc_prepare(struct processing_module *mod, if (ret < 0) return ret; - /* SRC component will only ever have 1 source and 1 sink buffer */ + /* + * SRC component will only ever have 1 source and 1 sink buffer, + * asrc_params() has checked their validity already + */ sourceb = comp_dev_get_first_data_producer(dev); sinkb = comp_dev_get_first_data_consumer(dev); diff --git a/src/audio/crossover/crossover.c b/src/audio/crossover/crossover.c index 2afc3aadb0ec..c6b34acd1b45 100644 --- a/src/audio/crossover/crossover.c +++ b/src/audio/crossover/crossover.c @@ -534,11 +534,16 @@ static int crossover_prepare(struct processing_module *mod, comp_info(dev, "crossover_prepare()"); + source = comp_dev_get_first_data_producer(dev); + if (!source) { + comp_err(dev, "no source buffer"); + return -ENOTCONN; + } + crossover_params(mod); /* Crossover has a variable number of sinks */ mod->max_sinks = SOF_CROSSOVER_MAX_STREAMS; - source = comp_dev_get_first_data_producer(dev); /* Get source data format */ cd->source_format = audio_stream_get_frm_fmt(&source->stream); diff --git a/src/audio/crossover/crossover_ipc4.c b/src/audio/crossover/crossover_ipc4.c index 9fbe7730e53e..981d34bafb7f 100644 --- a/src/audio/crossover/crossover_ipc4.c +++ b/src/audio/crossover/crossover_ipc4.c @@ -118,6 +118,7 @@ void crossover_params(struct processing_module *mod) ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); component_set_nearest_period_frames(dev, params->rate); + /* First producer verified by the caller */ sourceb = comp_dev_get_first_data_producer(dev); ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); diff --git a/src/audio/dcblock/dcblock.c b/src/audio/dcblock/dcblock.c index b32a25c7bb8a..e7d1a0b90420 100644 --- a/src/audio/dcblock/dcblock.c +++ b/src/audio/dcblock/dcblock.c @@ -195,11 +195,15 @@ static int dcblock_prepare(struct processing_module *mod, comp_info(dev, "dcblock_prepare()"); - dcblock_params(mod); - /* DC Filter component will only ever have one source and sink buffer */ sourceb = comp_dev_get_first_data_producer(dev); sinkb = comp_dev_get_first_data_consumer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } + + dcblock_params(mod); /* get source data format */ cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream); diff --git a/src/audio/dcblock/dcblock_ipc4.c b/src/audio/dcblock/dcblock_ipc4.c index 534510841b85..d8030126a270 100644 --- a/src/audio/dcblock/dcblock_ipc4.c +++ b/src/audio/dcblock/dcblock_ipc4.c @@ -61,6 +61,8 @@ void dcblock_params(struct processing_module *mod) ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); component_set_nearest_period_frames(dev, params->rate); + /* The caller has verified, that sink and source buffers are connected */ + sinkb = comp_dev_get_first_data_consumer(dev); ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); diff --git a/src/audio/drc/drc.c b/src/audio/drc/drc.c index bd22c557478f..0f06293fc243 100644 --- a/src/audio/drc/drc.c +++ b/src/audio/drc/drc.c @@ -326,6 +326,8 @@ static void drc_params(struct processing_module *mod) ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); component_set_nearest_period_frames(dev, params->rate); + /* The caller has verified, that sink and source buffers are connected */ + sinkb = comp_dev_get_first_data_consumer(dev); ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); @@ -347,13 +349,17 @@ static int drc_prepare(struct processing_module *mod, comp_info(dev, "drc_prepare()"); -#if CONFIG_IPC_MAJOR_4 - drc_params(mod); -#endif - /* DRC component will only ever have 1 source and 1 sink buffer */ sourceb = comp_dev_get_first_data_producer(dev); sinkb = comp_dev_get_first_data_consumer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } + +#if CONFIG_IPC_MAJOR_4 + drc_params(mod); +#endif /* get source data format */ cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream); diff --git a/src/audio/eq_fir/eq_fir.c b/src/audio/eq_fir/eq_fir.c index f9a4b4bd196e..344e9e25b5af 100644 --- a/src/audio/eq_fir/eq_fir.c +++ b/src/audio/eq_fir/eq_fir.c @@ -416,15 +416,20 @@ static int eq_fir_prepare(struct processing_module *mod, comp_dbg(dev, "eq_fir_prepare()"); + /* EQ component will only ever have 1 source and 1 sink buffer. */ + sourceb = comp_dev_get_first_data_producer(dev); + sinkb = comp_dev_get_first_data_consumer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } + ret = eq_fir_params(mod); if (ret < 0) { comp_set_state(dev, COMP_TRIGGER_RESET); return ret; } - /* EQ component will only ever have 1 source and 1 sink buffer. */ - sourceb = comp_dev_get_first_data_producer(dev); - sinkb = comp_dev_get_first_data_consumer(dev); eq_fir_set_alignment(&sourceb->stream, &sinkb->stream); channels = audio_stream_get_channels(&sinkb->stream); frame_fmt = audio_stream_get_frm_fmt(&sourceb->stream); diff --git a/src/audio/eq_fir/eq_fir_ipc4.c b/src/audio/eq_fir/eq_fir_ipc4.c index eec4165b748b..9c73466cfb4a 100644 --- a/src/audio/eq_fir/eq_fir_ipc4.c +++ b/src/audio/eq_fir/eq_fir_ipc4.c @@ -59,6 +59,8 @@ int eq_fir_params(struct processing_module *mod) ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); component_set_nearest_period_frames(dev, params->rate); + /* The caller has verified, that sink and source buffers are connected */ + sourceb = comp_dev_get_first_data_producer(dev); ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index d5dd63a1e568..d369461c31e2 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -187,13 +187,18 @@ static int eq_iir_prepare(struct processing_module *mod, comp_dbg(dev, "eq_iir_prepare()"); + /* EQ component will only ever have 1 source and 1 sink buffer */ + sourceb = comp_dev_get_first_data_producer(dev); + sinkb = comp_dev_get_first_data_consumer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } + ret = eq_iir_prepare_sub(mod); if (ret < 0) return ret; - /* EQ component will only ever have 1 source and 1 sink buffer */ - sourceb = comp_dev_get_first_data_producer(dev); - sinkb = comp_dev_get_first_data_consumer(dev); eq_iir_set_alignment(&sourceb->stream, &sinkb->stream); /* get source and sink data format */ diff --git a/src/audio/eq_iir/eq_iir_ipc3.c b/src/audio/eq_iir/eq_iir_ipc3.c index ca611bc8a819..8fe17f932cca 100644 --- a/src/audio/eq_iir/eq_iir_ipc3.c +++ b/src/audio/eq_iir/eq_iir_ipc3.c @@ -272,6 +272,8 @@ static int eq_iir_verify_params(struct comp_dev *dev, comp_dbg(dev, "eq_iir_verify_params()"); + /* The caller has verified, that sink and source buffers are connected */ + /* EQ component will only ever have 1 source and 1 sink buffer */ sourceb = comp_dev_get_first_data_producer(dev); sinkb = comp_dev_get_first_data_consumer(dev); diff --git a/src/audio/eq_iir/eq_iir_ipc4.c b/src/audio/eq_iir/eq_iir_ipc4.c index 324102be98e5..d5627d04bd8e 100644 --- a/src/audio/eq_iir/eq_iir_ipc4.c +++ b/src/audio/eq_iir/eq_iir_ipc4.c @@ -124,6 +124,8 @@ static int eq_iir_params(struct processing_module *mod) comp_params.chmap[i] = (mod->priv.cfg.base_cfg.audio_fmt.ch_map >> i * 4) & 0xf; component_set_nearest_period_frames(dev, comp_params.rate); + + /* The caller has verified, that sink and source buffers are connected */ sinkb = comp_dev_get_first_data_consumer(dev); return buffer_set_params(sinkb, &comp_params, true); } diff --git a/src/audio/google/google_ctc_audio_processing.c b/src/audio/google/google_ctc_audio_processing.c index b78ee2514a87..463380e37f79 100644 --- a/src/audio/google/google_ctc_audio_processing.c +++ b/src/audio/google/google_ctc_audio_processing.c @@ -355,6 +355,11 @@ static int ctc_prepare(struct processing_module *mod, comp_info(mod->dev, "ctc_prepare()"); source = comp_dev_get_first_data_producer(dev); + if (!source) { + comp_err(dev, "no source buffer"); + return -ENOTCONN; + } + switch (audio_stream_get_frm_fmt(&source->stream)) { #if CONFIG_FORMAT_S16LE case SOF_IPC_FRAME_S16_LE: diff --git a/src/audio/igo_nr/igo_nr.c b/src/audio/igo_nr/igo_nr.c index f53124e71e6e..1cda1a57b857 100644 --- a/src/audio/igo_nr/igo_nr.c +++ b/src/audio/igo_nr/igo_nr.c @@ -818,6 +818,11 @@ static int32_t igo_nr_prepare(struct processing_module *mod, comp_dbg(dev, "igo_nr_prepare()"); + if (!source || !sink) { + comp_err(dev, "no source or sink"); + return -ENOTCONN; + } + #if CONFIG_IPC_MAJOR_4 ret = igo_nr_ipc4_params(mod, source, sink); if (ret) { diff --git a/src/audio/mfcc/mfcc.c b/src/audio/mfcc/mfcc.c index 11cae843829e..3eef92db3bab 100644 --- a/src/audio/mfcc/mfcc.c +++ b/src/audio/mfcc/mfcc.c @@ -193,6 +193,10 @@ static int mfcc_prepare(struct processing_module *mod, /* MFCC component will only ever have 1 source and 1 sink buffer */ sourceb = comp_dev_get_first_data_producer(dev); sinkb = comp_dev_get_first_data_consumer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink"); + return -ENOTCONN; + } /* get source data format */ source_format = audio_stream_get_frm_fmt(&sourceb->stream); diff --git a/src/audio/mixer/mixer.c b/src/audio/mixer/mixer.c index f7583c8b4d1b..42d4c9e33fbc 100644 --- a/src/audio/mixer/mixer.c +++ b/src/audio/mixer/mixer.c @@ -214,6 +214,11 @@ static int mixer_prepare(struct processing_module *mod, struct comp_buffer *sink; sink = comp_dev_get_first_data_consumer(dev); + if (!sink) { + comp_err(dev, "no sink"); + return -ENOTCONN; + } + md->mix_func = mixer_get_processing_function(dev, sink); mixer_set_frame_alignment(&sink->stream); diff --git a/src/audio/module_adapter/module/waves/waves.c b/src/audio/module_adapter/module/waves/waves.c index 5df71d159d8a..d384b2b15334 100644 --- a/src/audio/module_adapter/module/waves/waves.c +++ b/src/audio/module_adapter/module/waves/waves.c @@ -226,6 +226,11 @@ static int waves_effect_check(struct comp_dev *dev) /* Init sink & source buffers */ comp_dbg(dev, "waves_effect_check() start"); + if (!source || !sink) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } + /* todo use fallback to comp_verify_params when ready */ /* resampling not supported */ diff --git a/src/audio/multiband_drc/multiband_drc.c b/src/audio/multiband_drc/multiband_drc.c index 3787352f1fa3..45df154dfad6 100644 --- a/src/audio/multiband_drc/multiband_drc.c +++ b/src/audio/multiband_drc/multiband_drc.c @@ -378,6 +378,10 @@ static int multiband_drc_prepare(struct processing_module *mod, /* DRC component will only ever have 1 source and 1 sink buffer */ sourceb = comp_dev_get_first_data_producer(dev); + if (!sourceb) { + comp_err(dev, "no source buffer"); + return -ENOTCONN; + } /* get source data format */ cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream); diff --git a/src/audio/multiband_drc/multiband_drc_ipc4.c b/src/audio/multiband_drc/multiband_drc_ipc4.c index 1c6029ecf2a0..03d7e6c5a074 100644 --- a/src/audio/multiband_drc/multiband_drc_ipc4.c +++ b/src/audio/multiband_drc/multiband_drc_ipc4.c @@ -101,6 +101,10 @@ int multiband_drc_params(struct processing_module *mod) component_set_nearest_period_frames(dev, comp_params.rate); sinkb = comp_dev_get_first_data_consumer(dev); + if (!sinkb) { + comp_err(dev, "no sink buffer"); + return -ENOTCONN; + } return buffer_set_params(sinkb, &comp_params, true); } diff --git a/src/audio/rtnr/rtnr.c b/src/audio/rtnr/rtnr.c index 88c420a6af2a..3cb0cb484a8d 100644 --- a/src/audio/rtnr/rtnr.c +++ b/src/audio/rtnr/rtnr.c @@ -780,6 +780,8 @@ static void rtnr_params(struct processing_module *mod) ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); component_set_nearest_period_frames(dev, params->rate); + /* The caller has checked validity of source and sink buffers */ + sourceb = comp_dev_get_first_data_producer(dev); ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); @@ -799,6 +801,13 @@ static int rtnr_prepare(struct processing_module *mod, comp_dbg(dev, "rtnr_prepare()"); + sinkb = comp_dev_get_first_data_consumer(dev); + sourceb = comp_dev_get_first_data_producer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } + #if CONFIG_IPC_MAJOR_4 rtnr_params(mod); #endif @@ -813,10 +822,8 @@ static int rtnr_prepare(struct processing_module *mod, /* Initialize RTNR */ /* Get sink data format */ - sinkb = comp_dev_get_first_data_consumer(dev); cd->sink_format = audio_stream_get_frm_fmt(&sinkb->stream); cd->sink_stream.frame_fmt = audio_stream_get_frm_fmt(&sinkb->stream); - sourceb = comp_dev_get_first_data_producer(dev); ret = rtnr_check_params(mod, &sourceb->stream, &sinkb->stream); if (ret) goto err; diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index 6215caccd2a2..20ab3ff5b8c1 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -427,6 +427,10 @@ static int selector_prepare(struct comp_dev *dev) /* selector component will have 1 source and 1 sink buffer */ sourceb = comp_dev_get_first_data_producer(dev); sinkb = comp_dev_get_first_data_consumer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } /* get source data format and period bytes */ cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream); diff --git a/src/audio/smart_amp/smart_amp.c b/src/audio/smart_amp/smart_amp.c index 6cb396a4c153..937fd20434b3 100644 --- a/src/audio/smart_amp/smart_amp.c +++ b/src/audio/smart_amp/smart_amp.c @@ -755,6 +755,10 @@ static int smart_amp_prepare(struct comp_dev *dev) /* sink buffer */ sad->sink_buf = comp_dev_get_first_data_consumer(dev); + if (!sad->sink_buf) { + comp_err(dev, "no sink buffer"); + return -ENOTCONN; + } /* get frame format and channels param of stream and feedback source */ ff_src_fmt = audio_stream_get_frm_fmt(&sad->source_buf->stream); diff --git a/src/audio/tdfb/tdfb.c b/src/audio/tdfb/tdfb.c index 0f3636fcfedd..b335b56ea47e 100644 --- a/src/audio/tdfb/tdfb.c +++ b/src/audio/tdfb/tdfb.c @@ -731,15 +731,20 @@ static int tdfb_prepare(struct processing_module *mod, comp_info(dev, "tdfb_prepare()"); + /* Find source and sink buffers */ + sourceb = comp_dev_get_first_data_producer(dev); + sinkb = comp_dev_get_first_data_consumer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } + ret = tdfb_params(mod); if (ret) { comp_err(dev, "Failed tdfb_params()"); return ret; } - /* Find source and sink buffers */ - sourceb = comp_dev_get_first_data_producer(dev); - sinkb = comp_dev_get_first_data_consumer(dev); tdfb_set_alignment(&sourceb->stream, &sinkb->stream); frame_fmt = audio_stream_get_frm_fmt(&sourceb->stream); diff --git a/src/audio/tdfb/tdfb_ipc4.c b/src/audio/tdfb/tdfb_ipc4.c index 176d9fa710b5..dd8ddec714c2 100644 --- a/src/audio/tdfb/tdfb_ipc4.c +++ b/src/audio/tdfb/tdfb_ipc4.c @@ -199,6 +199,8 @@ int tdfb_params(struct processing_module *mod) ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); component_set_nearest_period_frames(dev, params->rate); + + /* The caller has verified source and sink buffer validity */ sourceb = comp_dev_get_first_data_producer(dev); ipc4_update_buffer_format(sourceb, &mod->priv.cfg.input_pins[0].audio_fmt); diff --git a/src/audio/tone.c b/src/audio/tone.c index 05389a3f4b1b..2cc3a82d8fcb 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -429,8 +429,11 @@ static int tone_params(struct comp_dev *dev, struct comp_buffer *sourceb, *sinkb; sourceb = comp_dev_get_first_data_producer(dev); - sinkb = comp_dev_get_first_data_consumer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } comp_info(dev, "tone_params(), config->frame_fmt = %u", dev->ipc_config.frame_fmt); @@ -671,6 +674,10 @@ static int tone_prepare(struct comp_dev *dev) return PPL_STATUS_PATH_STOP; sourceb = comp_dev_get_first_data_producer(dev); + if (!sourceb) { + comp_err(dev, "no source buffer"); + return -ENOTCONN; + } cd->channels = audio_stream_get_channels(&sourceb->stream); comp_info(dev, "tone_prepare(), cd->channels = %u, cd->rate = %u", diff --git a/src/audio/volume/volume.c b/src/audio/volume/volume.c index c6cea52135bc..4b168b7fa1c0 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/volume/volume.c @@ -673,11 +673,15 @@ static int volume_prepare(struct processing_module *mod, comp_dbg(dev, "volume_prepare()"); - ret = volume_peak_prepare(cd, mod); - /* volume component will only ever have 1 sink and source buffer */ sinkb = comp_dev_get_first_data_consumer(dev); sourceb = comp_dev_get_first_data_producer(dev); + if (!sourceb || !sinkb) { + comp_err(dev, "no source or sink buffer"); + return -ENOTCONN; + } + + ret = volume_peak_prepare(cd, mod); volume_set_alignment(&sourceb->stream, &sinkb->stream); diff --git a/src/audio/volume/volume_ipc4.c b/src/audio/volume/volume_ipc4.c index 3abc62bfab50..2424cbb13a76 100644 --- a/src/audio/volume/volume_ipc4.c +++ b/src/audio/volume/volume_ipc4.c @@ -419,7 +419,10 @@ static int volume_params(struct processing_module *mod) component_set_nearest_period_frames(dev, params->rate); - /* volume component will only ever have 1 sink buffer */ + /* + * volume component will only ever have 1 sink buffer, the caller has + * verified their validity + */ sinkb = comp_dev_get_first_data_consumer(dev); ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); diff --git a/src/ipc/ipc-helper.c b/src/ipc/ipc-helper.c index 65910767d95e..c6666581e5d4 100644 --- a/src/ipc/ipc-helper.c +++ b/src/ipc/ipc-helper.c @@ -156,6 +156,14 @@ int comp_verify_params(struct comp_dev *dev, uint32_t flag, /* set component period frames */ component_set_nearest_period_frames(dev, audio_stream_get_rate(&buf->stream)); + } else if (list_is_empty(source_list)) { + /* + * both lists are empty, e.g. if it's the single component in a + * pipeline and no other pipelines are currently connected, then + * there's just nothing to update + */ + comp_dbg(dev, "no connected buffers"); + return 0; } else { /* for other components we iterate over all downstream buffers * (for playback) or upstream buffers (for capture). diff --git a/src/samples/audio/smart_amp_test_ipc3.c b/src/samples/audio/smart_amp_test_ipc3.c index 289b8a36e126..f02f6c5d9db7 100644 --- a/src/samples/audio/smart_amp_test_ipc3.c +++ b/src/samples/audio/smart_amp_test_ipc3.c @@ -509,6 +509,10 @@ static int smart_amp_prepare(struct comp_dev *dev) } sad->sink_buf = comp_dev_get_first_data_consumer(dev); + if (!sad->sink_buf) { + comp_err(dev, "no sink buffer"); + return -ENOTCONN; + } sad->out_channels = audio_stream_get_channels(&sad->sink_buf->stream);