aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2011-08-05 07:49:52 -0400
committerTakashi Iwai <tiwai@suse.de>2011-08-10 14:05:47 -0400
commit15439bde3af7ff88459ea2b5520b77312e958df2 (patch)
tree89430da374b8f97f70900285b116f01b0f0bdefd /sound/usb
parenta5a3973da8b52944bc5909852714e55771c31ce7 (diff)
ALSA: snd-usb-caiaq: Correct offset fields of outbound iso_frame_desc
This fixes faulty outbount packets in case the inbound packets received from the hardware are fragmented and contain bogus input iso frames. The bug has been there for ages, but for some strange reasons, it was only triggered by newer machines in 64bit mode. Signed-off-by: Daniel Mack <zonque@gmail.com> Reported-and-tested-by: William Light <wrl@illest.net> Reported-by: Pedro Ribeiro <pedrib@gmail.com> Cc: stable@kernel.org Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/caiaq/audio.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index d0d493ca28ae..aa52b3e13bb5 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -614,6 +614,7 @@ static void read_completed(struct urb *urb)
614 struct snd_usb_caiaqdev *dev; 614 struct snd_usb_caiaqdev *dev;
615 struct urb *out; 615 struct urb *out;
616 int frame, len, send_it = 0, outframe = 0; 616 int frame, len, send_it = 0, outframe = 0;
617 size_t offset = 0;
617 618
618 if (urb->status || !info) 619 if (urb->status || !info)
619 return; 620 return;
@@ -634,7 +635,8 @@ static void read_completed(struct urb *urb)
634 len = urb->iso_frame_desc[outframe].actual_length; 635 len = urb->iso_frame_desc[outframe].actual_length;
635 out->iso_frame_desc[outframe].length = len; 636 out->iso_frame_desc[outframe].length = len;
636 out->iso_frame_desc[outframe].actual_length = 0; 637 out->iso_frame_desc[outframe].actual_length = 0;
637 out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame; 638 out->iso_frame_desc[outframe].offset = offset;
639 offset += len;
638 640
639 if (len > 0) { 641 if (len > 0) {
640 spin_lock(&dev->spinlock); 642 spin_lock(&dev->spinlock);
@@ -650,7 +652,7 @@ static void read_completed(struct urb *urb)
650 } 652 }
651 653
652 if (send_it) { 654 if (send_it) {
653 out->number_of_packets = FRAMES_PER_URB; 655 out->number_of_packets = outframe;
654 out->transfer_flags = URB_ISO_ASAP; 656 out->transfer_flags = URB_ISO_ASAP;
655 usb_submit_urb(out, GFP_ATOMIC); 657 usb_submit_urb(out, GFP_ATOMIC);
656 } 658 }