summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2019-04-30 18:09:18 -0500
committerMark Brown <broonie@kernel.org>2019-05-03 14:56:31 +0900
commit8e3a6e45a77bd4167554b4bd0633a2adabf1bd77 (patch)
treebcfe8008ad4645aaa4a7851225ada17e69dd616e /sound
parent4acb1c2ea42e19101eae4ac9f002853553b8b721 (diff)
ASoC: SOF: topology: add support for stricter ABI checks
Fail early if topology is more recent than kernel and Kconfig is selected. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/sof/topology.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index 1f71857298a9..c88afa872a58 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -3049,6 +3049,7 @@ static int sof_manifest(struct snd_soc_component *scomp, int index,
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
u32 size;
+ u32 abi_version;
size = le32_to_cpu(man->priv.size);
@@ -3058,20 +3059,36 @@ static int sof_manifest(struct snd_soc_component *scomp, int index,
return 0;
}
- if (size == SOF_TPLG_ABI_SIZE) {
- dev_info(sdev->dev,
- "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n",
- man->priv.data[0], man->priv.data[1],
- man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR,
- SOF_ABI_PATCH);
- if (SOF_ABI_VER(man->priv.data[0], man->priv.data[1],
- man->priv.data[2]) <= SOF_ABI_VERSION)
- return 0;
+ if (size != SOF_TPLG_ABI_SIZE) {
+ dev_err(sdev->dev, "error: invalid topology ABI size\n");
+ return -EINVAL;
}
- dev_err(sdev->dev,
- "error: Incompatible ABI version %d:%d:%d\n",
- man->priv.data[0], man->priv.data[1], man->priv.data[2]);
- return -EINVAL;
+
+ dev_info(sdev->dev,
+ "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n",
+ man->priv.data[0], man->priv.data[1],
+ man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR,
+ SOF_ABI_PATCH);
+
+ abi_version = SOF_ABI_VER(man->priv.data[0],
+ man->priv.data[1],
+ man->priv.data[2]);
+
+ if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) {
+ dev_err(sdev->dev, "error: incompatible topology ABI version\n");
+ return -EINVAL;
+ }
+
+ if (abi_version > SOF_ABI_VERSION) {
+ if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) {
+ dev_warn(sdev->dev, "warn: topology ABI is more recent than kernel\n");
+ } else {
+ dev_err(sdev->dev, "error: topology ABI is more recent than kernel\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
}
/* vendor specific kcontrol handlers available for binding */