[alsa-devel] [PATCH] ALSA: fireworks/bebob/dice/oxfw: fix substreams counting at vmalloc failure

Takashi Iwai tiwai at suse.de
Sat Aug 29 09:15:07 CEST 2015


On Sat, 29 Aug 2015 03:38:46 +0200,
Takashi Sakamoto wrote:
> 
> 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 <tiwai at suse.de>
> Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>

Applied, thanks.


Takashi

> ---
>  sound/firewire/bebob/bebob_pcm.c         | 20 ++++++++++++++++----
>  sound/firewire/dice/dice-pcm.c           | 18 ++++++++++++++----
>  sound/firewire/fireworks/fireworks_pcm.c | 18 ++++++++++++++----
>  sound/firewire/oxfw/oxfw-pcm.c           | 17 +++++++++++++----
>  4 files changed, 57 insertions(+), 16 deletions(-)
> 
> diff --git a/sound/firewire/bebob/bebob_pcm.c b/sound/firewire/bebob/bebob_pcm.c
> index 7a2c1f5..c0f018a 100644
> --- a/sound/firewire/bebob/bebob_pcm.c
> +++ b/sound/firewire/bebob/bebob_pcm.c
> @@ -211,26 +211,38 @@ pcm_capture_hw_params(struct snd_pcm_substream *substream,
>  		      struct snd_pcm_hw_params *hw_params)
>  {
>  	struct snd_bebob *bebob = 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(&bebob->substreams_counter);
>  	amdtp_stream_set_pcm_format(&bebob->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_bebob *bebob = 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(&bebob->substreams_counter);
>  	amdtp_stream_set_pcm_format(&bebob->rx_stream,
>  				    params_format(hw_params));
> -	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
> -						params_buffer_bytes(hw_params));
> +
> +	return 0;
>  }
>  
>  static int
> diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
> index f7771451..4e67b1d 100644
> --- a/sound/firewire/dice/dice-pcm.c
> +++ b/sound/firewire/dice/dice-pcm.c
> @@ -230,6 +230,12 @@ static int capture_hw_params(struct snd_pcm_substream *substream,
>  			     struct snd_pcm_hw_params *hw_params)
>  {
>  	struct snd_dice *dice = 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) {
>  		mutex_lock(&dice->mutex);
> @@ -240,13 +246,18 @@ static int capture_hw_params(struct snd_pcm_substream *substream,
>  	amdtp_stream_set_pcm_format(&dice->tx_stream,
>  				    params_format(hw_params));
>  
> -	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
> -						params_buffer_bytes(hw_params));
> +	return 0;
>  }
>  static int playback_hw_params(struct snd_pcm_substream *substream,
>  			      struct snd_pcm_hw_params *hw_params)
>  {
>  	struct snd_dice *dice = 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) {
>  		mutex_lock(&dice->mutex);
> @@ -257,8 +268,7 @@ static int playback_hw_params(struct snd_pcm_substream *substream,
>  	amdtp_stream_set_pcm_format(&dice->rx_stream,
>  				    params_format(hw_params));
>  
> -	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
> -						params_buffer_bytes(hw_params));
> +	return 0;
>  }
>  
>  static int capture_hw_free(struct snd_pcm_substream *substream)
> diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c
> index 8a34753..c30b2ff 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)
> diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c
> index 67ade07..9c73930 100644
> --- a/sound/firewire/oxfw/oxfw-pcm.c
> +++ b/sound/firewire/oxfw/oxfw-pcm.c
> @@ -231,7 +231,12 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
>  				 struct snd_pcm_hw_params *hw_params)
>  {
>  	struct snd_oxfw *oxfw = 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) {
>  		mutex_lock(&oxfw->mutex);
> @@ -241,13 +246,18 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
>  
>  	amdtp_stream_set_pcm_format(&oxfw->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_oxfw *oxfw = 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) {
>  		mutex_lock(&oxfw->mutex);
> @@ -257,8 +267,7 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
>  
>  	amdtp_stream_set_pcm_format(&oxfw->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)
> -- 
> 2.1.4
> 


More information about the Alsa-devel mailing list