From 22c103cd3dfadff340b3b639e477a3c161cb2104 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sat, 29 Aug 2015 10:38:46 +0900 Subject: ALSA: fireworks/bebob/dice/oxfw: fix substreams counting at vmalloc failure In PCM core, when hw_params() in each driver returns error, the state of PCM substream is kept as 'open'. In this case, current drivers for sound units on IEEE 1394 bus doesn't decrement substream counter in hw_free() correctly. This causes these drivers to keep streams even if not required. This commit fixes this bug. When snd_pcm_lib_alloc_vmalloc_buffer() fails, hw_params function in each driver returns without incrementing the counter. Reported-by: Takashi Iwai Signed-off-by: Takashi Sakamoto Acked-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/firewire/fireworks/fireworks_pcm.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'sound/firewire/fireworks') diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c index 8a34753de210..c30b2ffa8dfb 100644 --- a/sound/firewire/fireworks/fireworks_pcm.c +++ b/sound/firewire/fireworks/fireworks_pcm.c @@ -244,25 +244,35 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct snd_efw *efw = substream->private_data; + int err; + + err = snd_pcm_lib_alloc_vmalloc_buffer(substream, + params_buffer_bytes(hw_params)); + if (err < 0) + return err; if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) atomic_inc(&efw->capture_substreams); amdtp_stream_set_pcm_format(&efw->tx_stream, params_format(hw_params)); - return snd_pcm_lib_alloc_vmalloc_buffer(substream, - params_buffer_bytes(hw_params)); + return 0; } static int pcm_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct snd_efw *efw = substream->private_data; + int err; + + err = snd_pcm_lib_alloc_vmalloc_buffer(substream, + params_buffer_bytes(hw_params)); + if (err < 0) + return err; if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) atomic_inc(&efw->playback_substreams); amdtp_stream_set_pcm_format(&efw->rx_stream, params_format(hw_params)); - return snd_pcm_lib_alloc_vmalloc_buffer(substream, - params_buffer_bytes(hw_params)); + return 0; } static int pcm_capture_hw_free(struct snd_pcm_substream *substream) -- cgit