[alsa-devel] [PATCH] fireworks: serialize transactions to update connections at bus reset

Takashi Sakamoto o-takashi at sakamocchi.jp
Sat Feb 20 08:48:29 CET 2016


On Feb 20 2016 16:41, Takashi Sakamoto wrote:
> In IEC 61883-1, at bus-reset, applications can continue isochronous
> streaming by updating connections. In ALSA fireworks driver, the
> operation is executed in 'update' handler for bus driver.
> 
> The connection resources are also changed in process contexts of PCM/MIDI
> applications. Therefore, bus-reset handling has race condition
> against connection. Current ALSA fireworks driver has a bug for the
> condition.
> 
> This commit fixes the bug, by expand critical section with mutex. As a
> result, connection updating operation in bus-reset handler and connection
> changing operation in process context are serialized.

Oops. I forgot to add 'ALSA:' prefix to the commit title. I'm sorry but
would you please add it when merging to for-next branch?

> Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
> ---
>  sound/firewire/fireworks/fireworks.c        | 3 +++
>  sound/firewire/fireworks/fireworks_stream.c | 6 ++----
>  2 files changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
> index d5b19bc..8f27b67 100644
> --- a/sound/firewire/fireworks/fireworks.c
> +++ b/sound/firewire/fireworks/fireworks.c
> @@ -301,7 +301,10 @@ static void efw_update(struct fw_unit *unit)
>  	struct snd_efw *efw = dev_get_drvdata(&unit->device);
>  
>  	snd_efw_transaction_bus_reset(efw->unit);
> +
> +	mutex_lock(&efw->mutex);
>  	snd_efw_stream_update_duplex(efw);
> +	mutex_unlock(&efw->mutex);
>  }
>  
>  static void efw_remove(struct fw_unit *unit)
> diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
> index 968a40a..425db8d 100644
> --- a/sound/firewire/fireworks/fireworks_stream.c
> +++ b/sound/firewire/fireworks/fireworks_stream.c
> @@ -313,12 +313,10 @@ void snd_efw_stream_stop_duplex(struct snd_efw *efw)
>  
>  void snd_efw_stream_update_duplex(struct snd_efw *efw)
>  {
> -	if ((cmp_connection_update(&efw->out_conn) < 0) ||
> -	    (cmp_connection_update(&efw->in_conn) < 0)) {
> -		mutex_lock(&efw->mutex);
> +	if (cmp_connection_update(&efw->out_conn) < 0 ||
> +	    cmp_connection_update(&efw->in_conn) < 0) {
>  		stop_stream(efw, &efw->rx_stream);
>  		stop_stream(efw, &efw->tx_stream);
> -		mutex_unlock(&efw->mutex);
>  	} else {
>  		amdtp_stream_update(&efw->rx_stream);
>  		amdtp_stream_update(&efw->tx_stream);

Regards

Takashi Sakamoto


More information about the Alsa-devel mailing list