diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-01-27 10:17:26 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-01-28 01:22:30 -0500 |
commit | f2bb614bb6c7f5245521195f144272ef93d9f086 (patch) | |
tree | 2e491dc66f9805f1872e2c7a141dc38da30f4d81 /sound/usb | |
parent | 3d3ae4454deb94bbad9ad0b2b559cbf6c0db4ec2 (diff) |
ALSA: line6: Clear prev_fbuf and prev_fsize properly
Clearing prev_fsize in line6_pcm_acquire() is pretty racy.
This can be called at any time while the stream is being played.
Rather better to clear prev_fbuf and prev_fsize at the proper place
like the stream stop for capture, and just after copying the monitor /
impulse data inside the spinlock.
Tested-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/line6/pcm.c | 8 | ||||
-rw-r--r-- | sound/usb/line6/playback.c | 6 |
2 files changed, 7 insertions, 7 deletions
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index f75825995e24..dedbe24cbf60 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c | |||
@@ -171,8 +171,6 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) | |||
171 | 171 | ||
172 | flags_final = 0; | 172 | flags_final = 0; |
173 | 173 | ||
174 | line6pcm->prev_fbuf = NULL; | ||
175 | |||
176 | if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { | 174 | if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { |
177 | err = line6_alloc_stream_buffer(line6pcm, &line6pcm->in); | 175 | err = line6_alloc_stream_buffer(line6pcm, &line6pcm->in); |
178 | if (err < 0) | 176 | if (err < 0) |
@@ -193,7 +191,6 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) | |||
193 | } | 191 | } |
194 | 192 | ||
195 | line6pcm->in.count = 0; | 193 | line6pcm->in.count = 0; |
196 | line6pcm->prev_fsize = 0; | ||
197 | err = line6_submit_audio_in_all_urbs(line6pcm); | 194 | err = line6_submit_audio_in_all_urbs(line6pcm); |
198 | 195 | ||
199 | if (err < 0) | 196 | if (err < 0) |
@@ -248,8 +245,11 @@ int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels) | |||
248 | flags_new = flags_old & ~channels; | 245 | flags_new = flags_old & ~channels; |
249 | } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); | 246 | } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); |
250 | 247 | ||
251 | if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM)) | 248 | if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM)) { |
252 | line6_unlink_audio_urbs(line6pcm, &line6pcm->in); | 249 | line6_unlink_audio_urbs(line6pcm, &line6pcm->in); |
250 | line6pcm->prev_fbuf = NULL; | ||
251 | line6pcm->prev_fsize = 0; | ||
252 | } | ||
253 | 253 | ||
254 | if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) { | 254 | if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) { |
255 | line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in); | 255 | line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in); |
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index b4a26d0c8267..242265929145 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c | |||
@@ -166,9 +166,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
166 | struct usb_iso_packet_descriptor *fout = | 166 | struct usb_iso_packet_descriptor *fout = |
167 | &urb_out->iso_frame_desc[i]; | 167 | &urb_out->iso_frame_desc[i]; |
168 | 168 | ||
169 | if (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) | 169 | fsize = line6pcm->prev_fsize; |
170 | fsize = line6pcm->prev_fsize; | ||
171 | |||
172 | if (fsize == 0) { | 170 | if (fsize == 0) { |
173 | int n; | 171 | int n; |
174 | 172 | ||
@@ -263,6 +261,8 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
263 | line6pcm->volume_monitor, | 261 | line6pcm->volume_monitor, |
264 | bytes_per_frame); | 262 | bytes_per_frame); |
265 | } | 263 | } |
264 | line6pcm->prev_fbuf = NULL; | ||
265 | line6pcm->prev_fsize = 0; | ||
266 | } | 266 | } |
267 | spin_unlock(&line6pcm->in.lock); | 267 | spin_unlock(&line6pcm->in.lock); |
268 | 268 | ||