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
