From 53eec620bbb8912c9a0c6e608290d1b778ca284d Mon Sep 17 00:00:00 2001
From: Jonathan Bell <jonathan@raspberrypi.com>
Date: Wed, 11 Jun 2025 15:52:40 +0100
Subject: [PATCH] usb: dwc2: limit "maximum packet size" for split-IN transfers

dwc2_hc_start_transfer() overwrites hc->xfer_len for split-IN transfers.
Drivers may not allocate buffers that are multiples of the endpoint max
packet size, which may cause buffer overruns in the last transfer.

The hardware needs HCTSIZ to be set to a multiple of HCCHAR.MPS, so trim
chan->max_packet in dwc2_assign_and_init_hc().

Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
---
 drivers/usb/dwc2/hcd.c | 5 +++++
 1 file changed, 5 insertions(+)

--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -2338,6 +2338,7 @@ static void dwc2_hc_init_xfer(struct dwc
 			else
 				chan->xfer_buf = urb->setup_packet;
 			chan->xfer_len = 8;
+			chan->max_packet = 8;
 			break;
 
 		case DWC2_CONTROL_DATA:
@@ -2621,6 +2622,10 @@ static int dwc2_assign_and_init_hc(struc
 	else
 		chan->do_split = 0;
 
+	/* Limit split IN transfers to the remaining buffer space */
+	if (qh->do_split && chan->ep_is_in)
+		chan->max_packet = min_t(u32, chan->max_packet, chan->xfer_len);
+
 	/* Set the transfer attributes */
 	dwc2_hc_init_xfer(hsotg, chan, qtd);
 
