[U-Boot] [PATCH] fastboot: Fix OUT transaction length alignment

Sam Protsenko semen.protsenko at linaro.org
Wed Apr 13 14:02:53 CEST 2016


On Wed, Apr 13, 2016 at 3:01 PM, Semen Protsenko
<semen.protsenko at linaro.org> wrote:
> From: Sam Protsenko <semen.protsenko at 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.
>
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  drivers/usb/gadget/f_fastboot.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
> index 2e87fee..54dcce0 100644
> --- a/drivers/usb/gadget/f_fastboot.c
> +++ b/drivers/usb/gadget/f_fastboot.c
> @@ -58,6 +58,7 @@ static unsigned int fastboot_flash_session_id;
>  static unsigned int download_size;
>  static unsigned int download_bytes;
>  static bool is_high_speed;
> +static bool quirk_ep_out_aligned_size;
>
>  static struct usb_endpoint_descriptor fs_ep_in = {
>         .bLength            = USB_DT_ENDPOINT_SIZE,
> @@ -240,6 +241,8 @@ static int fastboot_set_alt(struct usb_function *f,
>         debug("%s: func: %s intf: %d alt: %d\n",
>               __func__, f->name, interface, alt);
>
> +       quirk_ep_out_aligned_size = gadget->quirk_ep_out_aligned_size;
> +
>         /* make sure we don't enable the ep twice */
>         if (gadget->speed == USB_SPEED_HIGH) {
>                 ret = usb_ep_enable(f_fb->out_ep, &hs_ep_out);
> @@ -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;
>  }
>
> --
> 2.8.0.rc3
>

Steve,

Can you please check if it fixes "fastboot flash" on your boards?

Thanks.


More information about the U-Boot mailing list