瀏覽代碼

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>
Daniel Mack 14 年之前
父節點
當前提交
15439bde3a
共有 1 個文件被更改,包括 4 次插入2 次删除
  1. 4 2
      sound/usb/caiaq/audio.c

+ 4 - 2
sound/usb/caiaq/audio.c

@@ -614,6 +614,7 @@ static void read_completed(struct urb *urb)
 	struct snd_usb_caiaqdev *dev;
 	struct snd_usb_caiaqdev *dev;
 	struct urb *out;
 	struct urb *out;
 	int frame, len, send_it = 0, outframe = 0;
 	int frame, len, send_it = 0, outframe = 0;
+	size_t offset = 0;
 
 
 	if (urb->status || !info)
 	if (urb->status || !info)
 		return;
 		return;
@@ -634,7 +635,8 @@ static void read_completed(struct urb *urb)
 		len = urb->iso_frame_desc[outframe].actual_length;
 		len = urb->iso_frame_desc[outframe].actual_length;
 		out->iso_frame_desc[outframe].length = len;
 		out->iso_frame_desc[outframe].length = len;
 		out->iso_frame_desc[outframe].actual_length = 0;
 		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) {
 		if (len > 0) {
 			spin_lock(&dev->spinlock);
 			spin_lock(&dev->spinlock);
@@ -650,7 +652,7 @@ static void read_completed(struct urb *urb)
 	}
 	}
 
 
 	if (send_it) {
 	if (send_it) {
-		out->number_of_packets = FRAMES_PER_URB;
+		out->number_of_packets = outframe;
 		out->transfer_flags = URB_ISO_ASAP;
 		out->transfer_flags = URB_ISO_ASAP;
 		usb_submit_urb(out, GFP_ATOMIC);
 		usb_submit_urb(out, GFP_ATOMIC);
 	}
 	}