aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/pcm.c')
-rw-r--r--sound/usb/pcm.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index b375d58871e7..ca3256d6fde3 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -241,16 +241,17 @@ static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep)
241 struct snd_usb_endpoint *ep = subs->sync_endpoint; 241 struct snd_usb_endpoint *ep = subs->sync_endpoint;
242 242
243 if (subs->data_endpoint->iface != subs->sync_endpoint->iface || 243 if (subs->data_endpoint->iface != subs->sync_endpoint->iface ||
244 subs->data_endpoint->alt_idx != subs->sync_endpoint->alt_idx) { 244 subs->data_endpoint->altsetting != subs->sync_endpoint->altsetting) {
245 err = usb_set_interface(subs->dev, 245 err = usb_set_interface(subs->dev,
246 subs->sync_endpoint->iface, 246 subs->sync_endpoint->iface,
247 subs->sync_endpoint->alt_idx); 247 subs->sync_endpoint->altsetting);
248 if (err < 0) { 248 if (err < 0) {
249 clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags);
249 snd_printk(KERN_ERR 250 snd_printk(KERN_ERR
250 "%d:%d:%d: cannot set interface (%d)\n", 251 "%d:%d:%d: cannot set interface (%d)\n",
251 subs->dev->devnum, 252 subs->dev->devnum,
252 subs->sync_endpoint->iface, 253 subs->sync_endpoint->iface,
253 subs->sync_endpoint->alt_idx, err); 254 subs->sync_endpoint->altsetting, err);
254 return -EIO; 255 return -EIO;
255 } 256 }
256 } 257 }
@@ -282,22 +283,6 @@ static void stop_endpoints(struct snd_usb_substream *subs, bool wait)
282 } 283 }
283} 284}
284 285
285static int deactivate_endpoints(struct snd_usb_substream *subs)
286{
287 int reta, retb;
288
289 reta = snd_usb_endpoint_deactivate(subs->sync_endpoint);
290 retb = snd_usb_endpoint_deactivate(subs->data_endpoint);
291
292 if (reta < 0)
293 return reta;
294
295 if (retb < 0)
296 return retb;
297
298 return 0;
299}
300
301static int search_roland_implicit_fb(struct usb_device *dev, int ifnum, 286static int search_roland_implicit_fb(struct usb_device *dev, int ifnum,
302 unsigned int altsetting, 287 unsigned int altsetting,
303 struct usb_host_interface **alts, 288 struct usb_host_interface **alts,
@@ -595,6 +580,7 @@ static int configure_sync_endpoint(struct snd_usb_substream *subs)
595 subs->pcm_format, 580 subs->pcm_format,
596 subs->channels, 581 subs->channels,
597 subs->period_bytes, 582 subs->period_bytes,
583 0, 0,
598 subs->cur_rate, 584 subs->cur_rate,
599 subs->cur_audiofmt, 585 subs->cur_audiofmt,
600 NULL); 586 NULL);
@@ -631,6 +617,7 @@ static int configure_sync_endpoint(struct snd_usb_substream *subs)
631 subs->pcm_format, 617 subs->pcm_format,
632 sync_fp->channels, 618 sync_fp->channels,
633 sync_period_bytes, 619 sync_period_bytes,
620 0, 0,
634 subs->cur_rate, 621 subs->cur_rate,
635 sync_fp, 622 sync_fp,
636 NULL); 623 NULL);
@@ -653,6 +640,8 @@ static int configure_endpoint(struct snd_usb_substream *subs)
653 subs->pcm_format, 640 subs->pcm_format,
654 subs->channels, 641 subs->channels,
655 subs->period_bytes, 642 subs->period_bytes,
643 subs->period_frames,
644 subs->buffer_periods,
656 subs->cur_rate, 645 subs->cur_rate,
657 subs->cur_audiofmt, 646 subs->cur_audiofmt,
658 subs->sync_endpoint); 647 subs->sync_endpoint);
@@ -689,6 +678,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
689 678
690 subs->pcm_format = params_format(hw_params); 679 subs->pcm_format = params_format(hw_params);
691 subs->period_bytes = params_period_bytes(hw_params); 680 subs->period_bytes = params_period_bytes(hw_params);
681 subs->period_frames = params_period_size(hw_params);
682 subs->buffer_periods = params_periods(hw_params);
692 subs->channels = params_channels(hw_params); 683 subs->channels = params_channels(hw_params);
693 subs->cur_rate = params_rate(hw_params); 684 subs->cur_rate = params_rate(hw_params);
694 685
@@ -730,7 +721,8 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
730 down_read(&subs->stream->chip->shutdown_rwsem); 721 down_read(&subs->stream->chip->shutdown_rwsem);
731 if (!subs->stream->chip->shutdown) { 722 if (!subs->stream->chip->shutdown) {
732 stop_endpoints(subs, true); 723 stop_endpoints(subs, true);
733 deactivate_endpoints(subs); 724 snd_usb_endpoint_deactivate(subs->sync_endpoint);
725 snd_usb_endpoint_deactivate(subs->data_endpoint);
734 } 726 }
735 up_read(&subs->stream->chip->shutdown_rwsem); 727 up_read(&subs->stream->chip->shutdown_rwsem);
736 return snd_pcm_lib_free_vmalloc_buffer(substream); 728 return snd_pcm_lib_free_vmalloc_buffer(substream);
@@ -1363,6 +1355,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
1363 frames = 0; 1355 frames = 0;
1364 urb->number_of_packets = 0; 1356 urb->number_of_packets = 0;
1365 spin_lock_irqsave(&subs->lock, flags); 1357 spin_lock_irqsave(&subs->lock, flags);
1358 subs->frame_limit += ep->max_urb_frames;
1366 for (i = 0; i < ctx->packets; i++) { 1359 for (i = 0; i < ctx->packets; i++) {
1367 if (ctx->packet_size[i]) 1360 if (ctx->packet_size[i])
1368 counts = ctx->packet_size[i]; 1361 counts = ctx->packet_size[i];
@@ -1377,6 +1370,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
1377 subs->transfer_done += counts; 1370 subs->transfer_done += counts;
1378 if (subs->transfer_done >= runtime->period_size) { 1371 if (subs->transfer_done >= runtime->period_size) {
1379 subs->transfer_done -= runtime->period_size; 1372 subs->transfer_done -= runtime->period_size;
1373 subs->frame_limit = 0;
1380 period_elapsed = 1; 1374 period_elapsed = 1;
1381 if (subs->fmt_type == UAC_FORMAT_TYPE_II) { 1375 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
1382 if (subs->transfer_done > 0) { 1376 if (subs->transfer_done > 0) {
@@ -1399,8 +1393,10 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
1399 break; 1393 break;
1400 } 1394 }
1401 } 1395 }
1402 if (period_elapsed && 1396 /* finish at the period boundary or after enough frames */
1403 !snd_usb_endpoint_implicit_feedback_sink(subs->data_endpoint)) /* finish at the period boundary */ 1397 if ((period_elapsed ||
1398 subs->transfer_done >= subs->frame_limit) &&
1399 !snd_usb_endpoint_implicit_feedback_sink(ep))
1404 break; 1400 break;
1405 } 1401 }
1406 bytes = frames * ep->stride; 1402 bytes = frames * ep->stride;