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

Commit d8a243af authored by Stephane Grosjean's avatar Stephane Grosjean Committed by Marc Kleine-Budde
Browse files

can: peak: fix potential bug in packet fragmentation



In some rare conditions when running one PEAK USB-FD interface over
a non high-speed USB controller, one useless USB fragment might be sent.
This patch fixes the way a USB command is fragmented when its length is
greater than 64 bytes and when the underlying USB controller is not a
high-speed one.

Signed-off-by: default avatarStephane Grosjean <s.grosjean@peak-system.com>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 6311b7ce
Loading
Loading
Loading
Loading
+11 −10
Original line number Original line Diff line number Diff line
@@ -184,7 +184,7 @@ static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
	void *cmd_head = pcan_usb_fd_cmd_buffer(dev);
	void *cmd_head = pcan_usb_fd_cmd_buffer(dev);
	int err = 0;
	int err = 0;
	u8 *packet_ptr;
	u8 *packet_ptr;
	int i, n = 1, packet_len;
	int packet_len;
	ptrdiff_t cmd_len;
	ptrdiff_t cmd_len;


	/* usb device unregistered? */
	/* usb device unregistered? */
@@ -201,17 +201,13 @@ static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
	}
	}


	packet_ptr = cmd_head;
	packet_ptr = cmd_head;
	packet_len = cmd_len;


	/* firmware is not able to re-assemble 512 bytes buffer in full-speed */
	/* firmware is not able to re-assemble 512 bytes buffer in full-speed */
	if ((dev->udev->speed != USB_SPEED_HIGH) &&
	if (unlikely(dev->udev->speed != USB_SPEED_HIGH))
	    (cmd_len > PCAN_UFD_LOSPD_PKT_SIZE)) {
		packet_len = min(packet_len, PCAN_UFD_LOSPD_PKT_SIZE);
		packet_len = PCAN_UFD_LOSPD_PKT_SIZE;
		n += cmd_len / packet_len;
	} else {
		packet_len = cmd_len;
	}


	for (i = 0; i < n; i++) {
	do {
		err = usb_bulk_msg(dev->udev,
		err = usb_bulk_msg(dev->udev,
				   usb_sndbulkpipe(dev->udev,
				   usb_sndbulkpipe(dev->udev,
						   PCAN_USBPRO_EP_CMDOUT),
						   PCAN_USBPRO_EP_CMDOUT),
@@ -224,7 +220,12 @@ static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
		}
		}


		packet_ptr += packet_len;
		packet_ptr += packet_len;
	}
		cmd_len -= packet_len;

		if (cmd_len < PCAN_UFD_LOSPD_PKT_SIZE)
			packet_len = cmd_len;

	} while (packet_len > 0);


	return err;
	return err;
}
}