aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/caiaq/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/caiaq/audio.c')
-rw-r--r--sound/usb/caiaq/audio.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index d0d493ca28ae..2cf87f5afed4 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -139,8 +139,12 @@ static void stream_stop(struct snd_usb_caiaqdev *dev)
139 139
140 for (i = 0; i < N_URBS; i++) { 140 for (i = 0; i < N_URBS; i++) {
141 usb_kill_urb(dev->data_urbs_in[i]); 141 usb_kill_urb(dev->data_urbs_in[i]);
142 usb_kill_urb(dev->data_urbs_out[i]); 142
143 if (test_bit(i, &dev->outurb_active_mask))
144 usb_kill_urb(dev->data_urbs_out[i]);
143 } 145 }
146
147 dev->outurb_active_mask = 0;
144} 148}
145 149
146static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) 150static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream)
@@ -612,8 +616,9 @@ static void read_completed(struct urb *urb)
612{ 616{
613 struct snd_usb_caiaq_cb_info *info = urb->context; 617 struct snd_usb_caiaq_cb_info *info = urb->context;
614 struct snd_usb_caiaqdev *dev; 618 struct snd_usb_caiaqdev *dev;
615 struct urb *out; 619 struct urb *out = NULL;
616 int frame, len, send_it = 0, outframe = 0; 620 int i, frame, len, send_it = 0, outframe = 0;
621 size_t offset = 0;
617 622
618 if (urb->status || !info) 623 if (urb->status || !info)
619 return; 624 return;
@@ -623,7 +628,17 @@ static void read_completed(struct urb *urb)
623 if (!dev->streaming) 628 if (!dev->streaming)
624 return; 629 return;
625 630
626 out = dev->data_urbs_out[info->index]; 631 /* find an unused output urb that is unused */
632 for (i = 0; i < N_URBS; i++)
633 if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) {
634 out = dev->data_urbs_out[i];
635 break;
636 }
637
638 if (!out) {
639 log("Unable to find an output urb to use\n");
640 goto requeue;
641 }
627 642
628 /* read the recently received packet and send back one which has 643 /* read the recently received packet and send back one which has
629 * the same layout */ 644 * the same layout */
@@ -634,7 +649,8 @@ static void read_completed(struct urb *urb)
634 len = urb->iso_frame_desc[outframe].actual_length; 649 len = urb->iso_frame_desc[outframe].actual_length;
635 out->iso_frame_desc[outframe].length = len; 650 out->iso_frame_desc[outframe].length = len;
636 out->iso_frame_desc[outframe].actual_length = 0; 651 out->iso_frame_desc[outframe].actual_length = 0;
637 out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame; 652 out->iso_frame_desc[outframe].offset = offset;
653 offset += len;
638 654
639 if (len > 0) { 655 if (len > 0) {
640 spin_lock(&dev->spinlock); 656 spin_lock(&dev->spinlock);
@@ -650,11 +666,15 @@ static void read_completed(struct urb *urb)
650 } 666 }
651 667
652 if (send_it) { 668 if (send_it) {
653 out->number_of_packets = FRAMES_PER_URB; 669 out->number_of_packets = outframe;
654 out->transfer_flags = URB_ISO_ASAP; 670 out->transfer_flags = URB_ISO_ASAP;
655 usb_submit_urb(out, GFP_ATOMIC); 671 usb_submit_urb(out, GFP_ATOMIC);
672 } else {
673 struct snd_usb_caiaq_cb_info *oinfo = out->context;
674 clear_bit(oinfo->index, &dev->outurb_active_mask);
656 } 675 }
657 676
677requeue:
658 /* re-submit inbound urb */ 678 /* re-submit inbound urb */
659 for (frame = 0; frame < FRAMES_PER_URB; frame++) { 679 for (frame = 0; frame < FRAMES_PER_URB; frame++) {
660 urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; 680 urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame;
@@ -676,6 +696,8 @@ static void write_completed(struct urb *urb)
676 dev->output_running = 1; 696 dev->output_running = 1;
677 wake_up(&dev->prepare_wait_queue); 697 wake_up(&dev->prepare_wait_queue);
678 } 698 }
699
700 clear_bit(info->index, &dev->outurb_active_mask);
679} 701}
680 702
681static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) 703static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
@@ -827,6 +849,9 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
827 if (!dev->data_cb_info) 849 if (!dev->data_cb_info)
828 return -ENOMEM; 850 return -ENOMEM;
829 851
852 dev->outurb_active_mask = 0;
853 BUILD_BUG_ON(N_URBS > (sizeof(dev->outurb_active_mask) * 8));
854
830 for (i = 0; i < N_URBS; i++) { 855 for (i = 0; i < N_URBS; i++) {
831 dev->data_cb_info[i].dev = dev; 856 dev->data_cb_info[i].dev = dev;
832 dev->data_cb_info[i].index = i; 857 dev->data_cb_info[i].index = i;