From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
When CONFIG_SND_CTL_VALIDATION is set, accesses to extended bytes control generate spurious error messages when the size exceeds 512 bytes, such as
[ 11.224223] sof_sdw sof_sdw: control 2:0:0:EQIIR5.0 eqiir_coef_5:0: invalid count 1024
In addition the error check returns -EINVAL which has the nasty side effect of preventing applications accessing controls from working, e.g.
root@plb:~# alsamixer cannot load mixer controls: Invalid argument
It's agreed that the control interface has been abused since 2014, but forcing a check should not prevent existing solutions from working.
This patch skips the checks conditionally if CONFIG_SND_CTL_VALIDATION is set and the byte array provided by topology is > 512. This preserves the checks for all other cases.
Fixes: 1a3232d2f61d2 ('ASoC: topology: Add support for TLV bytes controls') BugLink: https://github.com/thesofproject/linux/issues/2430 Reported-by: Takashi Iwai tiwai@suse.de Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Jaska Uimonen jaska.uimonen@intel.com Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com --- sound/soc/soc-topology.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 28faaf58326e..63086fa8b861 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -592,6 +592,17 @@ static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr, k->info = snd_soc_bytes_info_ext; k->tlv.c = snd_soc_bytes_tlv_callback;
+ /* + * When a topology-based implementation abuses the + * control interface and uses bytes_ext controls of + * more than 512 bytes, we need to disable the size + * checks, otherwise accesses to such controls will + * return an -EINVAL error and prevent the card from + * being configured. + */ + if (IS_ENABLED(CONFIG_SND_CTL_VALIDATION) && sbe->max > 512) + k->access |= SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK; + ext_ops = tplg->bytes_ext_ops; num_ops = tplg->bytes_ext_ops_count; for (i = 0; i < num_ops; i++) {