Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15439bde authored by Daniel Mack's avatar Daniel Mack Committed by Takashi Iwai
Browse files

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: default avatarDaniel Mack <zonque@gmail.com>
Reported-and-tested-by: default avatarWilliam Light <wrl@illest.net>
Reported-by: default avatarPedro Ribeiro <pedrib@gmail.com>
Cc: stable@kernel.org
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent a5a3973d
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -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);
	}
	}