diff --git a/sound/firewire/fireworks/fireworks_midi.c b/sound/firewire/fireworks/fireworks_midi.c index fba01bbba456..38232dcf6e03 100644 --- a/sound/firewire/fireworks/fireworks_midi.c +++ b/sound/firewire/fireworks/fireworks_midi.c @@ -17,8 +17,10 @@ static int midi_capture_open(struct snd_rawmidi_substream *substream) if (err < 0) goto end; + mutex_lock(&efw->mutex); atomic_inc(&efw->capture_substreams); err = snd_efw_stream_start_duplex(efw, 0); + mutex_unlock(&efw->mutex); if (err < 0) snd_efw_stream_lock_release(efw); @@ -35,8 +37,10 @@ static int midi_playback_open(struct snd_rawmidi_substream *substream) if (err < 0) goto end; + mutex_lock(&efw->mutex); atomic_inc(&efw->playback_substreams); err = snd_efw_stream_start_duplex(efw, 0); + mutex_unlock(&efw->mutex); if (err < 0) snd_efw_stream_lock_release(efw); end: @@ -47,8 +51,10 @@ static int midi_capture_close(struct snd_rawmidi_substream *substream) { struct snd_efw *efw = substream->rmidi->private_data; + mutex_lock(&efw->mutex); atomic_dec(&efw->capture_substreams); snd_efw_stream_stop_duplex(efw); + mutex_unlock(&efw->mutex); snd_efw_stream_lock_release(efw); return 0; @@ -58,8 +64,10 @@ static int midi_playback_close(struct snd_rawmidi_substream *substream) { struct snd_efw *efw = substream->rmidi->private_data; + mutex_lock(&efw->mutex); atomic_dec(&efw->playback_substreams); snd_efw_stream_stop_duplex(efw); + mutex_unlock(&efw->mutex); snd_efw_stream_lock_release(efw); return 0; diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c index d27135bac513..69f15a6d6f88 100644 --- a/sound/firewire/fireworks/fireworks_pcm.c +++ b/sound/firewire/fireworks/fireworks_pcm.c @@ -251,8 +251,11 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream, if (err < 0) return err; - if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) + if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { + mutex_lock(&efw->mutex); atomic_inc(&efw->capture_substreams); + mutex_unlock(&efw->mutex); + } amdtp_am824_set_pcm_format(&efw->tx_stream, params_format(hw_params)); @@ -269,8 +272,11 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream, if (err < 0) return err; - if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) + if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { + mutex_lock(&efw->mutex); atomic_inc(&efw->playback_substreams); + mutex_unlock(&efw->mutex); + } amdtp_am824_set_pcm_format(&efw->rx_stream, params_format(hw_params)); @@ -281,8 +287,11 @@ static int pcm_capture_hw_free(struct snd_pcm_substream *substream) { struct snd_efw *efw = substream->private_data; - if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) + if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) { + mutex_lock(&efw->mutex); atomic_dec(&efw->capture_substreams); + mutex_unlock(&efw->mutex); + } snd_efw_stream_stop_duplex(efw); @@ -292,8 +301,11 @@ static int pcm_playback_hw_free(struct snd_pcm_substream *substream) { struct snd_efw *efw = substream->private_data; - if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) + if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) { + mutex_lock(&efw->mutex); atomic_dec(&efw->playback_substreams); + mutex_unlock(&efw->mutex); + } snd_efw_stream_stop_duplex(efw); diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index 759f6e3ed44a..69307452dee7 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c @@ -214,8 +214,6 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate) unsigned int curr_rate; int err = 0; - mutex_lock(&efw->mutex); - /* Need no substreams */ if ((atomic_read(&efw->playback_substreams) == 0) && (atomic_read(&efw->capture_substreams) == 0)) @@ -286,7 +284,6 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate) } } end: - mutex_unlock(&efw->mutex); return err; } @@ -307,16 +304,12 @@ void snd_efw_stream_stop_duplex(struct snd_efw *efw) master_substreams = &efw->capture_substreams; } - mutex_lock(&efw->mutex); - if (atomic_read(slave_substreams) == 0) { stop_stream(efw, slave); if (atomic_read(master_substreams) == 0) stop_stream(efw, master); } - - mutex_unlock(&efw->mutex); } void snd_efw_stream_update_duplex(struct snd_efw *efw)