aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2011-08-05 13:49:52 +0200
committerTakashi Iwai <tiwai@suse.de>2011-08-10 20:05:47 +0200
commit15439bde3af7ff88459ea2b5520b77312e958df2 (patch)
tree89430da374b8f97f70900285b116f01b0f0bdefd /sound/usb
parenta5a3973da8b52944bc5909852714e55771c31ce7 (diff)
downloadkernel_samsung_smdk4412-15439bde3af7ff88459ea2b5520b77312e958df2.zip
kernel_samsung_smdk4412-15439bde3af7ff88459ea2b5520b77312e958df2.tar.gz
kernel_samsung_smdk4412-15439bde3af7ff88459ea2b5520b77312e958df2.tar.bz2
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 d0d493c..aa52b3e 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -614,6 +614,7 @@ static void read_completed(struct urb *urb)
struct snd_usb_caiaqdev *dev;
struct urb *out;
int frame, len, send_it = 0, outframe = 0;
+ size_t offset = 0;
if (urb->status || !info)
return;
@@ -634,7 +635,8 @@ static void read_completed(struct urb *urb)
len = urb->iso_frame_desc[outframe].actual_length;
out->iso_frame_desc[outframe].length = len;
out->iso_frame_desc[outframe].actual_length = 0;
- out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame;
+ out->iso_frame_desc[outframe].offset = offset;
+ offset += len;
if (len > 0) {
spin_lock(&dev->spinlock);
@@ -650,7 +652,7 @@ static void read_completed(struct urb *urb)
}
if (send_it) {
- out->number_of_packets = FRAMES_PER_URB;
+ out->number_of_packets = outframe;
out->transfer_flags = URB_ISO_ASAP;
usb_submit_urb(out, GFP_ATOMIC);
}