aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-01-23 08:34:42 -0500
committerTakashi Iwai <tiwai@suse.de>2015-01-28 01:20:53 -0500
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)
106 flags_new = flags_old | channels; 106 flags_new = flags_old | channels;
107 } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); 107 } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
108 108
109 flags_final = flags_old; 109 flags_final = 0;
110 110
111 line6pcm->prev_fbuf = NULL; 111 line6pcm->prev_fbuf = NULL;
112 112
@@ -120,9 +120,9 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
120 err = -ENOMEM; 120 err = -ENOMEM;
121 goto pcm_acquire_error; 121 goto pcm_acquire_error;
122 } 122 }
123
124 flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;
125 } 123 }
124
125 flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;
126 } 126 }
127 127
128 if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) { 128 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)
157 err = -ENOMEM; 157 err = -ENOMEM;
158 goto pcm_acquire_error; 158 goto pcm_acquire_error;
159 } 159 }
160
161 flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;
162 } 160 }
161
162 flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;
163 } 163 }
164 164
165 if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) { 165 if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) {
@@ -187,7 +187,7 @@ pcm_acquire_error:
187 If not all requested resources/streams could be obtained, release 187 If not all requested resources/streams could be obtained, release
188 those which were successfully obtained (if any). 188 those which were successfully obtained (if any).
189 */ 189 */
190 line6_pcm_release(line6pcm, flags_final & channels); 190 line6_pcm_release(line6pcm, flags_final);
191 return err; 191 return err;
192} 192}
193EXPORT_SYMBOL_GPL(line6_pcm_acquire); 193EXPORT_SYMBOL_GPL(line6_pcm_acquire);