Re: port-arm/60021: USB-only boot: uhub0 attaches but uhub1 never appears, no hotplug events; SD-boot sees hub+umass fine

Michael Cheponis <[email protected]>
Newsgroups gmane.os.netbsd.bugs
Message-ID <CAOaX04O06Gmu2UkxyDxtdiQSTLVPm+RWzC7zu-K2Q8Fm4kTJGQ@mail.gmail.com>
I will give it a go (build /wUSB_DEBUG), and report.  I also have an RPi3B
(not +), and will try there, too.

LLMs say not waiting long enough for the attach, probably.

On Tue, Aug 4, 2026 at 6:35 AM Taylor R Campbell via gnats <
[email protected]> wrote:

> The following reply was made to PR port-arm/60021; it has been noted by
> GNATS.
>
> From: Taylor R Campbell <[email protected]>
> To: Nick Hudson <[email protected]>
> Cc: [email protected], [email protected], [email protected]
> Subject: Re: port-arm/60021: USB-only boot: uhub0 attaches but uhub1 never
>         appears, no hotplug events; SD-boot sees hub+umass fine
> Date: Tue, 4 Aug 2026 13:34:02 +0000
>
>  > Date: Sat, 21 Feb 2026 10:39:41 +0000
>  > From: Nick Hudson <[email protected]>
>  >=20
>  > This is almost certainly that autoconf doesn't wait (long enough) for
>  > sub-ordintate hubs
>  >=20
>  > https://nxr.netbsd.org/xref/src/sys/dev/usb/uhub.c#880
>  >=20
>  >      880     mutex_enter(&sc->sc_lock);
>  >      881     sc->sc_explorepending =3D false;
>  >      882     for (int i =3D 0; i < sc->sc_statuslen; i++) {
>  >      883             if (sc->sc_statuspend[i] !=3D 0) {
>  >      884                     memcpy(sc->sc_status, sc->sc_statuspend,
>  >      885                         sc->sc_statuslen);
>  >      886                     memset(sc->sc_statuspend, 0,
> sc->sc_statuslen);
>  >      887                     usb_needs_explore(sc->sc_hub);
>  >      888                     break;
>  >      889             }
>  >      890     }
>  >      891     mutex_exit(&sc->sc_lock);
>  >      892     if (sc->sc_first_explore) {
>  >      893             config_pending_decr(sc->sc_dev);
>  >      894             sc->sc_first_explore =3D false;
>  >      895     }
>
>  I don't understand, doesn't it wait for subordinate hubs?  Maybe the
>  USB hub just doesn't report the device ready at first?
>
>  Here's a fuller picture of the logic -- note that uhub_explore will
>  _synchronously_ attach autoconf drivers for the devices it finds on
>  the hub, and then uhub_attach will _also_ config_pending_incr:
>
>      529 usbd_status
>      530 uhub_explore(struct usbd_device *dev)
>      531 {
>  ...
>      598        for (port =3D 1; port <=3D hd->bNbrPorts; port++) {
>      599                up =3D &dev->ud_hub->uh_ports[port - 1];
>  ...
>      848                /* Get device info and set its address. */
>      849                err =3D usbd_new_device(sc->sc_dev, dev->ud_bus,
>      850                          dev->ud_depth + 1, speed, port, up);
>  ...
>      858                if (err) {
>  ...
>      872                } else {
>  ...
>      878                        if (up->up_dev->ud_hub)
>      879
> up->up_dev->ud_hub->uh_explore(up->up_dev);
>      880                }
>      881        }
>      882        mutex_enter(&sc->sc_lock);
>      883        sc->sc_explorepending =3D false;
>      884        for (int i =3D 0; i < sc->sc_statuslen; i++) {
>      885                if (sc->sc_statuspend[i] !=3D 0) {
>      886                        memcpy(sc->sc_status, sc->sc_statuspend,
>      887                            sc->sc_statuslen);
>      888                        memset(sc->sc_statuspend, 0,
> sc->sc_statuslen);
>      889                        usb_needs_explore(sc->sc_hub);
>      890                        break;
>      891                }
>      892        }
>      893        mutex_exit(&sc->sc_lock);
>      894        if (sc->sc_first_explore) {
>      895                config_pending_decr(sc->sc_dev);
>      896                sc->sc_first_explore =3D false;
>      897        }
>
>  https://nxr.netbsd.org/xref/src/sys/dev/usb/uhub.c?r=3D1.163#529
>
>  usbd_new_device synchronously attaches autoconf drivers:
>
>     1394 usbd_status
>     1395 usbd_new_device(device_t parent, struct usbd_bus *bus, int depth,
> i=
>  nt speed,
>     1396     int port, struct usbd_port *up)
>     1397 {
>  ...
>     1606        if (port =3D=3D 0) { /* root hub */
>     1607                KASSERT(addr =3D=3D 1);
>     1608                usbd_attach_roothub(parent, dev);
>     1609                return USBD_NORMAL_COMPLETION;
>     1610        }
>     1611=20
>     1612        err =3D usbd_probe_and_attach(parent, dev, port, addr);
>     1613        if (err) {
>     1614                usbd_remove_device(dev, up);
>     1615                return err;
>     1616        }
>     1617=20
>     1618        return USBD_NORMAL_COMPLETION;
>     1619 }
>
>  https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=3D1.281#1388
>
>     1047 usbd_status
>     1048 usbd_attach_roothub(device_t parent, struct usbd_device *dev)
>     1049 {
>  ...
>     1065        dv =3D config_found(parent, &uaa, NULL,
>     1066            CFARGS(.iattr =3D "usbroothubif"));
>
>  https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=3D1.281#1047
>
>     1270 usbd_status
>     1271 usbd_probe_and_attach(device_t parent, struct usbd_device *dev,
>     1272     int port, int addr)
>     1273 {
>  ...
>     1283        err =3D usbd_attachwholedevice(parent, dev, port, 0);
>     1284        if (dev->ud_nifaces_claimed || err)
>     1285                return err;
>  ...
>     1290        for (confi =3D 0; confi < dd->bNumConfigurations; confi++)
> {
>  ...
>     1305                err =3D usbd_attachinterfaces(parent, dev, port,
> NULL);
>  ...
>     1313                if (dev->ud_nifaces_claimed || err)
>     1314                        return err;
>     1315        }
>  ...
>     1324        err =3D usbd_attachwholedevice(parent, dev, port, 1);
>
>  https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=3D1.281#1270
>
>     1129 static usbd_status
>     1130 usbd_attachwholedevice(device_t parent, struct usbd_device *dev,
> in=
>  t port,
>     1131     int usegeneric)
>     1132 {
>  ...
>     1161        dv =3D config_found(parent, &uaa, usbd_print,
>     1162                          CFARGS(.submatch =3D config_stdsubmatch,
>     1163                                 .iattr =3D "usbdevif",
>     1164                                 .locators =3D dlocs));
>  ...
>
>  https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=3D1.281#1129
>
>     1177 static usbd_status
>     1178 usbd_attachinterfaces(device_t parent, struct usbd_device *dev,
>     1179     int port, const int *locators)
>     1180 {
>  ...
>     1242                dv =3D config_found(parent, &uiaa, usbd_ifprint,
>     1243                                  CFARGS(.submatch =3D
> config_stdsubmatch,
>     1244                                         .iattr =3D "usbifif",
>     1245                                         .locators =3D ilocs));
>
>  uhub is only at one of these (usbdevif or usbifif), but the point is
>  the attach happens synchronously for subordinate hubs, before
>  uhub_explore gets to config_pending_decr.
>
>  And in uhub_attach, pretty much the first thing it does is
>  config_pending_incr -- and it also sets the hub of the USB device to
>  be the one it just created, so uhub_attach's call to uh_explore should
>  take care of this:
>
>      299 static void
>      300 uhub_attach(device_t parent, device_t self, void *aux)
>      301 {
>  ...
>      318        config_pending_incr(self);
>  ...
>      371        hub =3D kmem_alloc(sizeof(*hub) + (nports-1) *
> sizeof(struct usbd_=
>  port),
>      372            KM_SLEEP);
>      373        dev->ud_hub =3D hub;
>      374        dev->ud_hub->uh_hubsoftc =3D sc;
>      375        hub->uh_explore =3D uhub_explore;
>      376        hub->uh_hubdesc =3D hubdesc;
>
>  https://nxr.netbsd.org/xref/src/sys/dev/usb/uhub.c?r=3D1.163#529
>
>  As noted above, uhub_explore even explores the subordinate hubs
>  synchronously too by calling uh_explore!
>
>  So, does the USB device not appear to be connected at the time of the
>  initial probe, perhaps?
>
>  Building with USB_DEBUG and enabling usb_debug=3D1 so you can drop into
>  ddb and `show kernhist usbhist' might help.
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.