On Mon, Jul 30, 2018 at 12:11 AM,  <sc.dy...@gmail.com> wrote:
>  - Use DMA buffer aligned at 64KB boundary to avoid xhci bug.

In function xhci_event_xfer() xfer->actlen should be calculated
from sum of transferred TRB length, not xfer->length - remain,
when the transfer is splitted to multiple TRBs.

The xhci driver may split a transfer into multiple TRBs if the DMA
buffer is larger than 64kB or crosses 64kB boundary.
For the example of unpatched axen, 24kB buffer of SS Bulk-In transfer
might be spliited like following.

 TRB #0 bulk-in len 0x1000 paddr 0xda3ff000 (CHAIN)
 TRB #1 bulk-in len 0x5000 paddr 0xda400000 (IOC)

On the completion of each TRB xhci_event_xfer() calculates actlen.
The size of inbound packet is usually less than given buffer size,
TRB #0 ends up with SHORT_XFER and TRB #1 ends up with SUCCESS.

 bulk-in idx 2 last 3 len 0x6000 remain 0xf98 (for TRB #0)
 bulk-in idx 3 last 3 len 0x6000 remain 0x5000 (for TRB #1)

For TRB #0, the actlen is xfer->length - remain = 0x6000 - 0xf98 = 0x5068.
This value is stored in xfer->actlen.
The actlen of #1 is 0x6000 - 0x5000 = 0x1000, but xfer->actlen is not zero
so the actlen of #1 is ignored.
Thus the actlen of this transfer is determined to be 0x5068, however,
it is actually 0x68.

When axen works on USB2 the unpatched axen uses 16kB buffer.
It's smaller than 24kB of SS, less possible the buffer crosses 64kB boundary,
you might not meet the problem.

Reply via email to