[PATCH] ASoC: soc-pcm: fix regression in soc_new_pcm()
Commit af4bac11531f ("ASoC: soc-pcm: crash in snd_soc_dapm_new_dai") swapped the SNDRV_PCM_STREAM_* parameter in the snd_soc_dai_stream_valid(cpu_dai, ...) checks. But that works only for codec2codec links. For normal links it breaks registration of playback/capture-only PCM devices.
E.g. on qcom/apq8016_sbc there is usually one playback-only and one capture-only PCM device, but they disappeared after the commit.
The codec2codec case was added in commit a342031cdd08 ("ASoC: create pcm for codec2codec links as well") as an extra check (e.g. `playback = playback && cpu_playback->channels_min`).
We should be able to simplify the code by checking directly for the correct stream type in the loop. This also fixes the regression because we check for PLAYBACK for both codec and cpu dai again when codec2codec is not used.
Cc: Sameer Pujar spujar@nvidia.com Cc: Jerome Brunet jbrunet@baylibre.com Fixes: af4bac11531f ("ASoC: soc-pcm: crash in snd_soc_dapm_new_dai") Signed-off-by: Stephan Gerhold stephan@gerhold.net --- Original report of the regression: https://lore.kernel.org/alsa-devel/20200217144120.GA243254@gerhold.net/
I'm still quite confused about the crash that was fixed by the commit that introduced the regression... If anything, the original code added in commit a342031cdd08 ("ASoC: create pcm for codec2codec links as well") should have been too "restrictive" since it checked for both PLAYBACK and CAPTURE for the cpu dai in the codec2codec case...
Audio works fine gain on apq8016_sbc with this patch, but I don't have any device with codec2codec to test this. --- sound/soc/soc-pcm.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index ff1b7c7078e5..cfa24d214a9c 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2888,22 +2888,19 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) capture = rtd->dai_link->dpcm_capture; } else { /* Adapt stream for codec2codec links */ - struct snd_soc_pcm_stream *cpu_capture = rtd->dai_link->params ? - &cpu_dai->driver->playback : &cpu_dai->driver->capture; - struct snd_soc_pcm_stream *cpu_playback = rtd->dai_link->params ? - &cpu_dai->driver->capture : &cpu_dai->driver->playback; + int cpu_capture = rtd->dai_link->params ? + SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; + int cpu_playback = rtd->dai_link->params ? + SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
for_each_rtd_codec_dai(rtd, i, codec_dai) { if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) && - snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE)) + snd_soc_dai_stream_valid(cpu_dai, cpu_playback)) playback = 1; if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) && - snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK)) + snd_soc_dai_stream_valid(cpu_dai, cpu_capture)) capture = 1; } - - capture = capture && cpu_capture->channels_min; - playback = playback && cpu_playback->channels_min; }
if (rtd->dai_link->playback_only) {
On Tue 18 Feb 2020 at 11:38, Stephan Gerhold stephan@gerhold.net wrote:
Commit af4bac11531f ("ASoC: soc-pcm: crash in snd_soc_dapm_new_dai") swapped the SNDRV_PCM_STREAM_* parameter in the snd_soc_dai_stream_valid(cpu_dai, ...) checks. But that works only for codec2codec links. For normal links it breaks registration of playback/capture-only PCM devices.
E.g. on qcom/apq8016_sbc there is usually one playback-only and one capture-only PCM device, but they disappeared after the commit.
The codec2codec case was added in commit a342031cdd08 ("ASoC: create pcm for codec2codec links as well") as an extra check (e.g. `playback = playback && cpu_playback->channels_min`).
That particular check was there when I worked on that change but I seems I messed up when I rebased on Kuninori's work regarding snd_soc_dai_stream_valid() which happened more or less at the same time.
We should be able to simplify the code by checking directly for the correct stream type in the loop. This also fixes the regression because we check for PLAYBACK for both codec and cpu dai again when codec2codec is not used.
Cc: Sameer Pujar spujar@nvidia.com Cc: Jerome Brunet jbrunet@baylibre.com Fixes: af4bac11531f ("ASoC: soc-pcm: crash in snd_soc_dapm_new_dai") Signed-off-by: Stephan Gerhold stephan@gerhold.net
Looks good and works with the codec-to-codec links on Amlogic aiu. Thx !
Reviewed-by: Jerome Brunet jbrunet@baylibre.com Tested-by: Jerome Brunet jbrunet@baylibre.com
The patch
ASoC: soc-pcm: fix regression in soc_new_pcm()
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From a4877a6fb2bd2e356a5eaacd86d6b6d69ff84e69 Mon Sep 17 00:00:00 2001
From: Stephan Gerhold stephan@gerhold.net Date: Tue, 18 Feb 2020 11:38:24 +0100 Subject: [PATCH] ASoC: soc-pcm: fix regression in soc_new_pcm()
Commit af4bac11531f ("ASoC: soc-pcm: crash in snd_soc_dapm_new_dai") swapped the SNDRV_PCM_STREAM_* parameter in the snd_soc_dai_stream_valid(cpu_dai, ...) checks. But that works only for codec2codec links. For normal links it breaks registration of playback/capture-only PCM devices.
E.g. on qcom/apq8016_sbc there is usually one playback-only and one capture-only PCM device, but they disappeared after the commit.
The codec2codec case was added in commit a342031cdd08 ("ASoC: create pcm for codec2codec links as well") as an extra check (e.g. `playback = playback && cpu_playback->channels_min`).
We should be able to simplify the code by checking directly for the correct stream type in the loop. This also fixes the regression because we check for PLAYBACK for both codec and cpu dai again when codec2codec is not used.
Fixes: af4bac11531f ("ASoC: soc-pcm: crash in snd_soc_dapm_new_dai") Signed-off-by: Stephan Gerhold stephan@gerhold.net Tested-by: Jerome Brunet jbrunet@baylibre.com Reviewed-by: Jerome Brunet jbrunet@baylibre.com Cc: Jerome Brunet jbrunet@baylibre.com Cc: Sameer Pujar spujar@nvidia.com Link: https://lore.kernel.org/r/20200218103824.26708-1-stephan@gerhold.net Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/soc-pcm.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 6630fadd6e09..65a3856be250 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2858,22 +2858,19 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) capture = rtd->dai_link->dpcm_capture; } else { /* Adapt stream for codec2codec links */ - struct snd_soc_pcm_stream *cpu_capture = rtd->dai_link->params ? - &cpu_dai->driver->playback : &cpu_dai->driver->capture; - struct snd_soc_pcm_stream *cpu_playback = rtd->dai_link->params ? - &cpu_dai->driver->capture : &cpu_dai->driver->playback; + int cpu_capture = rtd->dai_link->params ? + SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; + int cpu_playback = rtd->dai_link->params ? + SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
for_each_rtd_codec_dai(rtd, i, codec_dai) { if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) && - snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE)) + snd_soc_dai_stream_valid(cpu_dai, cpu_playback)) playback = 1; if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) && - snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK)) + snd_soc_dai_stream_valid(cpu_dai, cpu_capture)) capture = 1; } - - capture = capture && cpu_capture->channels_min; - playback = playback && cpu_playback->channels_min; }
if (rtd->dai_link->playback_only) {
participants (3)
-
Jerome Brunet
-
Mark Brown
-
Stephan Gerhold