summaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorMark Hills <mark@pogo.org.uk>2009-10-24 13:59:35 +0200
committerTakashi Iwai <tiwai@suse.de>2009-10-30 12:29:16 +0100
commit3702b082281929cf1bdf14f67eb0619aab58b496 (patch)
tree26eeb2395c960744c70eb3d5e31a4d9f16ec0c6a /sound/usb
parentALSA: sound/parisc: Move dereference after NULL test (diff)
downloadlinux-3702b082281929cf1bdf14f67eb0619aab58b496.tar.xz
linux-3702b082281929cf1bdf14f67eb0619aab58b496.zip
ALSA: snd-usb-caiaq: Missing lock around use of buffer positions
Fix a race which causes snd_pcm_update_hw_ptr_pos() to report a bug. Signed-off-by: Mark Hills <mark@pogo.org.uk> Acked-by: Daniel Mack <daniel@caiaq.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/caiaq/audio.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 121af0644fd9..e76017cd5acf 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -269,16 +269,22 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
{
int index = sub->number;
struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+ snd_pcm_uframes_t ptr;
+
+ spin_lock(&dev->spinlock);
if (dev->input_panic || dev->output_panic)
- return SNDRV_PCM_POS_XRUN;
+ ptr = SNDRV_PCM_POS_XRUN;
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return bytes_to_frames(sub->runtime,
+ ptr = bytes_to_frames(sub->runtime,
dev->audio_out_buf_pos[index]);
else
- return bytes_to_frames(sub->runtime,
+ ptr = bytes_to_frames(sub->runtime,
dev->audio_in_buf_pos[index]);
+
+ spin_unlock(&dev->spinlock);
+ return ptr;
}
/* operators for both playback and capture */