diff options
Diffstat (limited to 'sound/firewire/isight.c')
-rw-r--r-- | sound/firewire/isight.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c index a6f19f57a1c3..0230605c917e 100644 --- a/sound/firewire/isight.c +++ b/sound/firewire/isight.c | |||
@@ -56,6 +56,7 @@ struct isight { | |||
56 | struct iso_packets_buffer buffer; | 56 | struct iso_packets_buffer buffer; |
57 | struct fw_iso_resources resources; | 57 | struct fw_iso_resources resources; |
58 | struct fw_iso_context *context; | 58 | struct fw_iso_context *context; |
59 | bool pcm_active; | ||
59 | bool pcm_running; | 60 | bool pcm_running; |
60 | bool first_packet; | 61 | bool first_packet; |
61 | int packet_index; | 62 | int packet_index; |
@@ -131,10 +132,12 @@ static void isight_pcm_abort(struct isight *isight) | |||
131 | { | 132 | { |
132 | unsigned long flags; | 133 | unsigned long flags; |
133 | 134 | ||
134 | snd_pcm_stream_lock_irqsave(isight->pcm, flags); | 135 | if (ACCESS_ONCE(isight->pcm_active)) { |
135 | if (snd_pcm_running(isight->pcm)) | 136 | snd_pcm_stream_lock_irqsave(isight->pcm, flags); |
136 | snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN); | 137 | if (snd_pcm_running(isight->pcm)) |
137 | snd_pcm_stream_unlock_irqrestore(isight->pcm, flags); | 138 | snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN); |
139 | snd_pcm_stream_unlock_irqrestore(isight->pcm, flags); | ||
140 | } | ||
138 | } | 141 | } |
139 | 142 | ||
140 | static void isight_dropped_samples(struct isight *isight, unsigned int total) | 143 | static void isight_dropped_samples(struct isight *isight, unsigned int total) |
@@ -295,8 +298,17 @@ static int isight_close(struct snd_pcm_substream *substream) | |||
295 | static int isight_hw_params(struct snd_pcm_substream *substream, | 298 | static int isight_hw_params(struct snd_pcm_substream *substream, |
296 | struct snd_pcm_hw_params *hw_params) | 299 | struct snd_pcm_hw_params *hw_params) |
297 | { | 300 | { |
298 | return snd_pcm_lib_alloc_vmalloc_buffer(substream, | 301 | struct isight *isight = substream->private_data; |
299 | params_buffer_bytes(hw_params)); | 302 | int err; |
303 | |||
304 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
305 | params_buffer_bytes(hw_params)); | ||
306 | if (err < 0) | ||
307 | return err; | ||
308 | |||
309 | ACCESS_ONCE(isight->pcm_active) = true; | ||
310 | |||
311 | return 0; | ||
300 | } | 312 | } |
301 | 313 | ||
302 | static void isight_stop_streaming(struct isight *isight) | 314 | static void isight_stop_streaming(struct isight *isight) |
@@ -322,6 +334,8 @@ static int isight_hw_free(struct snd_pcm_substream *substream) | |||
322 | { | 334 | { |
323 | struct isight *isight = substream->private_data; | 335 | struct isight *isight = substream->private_data; |
324 | 336 | ||
337 | ACCESS_ONCE(isight->pcm_active) = false; | ||
338 | |||
325 | mutex_lock(&isight->mutex); | 339 | mutex_lock(&isight->mutex); |
326 | isight_stop_streaming(isight); | 340 | isight_stop_streaming(isight); |
327 | mutex_unlock(&isight->mutex); | 341 | mutex_unlock(&isight->mutex); |