From: Aswin Murugan <[email protected]>

Some xHCI controllers report COMP_SUCCESS with a non-zero residual
length for chained multi-TRB transfers. This can occur with large bulk
IN transfers used by USB Ethernet adapters such as ax88179_eth, when
a transfer crosses the 64 KiB boundary and is split across multiple
TRBs.

Replace the fatal BUG_ON() with a debug message and handle the transfer
like a short transfer. The actual transfer length is already
calculated from the residual length reported by the hardware, so
this avoids crashing U-Boot while preserving the received data length.

Signed-off-by: Aswin Murugan <[email protected]>
Signed-off-by: Sumit Singh Dhami <[email protected]>
---
 drivers/usb/host/xhci-ring.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 6f5c4ec97b6..bd88544977d 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -601,7 +601,14 @@ static void record_transfer_result(struct usb_device *udev,
 
        switch (GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len))) {
        case COMP_SUCCESS:
-               BUG_ON(udev->act_len != length);
+               /*
+                * Some controllers report COMP_SUCCESS with a non-zero 
residual for
+                * chained transfers. Treat this as a short transfer since 
act_len
+                * already accounts for the reported residual by the hardware.
+                */
+               if (udev->act_len != length)
+                       debug("%s: COMP_SUCCESS with residual (act_len=%d, 
length=%d)\n",
+                             __func__, udev->act_len, length);
                /* fallthrough */
        case COMP_SHORT_TX:
                udev->status = 0;

base-commit: 3973f3c4d24df75ca90d7c0a9f03e5e5c9b48f32
-- 
Best regards
Sumit Singh Dhami

Reply via email to