summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-01-23 14:34:42 +0100
committerTakashi Iwai <tiwai@suse.de>2015-01-28 07:20:53 +0100
commit5343ecf4e5c94aecdd6a859b76c125c3544865d1 (patch)
tree65b7e343e00c4cca5e5ecce0a0d7deffd9c62368
parent6aa7f8ef293f27215f685b2f94e980c7f3a337d5 (diff)
ALSA: line6: Fix the error recovery in line6_pcm_acquire()
line6_pcm_acquire() tries to restore the newly obtained resources at the error path. But some flags aren't recorded and released properly when the corresponding buffer is already present. These bits have to be cleared in the error recovery, too. Also, "flags_final" can be initialized to zero since we pass only the subset of "channels" bits. Tested-by: Chris Rorvick <chris@rorvick.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/usb/line6/pcm.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index f740b4490d75..9a2a15f4c4e4 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -106,7 +106,7 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
flags_new = flags_old | channels;
} while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
- flags_final = flags_old;
+ flags_final = 0;
line6pcm->prev_fbuf = NULL;
@@ -120,9 +120,9 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
err = -ENOMEM;
goto pcm_acquire_error;
}
-
- flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;
}
+
+ flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;
}
if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) {
@@ -157,9 +157,9 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
err = -ENOMEM;
goto pcm_acquire_error;
}
-
- flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;
}
+
+ flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;
}
if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) {
@@ -187,7 +187,7 @@ pcm_acquire_error:
If not all requested resources/streams could be obtained, release
those which were successfully obtained (if any).
*/
- line6_pcm_release(line6pcm, flags_final & channels);
+ line6_pcm_release(line6pcm, flags_final);
return err;
}
EXPORT_SYMBOL_GPL(line6_pcm_acquire);