aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/line6/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/line6/pcm.c')
-rw-r--r--sound/usb/line6/pcm.c443
1 files changed, 272 insertions, 171 deletions
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index 8a6059adef69..8461d6bf992f 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -45,15 +45,22 @@ static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol,
45{ 45{
46 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 46 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
47 int value = ucontrol->value.integer.value[0]; 47 int value = ucontrol->value.integer.value[0];
48 int err;
48 49
49 if (line6pcm->impulse_volume == value) 50 if (line6pcm->impulse_volume == value)
50 return 0; 51 return 0;
51 52
52 line6pcm->impulse_volume = value; 53 line6pcm->impulse_volume = value;
53 if (value > 0) 54 if (value > 0) {
54 line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE); 55 err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE);
55 else 56 if (err < 0) {
56 line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE); 57 line6pcm->impulse_volume = 0;
58 line6_pcm_release(line6pcm, LINE6_STREAM_IMPULSE);
59 return err;
60 }
61 } else {
62 line6_pcm_release(line6pcm, LINE6_STREAM_IMPULSE);
63 }
57 return 1; 64 return 1;
58} 65}
59 66
@@ -90,180 +97,277 @@ static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol,
90 return 1; 97 return 1;
91} 98}
92 99
93static bool test_flags(unsigned long flags0, unsigned long flags1, 100/*
94 unsigned long mask) 101 Unlink all currently active URBs.
95{ 102*/
96 return ((flags0 & mask) == 0) && ((flags1 & mask) != 0); 103static void line6_unlink_audio_urbs(struct snd_line6_pcm *line6pcm,
97} 104 struct line6_pcm_stream *pcms)
98
99int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
100{ 105{
101 unsigned long flags_old, flags_new, flags_final; 106 int i;
102 int err;
103
104 do {
105 flags_old = ACCESS_ONCE(line6pcm->flags);
106 flags_new = flags_old | channels;
107 } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
108
109 flags_final = flags_old;
110
111 line6pcm->prev_fbuf = NULL;
112
113 if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) {
114 /* Invoked multiple times in a row so allocate once only */
115 if (!line6pcm->buffer_in) {
116 line6pcm->buffer_in =
117 kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
118 line6pcm->max_packet_size, GFP_KERNEL);
119 if (!line6pcm->buffer_in) {
120 err = -ENOMEM;
121 goto pcm_acquire_error;
122 }
123
124 flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;
125 }
126 }
127 107
128 if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) { 108 for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
129 /* 109 if (test_bit(i, &pcms->active_urbs)) {
130 Waiting for completion of active URBs in the stop handler is 110 if (!test_and_set_bit(i, &pcms->unlink_urbs))
131 a bug, we therefore report an error if capturing is restarted 111 usb_unlink_urb(pcms->urbs[i]);
132 too soon.
133 */
134 if (line6pcm->active_urb_in | line6pcm->unlink_urb_in) {
135 dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
136 return -EBUSY;
137 } 112 }
138
139 line6pcm->count_in = 0;
140 line6pcm->prev_fsize = 0;
141 err = line6_submit_audio_in_all_urbs(line6pcm);
142
143 if (err < 0)
144 goto pcm_acquire_error;
145
146 flags_final |= channels & LINE6_BITS_CAPTURE_STREAM;
147 } 113 }
114}
148 115
149 if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) { 116/*
150 /* Invoked multiple times in a row so allocate once only */ 117 Wait until unlinking of all currently active URBs has been finished.
151 if (!line6pcm->buffer_out) { 118*/
152 line6pcm->buffer_out = 119static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm,
153 kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * 120 struct line6_pcm_stream *pcms)
154 line6pcm->max_packet_size, GFP_KERNEL); 121{
155 if (!line6pcm->buffer_out) { 122 int timeout = HZ;
156 err = -ENOMEM; 123 int i;
157 goto pcm_acquire_error; 124 int alive;
158 }
159
160 flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;
161 }
162 }
163 125
164 if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) { 126 do {
165 /* 127 alive = 0;
166 See comment above regarding PCM restart. 128 for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
167 */ 129 if (test_bit(i, &pcms->active_urbs))
168 if (line6pcm->active_urb_out | line6pcm->unlink_urb_out) { 130 alive++;
169 dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
170 return -EBUSY;
171 } 131 }
132 if (!alive)
133 break;
134 set_current_state(TASK_UNINTERRUPTIBLE);
135 schedule_timeout(1);
136 } while (--timeout > 0);
137 if (alive)
138 dev_err(line6pcm->line6->ifcdev,
139 "timeout: still %d active urbs..\n", alive);
140}
172 141
173 line6pcm->count_out = 0; 142static inline struct line6_pcm_stream *
174 err = line6_submit_audio_out_all_urbs(line6pcm); 143get_stream(struct snd_line6_pcm *line6pcm, int direction)
175 144{
176 if (err < 0) 145 return (direction == SNDRV_PCM_STREAM_PLAYBACK) ?
177 goto pcm_acquire_error; 146 &line6pcm->out : &line6pcm->in;
147}
178 148
179 flags_final |= channels & LINE6_BITS_PLAYBACK_STREAM; 149/* allocate a buffer if not opened yet;
150 * call this in line6pcm.state_change mutex
151 */
152static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm,
153 struct line6_pcm_stream *pstr, int type)
154{
155 /* Invoked multiple times in a row so allocate once only */
156 if (!test_and_set_bit(type, &pstr->opened) && !pstr->buffer) {
157 pstr->buffer = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
158 line6pcm->max_packet_size, GFP_KERNEL);
159 if (!pstr->buffer)
160 return -ENOMEM;
180 } 161 }
181
182 return 0; 162 return 0;
183
184pcm_acquire_error:
185 /*
186 If not all requested resources/streams could be obtained, release
187 those which were successfully obtained (if any).
188 */
189 line6_pcm_release(line6pcm, flags_final & channels);
190 return err;
191} 163}
192EXPORT_SYMBOL_GPL(line6_pcm_acquire);
193 164
194int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels) 165/* free a buffer if all streams are closed;
166 * call this in line6pcm.state_change mutex
167 */
168static void line6_buffer_release(struct snd_line6_pcm *line6pcm,
169 struct line6_pcm_stream *pstr, int type)
195{ 170{
196 unsigned long flags_old, flags_new;
197
198 do {
199 flags_old = ACCESS_ONCE(line6pcm->flags);
200 flags_new = flags_old & ~channels;
201 } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
202 171
203 if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM)) 172 clear_bit(type, &pstr->opened);
204 line6_unlink_audio_in_urbs(line6pcm); 173 if (!pstr->opened) {
205 174 line6_wait_clear_audio_urbs(line6pcm, pstr);
206 if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) { 175 kfree(pstr->buffer);
207 line6_wait_clear_audio_in_urbs(line6pcm); 176 pstr->buffer = NULL;
208 line6_free_capture_buffer(line6pcm);
209 } 177 }
178}
210 179
211 if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM)) 180/* start a PCM stream */
212 line6_unlink_audio_out_urbs(line6pcm); 181static int line6_stream_start(struct snd_line6_pcm *line6pcm, int direction,
182 int type)
183{
184 unsigned long flags;
185 struct line6_pcm_stream *pstr = get_stream(line6pcm, direction);
186 int ret = 0;
187
188 spin_lock_irqsave(&pstr->lock, flags);
189 if (!test_and_set_bit(type, &pstr->running)) {
190 if (pstr->active_urbs || pstr->unlink_urbs) {
191 ret = -EBUSY;
192 goto error;
193 }
213 194
214 if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) { 195 pstr->count = 0;
215 line6_wait_clear_audio_out_urbs(line6pcm); 196 /* Submit all currently available URBs */
216 line6_free_playback_buffer(line6pcm); 197 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
198 ret = line6_submit_audio_out_all_urbs(line6pcm);
199 else
200 ret = line6_submit_audio_in_all_urbs(line6pcm);
217 } 201 }
202 error:
203 if (ret < 0)
204 clear_bit(type, &pstr->running);
205 spin_unlock_irqrestore(&pstr->lock, flags);
206 return ret;
207}
218 208
219 return 0; 209/* stop a PCM stream; this doesn't sync with the unlinked URBs */
210static void line6_stream_stop(struct snd_line6_pcm *line6pcm, int direction,
211 int type)
212{
213 unsigned long flags;
214 struct line6_pcm_stream *pstr = get_stream(line6pcm, direction);
215
216 spin_lock_irqsave(&pstr->lock, flags);
217 clear_bit(type, &pstr->running);
218 if (!pstr->running) {
219 line6_unlink_audio_urbs(line6pcm, pstr);
220 if (direction == SNDRV_PCM_STREAM_CAPTURE) {
221 line6pcm->prev_fbuf = NULL;
222 line6pcm->prev_fsize = 0;
223 }
224 }
225 spin_unlock_irqrestore(&pstr->lock, flags);
220} 226}
221EXPORT_SYMBOL_GPL(line6_pcm_release);
222 227
223/* trigger callback */ 228/* common PCM trigger callback */
224int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) 229int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
225{ 230{
226 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 231 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
227 struct snd_pcm_substream *s; 232 struct snd_pcm_substream *s;
228 int err; 233 int err;
229 234
230 spin_lock(&line6pcm->lock_trigger); 235 clear_bit(LINE6_FLAG_PREPARED, &line6pcm->flags);
231 clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags);
232 236
233 snd_pcm_group_for_each_entry(s, substream) { 237 snd_pcm_group_for_each_entry(s, substream) {
234 if (s->pcm->card != substream->pcm->card) 238 if (s->pcm->card != substream->pcm->card)
235 continue; 239 continue;
236 switch (s->stream) {
237 case SNDRV_PCM_STREAM_PLAYBACK:
238 err = snd_line6_playback_trigger(line6pcm, cmd);
239 240
240 if (err < 0) { 241 switch (cmd) {
241 spin_unlock(&line6pcm->lock_trigger); 242 case SNDRV_PCM_TRIGGER_START:
243 case SNDRV_PCM_TRIGGER_RESUME:
244 err = line6_stream_start(line6pcm, s->stream,
245 LINE6_STREAM_PCM);
246 if (err < 0)
242 return err; 247 return err;
243 }
244
245 break; 248 break;
246 249
247 case SNDRV_PCM_STREAM_CAPTURE: 250 case SNDRV_PCM_TRIGGER_STOP:
248 err = snd_line6_capture_trigger(line6pcm, cmd); 251 case SNDRV_PCM_TRIGGER_SUSPEND:
252 line6_stream_stop(line6pcm, s->stream,
253 LINE6_STREAM_PCM);
254 break;
249 255
250 if (err < 0) { 256 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
251 spin_unlock(&line6pcm->lock_trigger); 257 if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
252 return err; 258 return -EINVAL;
253 } 259 set_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags);
260 break;
254 261
262 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
263 if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
264 return -EINVAL;
265 clear_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags);
255 break; 266 break;
256 267
257 default: 268 default:
258 dev_err(line6pcm->line6->ifcdev, 269 return -EINVAL;
259 "Unknown stream direction %d\n", s->stream);
260 } 270 }
261 } 271 }
262 272
263 spin_unlock(&line6pcm->lock_trigger);
264 return 0; 273 return 0;
265} 274}
266 275
276/* common PCM pointer callback */
277snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream)
278{
279 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
280 struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
281
282 return pstr->pos_done;
283}
284
285/* Acquire and start duplex streams:
286 * type is either LINE6_STREAM_IMPULSE or LINE6_STREAM_MONITOR
287 */
288int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type)
289{
290 struct line6_pcm_stream *pstr;
291 int ret = 0, dir;
292
293 mutex_lock(&line6pcm->state_mutex);
294 for (dir = 0; dir < 2; dir++) {
295 pstr = get_stream(line6pcm, dir);
296 ret = line6_buffer_acquire(line6pcm, pstr, type);
297 if (ret < 0)
298 goto error;
299 if (!pstr->running)
300 line6_wait_clear_audio_urbs(line6pcm, pstr);
301 }
302 for (dir = 0; dir < 2; dir++) {
303 ret = line6_stream_start(line6pcm, dir, type);
304 if (ret < 0)
305 goto error;
306 }
307 error:
308 mutex_unlock(&line6pcm->state_mutex);
309 if (ret < 0)
310 line6_pcm_release(line6pcm, type);
311 return ret;
312}
313EXPORT_SYMBOL_GPL(line6_pcm_acquire);
314
315/* Stop and release duplex streams */
316void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type)
317{
318 struct line6_pcm_stream *pstr;
319 int dir;
320
321 mutex_lock(&line6pcm->state_mutex);
322 for (dir = 0; dir < 2; dir++)
323 line6_stream_stop(line6pcm, dir, type);
324 for (dir = 0; dir < 2; dir++) {
325 pstr = get_stream(line6pcm, dir);
326 line6_buffer_release(line6pcm, pstr, type);
327 }
328 mutex_unlock(&line6pcm->state_mutex);
329}
330EXPORT_SYMBOL_GPL(line6_pcm_release);
331
332/* common PCM hw_params callback */
333int snd_line6_hw_params(struct snd_pcm_substream *substream,
334 struct snd_pcm_hw_params *hw_params)
335{
336 int ret;
337 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
338 struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
339
340 mutex_lock(&line6pcm->state_mutex);
341 ret = line6_buffer_acquire(line6pcm, pstr, LINE6_STREAM_PCM);
342 if (ret < 0)
343 goto error;
344
345 ret = snd_pcm_lib_malloc_pages(substream,
346 params_buffer_bytes(hw_params));
347 if (ret < 0) {
348 line6_buffer_release(line6pcm, pstr, LINE6_STREAM_PCM);
349 goto error;
350 }
351
352 pstr->period = params_period_bytes(hw_params);
353 error:
354 mutex_unlock(&line6pcm->state_mutex);
355 return ret;
356}
357
358/* common PCM hw_free callback */
359int snd_line6_hw_free(struct snd_pcm_substream *substream)
360{
361 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
362 struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
363
364 mutex_lock(&line6pcm->state_mutex);
365 line6_buffer_release(line6pcm, pstr, LINE6_STREAM_PCM);
366 mutex_unlock(&line6pcm->state_mutex);
367 return snd_pcm_lib_free_pages(substream);
368}
369
370
267/* control info callback */ 371/* control info callback */
268static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol, 372static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_info *uinfo) 373 struct snd_ctl_elem_info *uinfo)
@@ -282,7 +386,7 @@ static int snd_line6_control_playback_get(struct snd_kcontrol *kcontrol,
282 int i; 386 int i;
283 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 387 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
284 388
285 for (i = 2; i--;) 389 for (i = 0; i < 2; i++)
286 ucontrol->value.integer.value[i] = line6pcm->volume_playback[i]; 390 ucontrol->value.integer.value[i] = line6pcm->volume_playback[i];
287 391
288 return 0; 392 return 0;
@@ -295,7 +399,7 @@ static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
295 int i, changed = 0; 399 int i, changed = 0;
296 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 400 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
297 401
298 for (i = 2; i--;) 402 for (i = 0; i < 2; i++)
299 if (line6pcm->volume_playback[i] != 403 if (line6pcm->volume_playback[i] !=
300 ucontrol->value.integer.value[i]) { 404 ucontrol->value.integer.value[i]) {
301 line6pcm->volume_playback[i] = 405 line6pcm->volume_playback[i] =
@@ -334,21 +438,24 @@ static struct snd_kcontrol_new line6_controls[] = {
334/* 438/*
335 Cleanup the PCM device. 439 Cleanup the PCM device.
336*/ 440*/
337static void line6_cleanup_pcm(struct snd_pcm *pcm) 441static void cleanup_urbs(struct line6_pcm_stream *pcms)
338{ 442{
339 int i; 443 int i;
340 struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
341 444
342 for (i = LINE6_ISO_BUFFERS; i--;) { 445 for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
343 if (line6pcm->urb_audio_out[i]) { 446 if (pcms->urbs[i]) {
344 usb_kill_urb(line6pcm->urb_audio_out[i]); 447 usb_kill_urb(pcms->urbs[i]);
345 usb_free_urb(line6pcm->urb_audio_out[i]); 448 usb_free_urb(pcms->urbs[i]);
346 }
347 if (line6pcm->urb_audio_in[i]) {
348 usb_kill_urb(line6pcm->urb_audio_in[i]);
349 usb_free_urb(line6pcm->urb_audio_in[i]);
350 } 449 }
351 } 450 }
451}
452
453static void line6_cleanup_pcm(struct snd_pcm *pcm)
454{
455 struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
456
457 cleanup_urbs(&line6pcm->out);
458 cleanup_urbs(&line6pcm->in);
352 kfree(line6pcm); 459 kfree(line6pcm);
353} 460}
354 461
@@ -383,8 +490,10 @@ static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret)
383*/ 490*/
384void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm) 491void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
385{ 492{
386 line6_unlink_wait_clear_audio_out_urbs(line6pcm); 493 line6_unlink_audio_urbs(line6pcm, &line6pcm->out);
387 line6_unlink_wait_clear_audio_in_urbs(line6pcm); 494 line6_unlink_audio_urbs(line6pcm, &line6pcm->in);
495 line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out);
496 line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in);
388} 497}
389 498
390/* 499/*
@@ -411,6 +520,7 @@ int line6_init_pcm(struct usb_line6 *line6,
411 if (!line6pcm) 520 if (!line6pcm)
412 return -ENOMEM; 521 return -ENOMEM;
413 522
523 mutex_init(&line6pcm->state_mutex);
414 line6pcm->pcm = pcm; 524 line6pcm->pcm = pcm;
415 line6pcm->properties = properties; 525 line6pcm->properties = properties;
416 line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255; 526 line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255;
@@ -424,9 +534,8 @@ int line6_init_pcm(struct usb_line6 *line6,
424 usb_maxpacket(line6->usbdev, 534 usb_maxpacket(line6->usbdev,
425 usb_sndisocpipe(line6->usbdev, ep_write), 1)); 535 usb_sndisocpipe(line6->usbdev, ep_write), 1));
426 536
427 spin_lock_init(&line6pcm->lock_audio_out); 537 spin_lock_init(&line6pcm->out.lock);
428 spin_lock_init(&line6pcm->lock_audio_in); 538 spin_lock_init(&line6pcm->in.lock);
429 spin_lock_init(&line6pcm->lock_trigger);
430 line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; 539 line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
431 540
432 line6->line6pcm = line6pcm; 541 line6->line6pcm = line6pcm;
@@ -458,30 +567,22 @@ EXPORT_SYMBOL_GPL(line6_init_pcm);
458int snd_line6_prepare(struct snd_pcm_substream *substream) 567int snd_line6_prepare(struct snd_pcm_substream *substream)
459{ 568{
460 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 569 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
461 570 struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
462 switch (substream->stream) { 571
463 case SNDRV_PCM_STREAM_PLAYBACK: 572 mutex_lock(&line6pcm->state_mutex);
464 if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0) 573 if (!pstr->running)
465 line6_unlink_wait_clear_audio_out_urbs(line6pcm); 574 line6_wait_clear_audio_urbs(line6pcm, pstr);
466 575
467 break; 576 if (!test_and_set_bit(LINE6_FLAG_PREPARED, &line6pcm->flags)) {
468 577 line6pcm->out.count = 0;
469 case SNDRV_PCM_STREAM_CAPTURE: 578 line6pcm->out.pos = 0;
470 if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0) 579 line6pcm->out.pos_done = 0;
471 line6_unlink_wait_clear_audio_in_urbs(line6pcm); 580 line6pcm->out.bytes = 0;
472 581 line6pcm->in.count = 0;
473 break; 582 line6pcm->in.pos_done = 0;
474 } 583 line6pcm->in.bytes = 0;
475
476 if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) {
477 line6pcm->count_out = 0;
478 line6pcm->pos_out = 0;
479 line6pcm->pos_out_done = 0;
480 line6pcm->bytes_out = 0;
481 line6pcm->count_in = 0;
482 line6pcm->pos_in_done = 0;
483 line6pcm->bytes_in = 0;
484 } 584 }
485 585
586 mutex_unlock(&line6pcm->state_mutex);
486 return 0; 587 return 0;
487} 588}