
On Wed, Apr 13, 2016 at 03:01:02PM +0300, Semen Protsenko wrote:
From: Sam Protsenko semen.protsenko@linaro.org
Some UDC controllers may require buffer size to be aligned to wMaxPacketSize. It's indicated by gadget->quirk_ep_out_aligned_size field being set to "true" (in UDC driver code). In that case rx_bytes_expected must be aligned to wMaxPacket size, otherwise stuck on transaction will happen. For example, it's required by DWC3 controller data manual:
section 8.2.3.3 Buffer Size Rules and Zero-Length Packets: For OUT endpoints, the following rules apply: - The BUFSIZ field must be ≥ 1 byte. - The total size of a Buffer Descriptor must be a multiple of MaxPacketSize - A received zero-length packet still requires a MaxPacketSize buffer. Therefore, if the expected amount of data to be received is a multiple of MaxPacketSize, software should add MaxPacketSize bytes to the buffer to sink a possible zero-length packet at the end of the transfer.
But other UDC controllers don't need such alignment, so mentioned field is set to "false". If buffer size is aligned to wMaxPacketSize, those controllers may stuck on transaction. The example is DWC2.
This patch checks gadget->quirk_ep_out_aligned_size field and aligns rx_bytes_expected to wMaxPacketSize only when it's needed.
[snip]
@@ -435,12 +438,18 @@ static unsigned int rx_bytes_expected(unsigned int maxpacket) return 0; if (rx_remain > EP_BUFFER_SIZE) return EP_BUFFER_SIZE;
- if (!quirk_ep_out_aligned_size)
goto out;
- if (rx_remain < maxpacket) { rx_remain = maxpacket; } else if (rx_remain % maxpacket != 0) { rem = rx_remain % maxpacket; rx_remain = rx_remain + (maxpacket - rem); }
+out: return rx_remain;
Can we do: /* Only continue on conntrollers that require additional padding */ if (!quirk_ep_out_aligned_size) return rx_remain;
Or similar comment, so it's clear in the code why we're doing this and no need for a new goto here. Thanks!