From: Maksim Kiselev <biguncle...@gmail.com>

In the case when the transfer buffer spans 64KB boundary, one trb is
divided into several. In this case, the size of the first trb buffer
sets equal to the size of truncated to 64K boundary.

However, this is not taken into account when calculating the actual
length.

To fix this need to subtract the trimmed size of first TRB buff
from the available_length.

Signed-off-by: Maksim Kiselev <biguncle...@gmail.com>
---
 drivers/usb/host/xhci-ring.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 34eb4536f0e..89d2e54f20a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -659,6 +659,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long 
pipe,
        u64 buf_64 = xhci_dma_map(ctrl, buffer, length);
        dma_addr_t last_transfer_trb_addr;
        int available_length;
+       int first_trb_trimmed_sz = 0;
 
        debug("dev=%p, pipe=%lx, buffer=%p, length=%d\n",
                udev, pipe, buffer, length);
@@ -740,6 +741,8 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long 
pipe,
 
        if (trb_buff_len > length)
                trb_buff_len = length;
+       else
+               first_trb_trimmed_sz = length - trb_buff_len;
 
        first_trb = true;
 
@@ -825,6 +828,8 @@ again:
        BUG_ON(TRB_TO_SLOT_ID(field) != slot_id);
        BUG_ON(TRB_TO_EP_INDEX(field) != ep_index);
 
+       available_length -= first_trb_trimmed_sz;
+
        record_transfer_result(udev, event, available_length);
        xhci_acknowledge_event(ctrl);
        xhci_inval_cache((uintptr_t)buffer, length);
-- 
2.45.2

Reply via email to