mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-27 01:11:14 +00:00
62b7f5931c
bcm2708: boot tested on RPi B+ v1.2
bcm2709: boot tested on RPi 3B v1.2 and RPi 4B v1.1 4G
bcm2710: boot tested on RPi 3B v1.2
bcm2711: boot tested on RPi 4B v1.1 4G
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
(cherry-picked from commit f07e572f64
)
44 lines
1.7 KiB
Diff
44 lines
1.7 KiB
Diff
From b7944a79716c115d881898e6a95705b262e7c1c9 Mon Sep 17 00:00:00 2001
|
|
From: Jonathan Bell <jonathan@raspberrypi.org>
|
|
Date: Tue, 7 Jan 2020 10:08:19 +0000
|
|
Subject: [PATCH] dwc_otg: constrain endpoint max packet and transfer
|
|
size on split IN
|
|
|
|
The hcd would unconditionally set the transfer length to the endpoint
|
|
packet size for non-isoc IN transfers. If the remaining buffer length
|
|
was less than the length of returned data, random memory would get
|
|
scribbled over, with bad effects if it crossed a page boundary.
|
|
|
|
Force a babble error if this happens by limiting the max transfer size
|
|
to the available buffer space. DMA will stop writing to memory on a
|
|
babble condition.
|
|
|
|
The hardware expects xfersize to be an integer multiple of maxpacket
|
|
size, so override hcchar.b.mps as well.
|
|
|
|
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
|
|
---
|
|
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
|
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
|
@@ -1811,7 +1811,7 @@ int fiq_fsm_queue_split_transaction(dwc_
|
|
st->nr_errors = 0;
|
|
|
|
st->hcchar_copy.d32 = 0;
|
|
- st->hcchar_copy.b.mps = hc->max_packet;
|
|
+ st->hcchar_copy.b.mps = min_t(uint32_t, hc->xfer_len, hc->max_packet);
|
|
st->hcchar_copy.b.epdir = hc->ep_is_in;
|
|
st->hcchar_copy.b.devaddr = hc->dev_addr;
|
|
st->hcchar_copy.b.epnum = hc->ep_num;
|
|
@@ -1856,7 +1856,7 @@ int fiq_fsm_queue_split_transaction(dwc_
|
|
st->hctsiz_copy.b.pid = hc->data_pid_start;
|
|
|
|
if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
|
|
- hc->xfer_len = hc->max_packet;
|
|
+ hc->xfer_len = min_t(uint32_t, hc->xfer_len, hc->max_packet);
|
|
} else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
|
|
hc->xfer_len = 188;
|
|
}
|