[PATCH v4 00/64] drivers: usb: dwc3: sync code with Linux v6.16

Ilias Apalodimas ilias.apalodimas at linaro.org
Wed Jul 1 21:56:40 CEST 2026


Thanks Mattijs,

This helps a lot

Cheers
/Ilias


On Wed, 1 Jul 2026 at 13:51, Mattijs Korpershoek
<mkorpershoek at kernel.org> wrote:
>
> Hi Jens,
>
> On Tue, Jun 30, 2026 at 15:38, Mattijs Korpershoek <mkorpershoek at kernel.org> wrote:
>
> > On Tue, Jun 30, 2026 at 11:36, Mattijs Korpershoek <mkorpershoek at kernel.org> wrote:
> >
> >>
> >> I've tried this out on the Khadas VIM3 board using
> >> khadas-vim3_android_defconfig and usb gadget (with fastboot) seems to
> >> misbehave.
> >>
> >> With the series applied, I see:
> >> """
> >> U-Boot 2026.07-rc3-00064-g511db6941796 (Jun 30 2026 - 11:20:08 +0200) khadas-vim3
> >>
> >> Model: Khadas VIM3
> >> SoC:   Amlogic Meson G12B (A311D) Revision 29:b (10:2)
> >> DRAM:  2 GiB (total 3.8 GiB)
> >> Core:  408 devices, 37 uclasses, devicetree: separate
> >> MMC:   mmc at ffe03000: 0, mmc at ffe05000: 1, mmc at ffe07000: 2
> >> Loading Environment from MMC... MMC Device -1 not found
> >> *** Warning - No MMC card found, using default environment
> >>
> >> In:    usbkbd,serial
> >> Out:   vidconsole,serial
> >> Err:   vidconsole,serial
> >> Net:   eth0: ethernet at ff3f0000
> >>
> >> Hit any key to stop autoboot: 0
> >> => fastboot usb 0
> >> failed to start <NULL>: -12
> >> g_dnl_register: failed!, error: -12
> >> exit not allowed from main input shell.
> >> """
> >>
> >> With v2026.07-rc3, I see:
> >> """
> >> U-Boot 2026.07-rc3 (Jun 30 2026 - 11:24:04 +0200) khadas-vim3
> >>
> >> Model: Khadas VIM3
> >> SoC:   Amlogic Meson G12B (A311D) Revision 29:b (10:2)
> >> DRAM:  2 GiB (total 3.8 GiB)
> >> Core:  408 devices, 37 uclasses, devicetree: separate
> >> MMC:   mmc at ffe03000: 0, mmc at ffe05000: 1, mmc at ffe07000: 2
> >> Loading Environment from MMC... MMC Device -1 not found
> >> *** Warning - No MMC card found, using default environment
> >>
> >> In:    usbkbd,serial
> >> Out:   vidconsole,serial
> >> Err:   vidconsole,serial
> >> Net:   eth0: ethernet at ff3f0000
> >>
> >> Hit any key to stop autoboot: 0
> >> => fastboot usb 0
> >> crq->brequest:0x0
> >> """
> >>
> >> The failure code path seems to go through:
> >> g_dnl_register("usb_dnl_fastboot");
> >>   usb_composite_register(&g_dnl_driver);
> >>     usb_gadget_register_driver(&composite_driver);
> >>       usb_gadget_probe_driver(driver);
> >>         udc_bind_to_driver(udc, driver);
> >>           driver->bind(udc->gadget);
> >>
> >>
> >> I don't know why it's happening but I wanted to give some feedback early
> >> on.
> >> I'll have a closer look.
> >
> > I spend a bit more time on this.
> >
> > driver->bind() calls fastboot_bind() which fails to configure the input
> > endpoint with the following code:
> >
> >       f_fb->in_ep = usb_ep_autoconfig(gadget, &fs_ep_in);
> >
> > Looking more closely at usb_ep_autoconfig():
> > * in v2026.07-rc3 we have an ep_matches() that finds the relevant
> >   endpoint
> > * with this series, we now have usb_gadget_ep_match_desc() which does
> >   not behave the same way.
> >
> > If i put back the original ep_matches() implementation (from
> > v2026.07-rc3) and call that instead of usb_gadget_ep_match_desc() in
> > usb_ep_autoconfig_ss(), I can use fastboot again.
> >
> > I have not studied how different ep_matches() and
> > usb_gadget_ep_match_desc() are.
>
> usb_gadget_ep_match_desc() uses the endpoint's capabilities (the cap
> member of that struct) to find matching endpoints.
> This is significantly different from ep_matches(), which relied on
> endpoint names.
>
> Because of this change, I had to add the following diff to
> drivers/usb/gadget/dwc2_udc_otg.c:
>
> diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c
> index 9f037d1e8016..01c9a938bd79 100644
> --- a/drivers/usb/gadget/dwc2_udc_otg.c
> +++ b/drivers/usb/gadget/dwc2_udc_otg.c
> @@ -741,6 +741,7 @@ static const struct usb_gadget_ops dwc2_udc_ops = {
>  #endif
>  };
>
>  static struct dwc2_udc memory = {
>         .usb_address = 0,
>         .gadget = {
> @@ -755,6 +756,11 @@ static struct dwc2_udc memory = {
>                         .name = ep0name,
>                         .ops = &dwc2_ep_ops,
>                         .maxpacket = EP0_FIFO_SIZE,
> +                       .caps = {
> +                               .type_control = 1,
> +                               .dir_in = 1,
> +                               .dir_out = 1,
> +                       },
>                 },
>                 .dev = &memory,
>
> @@ -770,6 +776,10 @@ static struct dwc2_udc memory = {
>                         .name = "ep1in-bulk",
>                         .ops = &dwc2_ep_ops,
>                         .maxpacket = EP_FIFO_SIZE,
> +                       .caps = {
> +                               .type_bulk = 1,
> +                               .dir_in = 1,
> +                       },
>                 },
>                 .dev = &memory,
>
> @@ -785,6 +795,10 @@ static struct dwc2_udc memory = {
>                         .name = "ep2out-bulk",
>                         .ops = &dwc2_ep_ops,
>                         .maxpacket = EP_FIFO_SIZE,
> +                       .caps = {
> +                               .type_bulk = 1,
> +                               .dir_out = 1,
> +                       },
>                 },
>                 .dev = &memory,
>
> @@ -800,6 +814,10 @@ static struct dwc2_udc memory = {
>                         .name = "ep3in-int",
>                         .ops = &dwc2_ep_ops,
>                         .maxpacket = EP_FIFO_SIZE,
> +                       .caps = {
> +                               .type_int = 1,
> +                               .dir_in = 1,
> +                       },
>                 },
>
> This was not sufficient. I also had to update the .maxpacket fields to
> .maxpacket_limit as following:
>
> diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c
> index 01c9a938bd79..4a62cd60cb7d 100644
> --- a/drivers/usb/gadget/dwc2_udc_otg.c
> +++ b/drivers/usb/gadget/dwc2_udc_otg.c
> @@ -755,7 +755,7 @@ static struct dwc2_udc memory = {
>                 .ep = {
>                         .name = ep0name,
>                         .ops = &dwc2_ep_ops,
> -                       .maxpacket = EP0_FIFO_SIZE,
> +                       .maxpacket_limit = EP0_FIFO_SIZE,
>                         .caps = {
>                                 .type_control = 1,
>                                 .dir_in = 1,
> @@ -775,7 +775,7 @@ static struct dwc2_udc memory = {
>                 .ep = {
>                         .name = "ep1in-bulk",
>                         .ops = &dwc2_ep_ops,
> -                       .maxpacket = EP_FIFO_SIZE,
> +                       .maxpacket_limit = EP_FIFO_SIZE,
>                         .caps = {
>                                 .type_bulk = 1,
>                                 .dir_in = 1,
> @@ -794,7 +794,7 @@ static struct dwc2_udc memory = {
>                 .ep = {
>                         .name = "ep2out-bulk",
>                         .ops = &dwc2_ep_ops,
> -                       .maxpacket = EP_FIFO_SIZE,
> +                       .maxpacket_limit = EP_FIFO_SIZE,
>                         .caps = {
>                                 .type_bulk = 1,
>                                 .dir_out = 1,
> @@ -813,7 +813,7 @@ static struct dwc2_udc memory = {
>                 .ep = {
>                         .name = "ep3in-int",
>                         .ops = &dwc2_ep_ops,
> -                       .maxpacket = EP_FIFO_SIZE,
> +                       .maxpacket_limit = EP_FIFO_SIZE,
>                         .caps = {
>                                 .type_int = 1,
>                                 .dir_in = 1,
>
> Because this series introduces usb_gadget_ep_match_desc(), we should
> make sure that all the in-tree udc drivers have these capabilities set.
>
> In my opinion, we should do this as part of this series, otherwise we
> are breaking all the UDC drivers.
>
> Note that all drivers might not require this update, since drivers can
> also implement the usb_gadget_ops.match_ep() function instead.
>
> >
> >>
> >> Thanks,
> >> Mattijs
> >>


More information about the U-Boot mailing list