mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 00:04:15 +08:00
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: Stephane Grosjean <s.grosjean@peak-system.com> Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
parent
6311b7ce42
commit
d8a243af1a
@ -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);
|
||||
int err = 0;
|
||||
u8 *packet_ptr;
|
||||
int i, n = 1, packet_len;
|
||||
int packet_len;
|
||||
ptrdiff_t cmd_len;
|
||||
|
||||
/* 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_len = cmd_len;
|
||||
|
||||
/* firmware is not able to re-assemble 512 bytes buffer in full-speed */
|
||||
if ((dev->udev->speed != USB_SPEED_HIGH) &&
|
||||
(cmd_len > PCAN_UFD_LOSPD_PKT_SIZE)) {
|
||||
packet_len = PCAN_UFD_LOSPD_PKT_SIZE;
|
||||
n += cmd_len / packet_len;
|
||||
} else {
|
||||
packet_len = cmd_len;
|
||||
}
|
||||
if (unlikely(dev->udev->speed != USB_SPEED_HIGH))
|
||||
packet_len = min(packet_len, PCAN_UFD_LOSPD_PKT_SIZE);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
do {
|
||||
err = usb_bulk_msg(dev->udev,
|
||||
usb_sndbulkpipe(dev->udev,
|
||||
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;
|
||||
}
|
||||
cmd_len -= packet_len;
|
||||
|
||||
if (cmd_len < PCAN_UFD_LOSPD_PKT_SIZE)
|
||||
packet_len = cmd_len;
|
||||
|
||||
} while (packet_len > 0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user