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

"Michael Cheponis via gnats" <[email protected]>
Newsgroups gmane.os.netbsd.bugs
Message-ID <[email protected]>
The following reply was made to PR port-arm/60021; it has been noted by GNATS.

From: Michael Cheponis <[email protected]>
To: [email protected]
Cc: [email protected], [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 08:45:14 -0700

 --0000000000009c2a8506583a8c4e
 Content-Type: text/plain; charset="UTF-8"
 Content-Transfer-Encoding: quoted-printable
 
 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=E2=80=AFAM 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 neve=
 r
 >         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]>
 >  >=3D20
 >  > This is almost certainly that autoconf doesn't wait (long enough) for
 >  > sub-ordintate hubs
 >  >=3D20
 >  > https://nxr.netbsd.org/xref/src/sys/dev/usb/uhub.c#880
 >  >=3D20
 >  >      880     mutex_enter(&sc->sc_lock);
 >  >      881     sc->sc_explorepending =3D3D false;
 >  >      882     for (int i =3D3D 0; i < sc->sc_statuslen; i++) {
 >  >      883             if (sc->sc_statuspend[i] !=3D3D 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 =3D3D 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 =3D3D 1; port <=3D3D hd->bNbrPorts; port++) {
 >      599                up =3D3D &dev->ud_hub->uh_ports[port - 1];
 >  ...
 >      848                /* Get device info and set its address. */
 >      849                err =3D3D 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 =3D3D false;
 >      884        for (int i =3D3D 0; i < sc->sc_statuslen; i++) {
 >      885                if (sc->sc_statuspend[i] !=3D3D 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 =3D3D false;
 >      897        }
 >
 >  https://nxr.netbsd.org/xref/src/sys/dev/usb/uhub.c?r=3D3D1.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=3D
 >  nt speed,
 >     1396     int port, struct usbd_port *up)
 >     1397 {
 >  ...
 >     1606        if (port =3D3D=3D3D 0) { /* root hub */
 >     1607                KASSERT(addr =3D3D=3D3D 1);
 >     1608                usbd_attach_roothub(parent, dev);
 >     1609                return USBD_NORMAL_COMPLETION;
 >     1610        }
 >     1611=3D20
 >     1612        err =3D3D usbd_probe_and_attach(parent, dev, port, addr);
 >     1613        if (err) {
 >     1614                usbd_remove_device(dev, up);
 >     1615                return err;
 >     1616        }
 >     1617=3D20
 >     1618        return USBD_NORMAL_COMPLETION;
 >     1619 }
 >
 >  https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=3D3D1.281#1388
 >
 >     1047 usbd_status
 >     1048 usbd_attach_roothub(device_t parent, struct usbd_device *dev)
 >     1049 {
 >  ...
 >     1065        dv =3D3D config_found(parent, &uaa, NULL,
 >     1066            CFARGS(.iattr =3D3D "usbroothubif"));
 >
 >  https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=3D3D1.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 =3D3D usbd_attachwholedevice(parent, dev, port, 0);
 >     1284        if (dev->ud_nifaces_claimed || err)
 >     1285                return err;
 >  ...
 >     1290        for (confi =3D3D 0; confi < dd->bNumConfigurations; confi=
 ++)
 > {
 >  ...
 >     1305                err =3D3D usbd_attachinterfaces(parent, dev, port=
 ,
 > NULL);
 >  ...
 >     1313                if (dev->ud_nifaces_claimed || err)
 >     1314                        return err;
 >     1315        }
 >  ...
 >     1324        err =3D3D usbd_attachwholedevice(parent, dev, port, 1);
 >
 >  https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=3D3D1.281#1270
 >
 >     1129 static usbd_status
 >     1130 usbd_attachwholedevice(device_t parent, struct usbd_device *dev,
 > in=3D
 >  t port,
 >     1131     int usegeneric)
 >     1132 {
 >  ...
 >     1161        dv =3D3D config_found(parent, &uaa, usbd_print,
 >     1162                          CFARGS(.submatch =3D3D config_stdsubmat=
 ch,
 >     1163                                 .iattr =3D3D "usbdevif",
 >     1164                                 .locators =3D3D dlocs));
 >  ...
 >
 >  https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=3D3D1.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 =3D3D config_found(parent, &uiaa, usbd_ifprint=
 ,
 >     1243                                  CFARGS(.submatch =3D3D
 > config_stdsubmatch,
 >     1244                                         .iattr =3D3D "usbifif",
 >     1245                                         .locators =3D3D 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 =3D3D kmem_alloc(sizeof(*hub) + (nports-1) *
 > sizeof(struct usbd_=3D
 >  port),
 >      372            KM_SLEEP);
 >      373        dev->ud_hub =3D3D hub;
 >      374        dev->ud_hub->uh_hubsoftc =3D3D sc;
 >      375        hub->uh_explore =3D3D uhub_explore;
 >      376        hub->uh_hubdesc =3D3D hubdesc;
 >
 >  https://nxr.netbsd.org/xref/src/sys/dev/usb/uhub.c?r=3D3D1.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=3D3D1 so you can drop int=
 o
 >  ddb and `show kernhist usbhist' might help.
 >
 >
 
 --0000000000009c2a8506583a8c4e
 Content-Type: text/html; charset="UTF-8"
 Content-Transfer-Encoding: quoted-printable
 
 <div dir=3D"ltr"><div class=3D"gmail_default" style=3D"font-family:arial,he=
 lvetica,sans-serif;font-size:small">I will give it a go (build /wUSB_DEBUG)=
 , and report.=C2=A0 I also have an RPi3B=C2=A0 (not=C2=A0+), and will try t=
 here, too.</div><div class=3D"gmail_default" style=3D"font-family:arial,hel=
 vetica,sans-serif;font-size:small"><br></div><div class=3D"gmail_default" s=
 tyle=3D"font-family:arial,helvetica,sans-serif;font-size:small">LLMs say no=
 t waiting long enough for the attach, probably.</div></div><br><div class=
 =3D"gmail_quote gmail_quote_container"><div dir=3D"ltr" class=3D"gmail_attr=
 ">On Tue, Aug 4, 2026 at 6:35=E2=80=AFAM Taylor R Campbell via gnats &lt;<a=
  href=3D"mailto:[email protected]">[email protected]</a>&gt; wrot=
 e:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
 .8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The following=
  reply was made to PR port-arm/60021; it has been noted by GNATS.<br>
 <br>
 From: Taylor R Campbell &lt;[email protected]&gt;<br>
 To: Nick Hudson &lt;<a href=3D"mailto:[email protected]" target=3D"_bla=
 nk">[email protected]</a>&gt;<br>
 Cc: <a href=3D"mailto:[email protected]" target=3D"_blank">[email protected]</a>,=
  [email protected], [email protected]<br>
 Subject: Re: port-arm/60021: USB-only boot: uhub0 attaches but uhub1 never<=
 br>
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 appears, no hotplug events; SD-boot sees hub+um=
 ass fine<br>
 Date: Tue, 4 Aug 2026 13:34:02 +0000<br>
 <br>
 =C2=A0&gt; Date: Sat, 21 Feb 2026 10:39:41 +0000<br>
 =C2=A0&gt; From: Nick Hudson &lt;<a href=3D"mailto:[email protected]" t=
 arget=3D"_blank">[email protected]</a>&gt;<br>
 =C2=A0&gt;=3D20<br>
 =C2=A0&gt; This is almost certainly that autoconf doesn&#39;t wait (long en=
 ough) for<br>
 =C2=A0&gt; sub-ordintate hubs<br>
 =C2=A0&gt;=3D20<br>
 =C2=A0&gt; <a href=3D"https://nxr.netbsd.org/xref/src/sys/dev/usb/uhub.c#88=
 0" rel=3D"noreferrer" target=3D"_blank">https://nxr.netbsd.org/xref/src/sys=
 /dev/usb/uhub.c#880</a><br>
 =C2=A0&gt;=3D20<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 880=C2=A0 =C2=A0 =C2=A0mutex_enter(&amp;sc-&=
 gt;sc_lock);<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 881=C2=A0 =C2=A0 =C2=A0sc-&gt;sc_explorepend=
 ing =3D3D false;<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 882=C2=A0 =C2=A0 =C2=A0for (int i =3D3D 0; i=
  &lt; sc-&gt;sc_statuslen; i++) {<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 883=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
  =C2=A0if (sc-&gt;sc_statuspend[i] !=3D3D 0) {<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 884=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
  =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0memcpy(sc-&gt;sc_status, sc-&gt;sc_statu=
 spend,<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 885=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
  =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sc-&gt;sc_statuslen);<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 886=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
  =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0memset(sc-&gt;sc_statuspend, 0, sc-&gt;s=
 c_statuslen);<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 887=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
  =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0usb_needs_explore(sc-&gt;sc_hub);<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 888=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
  =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 889=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
  =C2=A0}<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 890=C2=A0 =C2=A0 =C2=A0}<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 891=C2=A0 =C2=A0 =C2=A0mutex_exit(&amp;sc-&g=
 t;sc_lock);<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 892=C2=A0 =C2=A0 =C2=A0if (sc-&gt;sc_first_e=
 xplore) {<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 893=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
  =C2=A0config_pending_decr(sc-&gt;sc_dev);<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 894=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
  =C2=A0sc-&gt;sc_first_explore =3D3D false;<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 895=C2=A0 =C2=A0 =C2=A0}<br>
 <br>
 =C2=A0I don&#39;t understand, doesn&#39;t it wait for subordinate hubs?=C2=
 =A0 Maybe the<br>
 =C2=A0USB hub just doesn&#39;t report the device ready at first?<br>
 <br>
 =C2=A0Here&#39;s a fuller picture of the logic -- note that uhub_explore wi=
 ll<br>
 =C2=A0_synchronously_ attach autoconf drivers for the devices it finds on<b=
 r>
 =C2=A0the hub, and then uhub_attach will _also_ config_pending_incr:<br>
 <br>
 =C2=A0 =C2=A0 =C2=A0529 usbd_status<br>
 =C2=A0 =C2=A0 =C2=A0530 uhub_explore(struct usbd_device *dev)<br>
 =C2=A0 =C2=A0 =C2=A0531 {<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 =C2=A0598=C2=A0 =C2=A0 =C2=A0 =C2=A0 for (port =3D3D 1; port =
 &lt;=3D3D hd-&gt;bNbrPorts; port++) {<br>
 =C2=A0 =C2=A0 =C2=A0599=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 up =3D3D &amp;dev-&gt;ud_hub-&gt;uh_ports[port - 1];<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 =C2=A0848=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 /* Get device info and set its address. */<br>
 =C2=A0 =C2=A0 =C2=A0849=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 err =3D3D usbd_new_device(sc-&gt;sc_dev, dev-&gt;ud_bus,<br>
 =C2=A0 =C2=A0 =C2=A0850=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dev-&gt;ud_depth + 1, speed, port, u=
 p);<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 =C2=A0858=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 if (err) {<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 =C2=A0872=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 } else {<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 =C2=A0878=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (up-&gt;up_dev-&gt;ud_hub)<br>
 =C2=A0 =C2=A0 =C2=A0879=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 up-&gt;up_dev-&=
 gt;ud_hub-&gt;uh_explore(up-&gt;up_dev);<br>
 =C2=A0 =C2=A0 =C2=A0880=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 }<br>
 =C2=A0 =C2=A0 =C2=A0881=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
 =C2=A0 =C2=A0 =C2=A0882=C2=A0 =C2=A0 =C2=A0 =C2=A0 mutex_enter(&amp;sc-&gt;=
 sc_lock);<br>
 =C2=A0 =C2=A0 =C2=A0883=C2=A0 =C2=A0 =C2=A0 =C2=A0 sc-&gt;sc_explorepending=
  =3D3D false;<br>
 =C2=A0 =C2=A0 =C2=A0884=C2=A0 =C2=A0 =C2=A0 =C2=A0 for (int i =3D3D 0; i &l=
 t; sc-&gt;sc_statuslen; i++) {<br>
 =C2=A0 =C2=A0 =C2=A0885=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 if (sc-&gt;sc_statuspend[i] !=3D3D 0) {<br>
 =C2=A0 =C2=A0 =C2=A0886=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 memcpy(sc-&gt;sc_status, sc-&gt;sc_statuspe=
 nd,<br>
 =C2=A0 =C2=A0 =C2=A0887=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc-&gt;sc_statuslen);<br>
 =C2=A0 =C2=A0 =C2=A0888=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 memset(sc-&gt;sc_statuspend, 0, sc-&gt;sc_s=
 tatuslen);<br>
 =C2=A0 =C2=A0 =C2=A0889=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 usb_needs_explore(sc-&gt;sc_hub);<br>
 =C2=A0 =C2=A0 =C2=A0890=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br>
 =C2=A0 =C2=A0 =C2=A0891=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 }<br>
 =C2=A0 =C2=A0 =C2=A0892=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
 =C2=A0 =C2=A0 =C2=A0893=C2=A0 =C2=A0 =C2=A0 =C2=A0 mutex_exit(&amp;sc-&gt;s=
 c_lock);<br>
 =C2=A0 =C2=A0 =C2=A0894=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (sc-&gt;sc_first_expl=
 ore) {<br>
 =C2=A0 =C2=A0 =C2=A0895=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 config_pending_decr(sc-&gt;sc_dev);<br>
 =C2=A0 =C2=A0 =C2=A0896=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 sc-&gt;sc_first_explore =3D3D false;<br>
 =C2=A0 =C2=A0 =C2=A0897=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
 <br>
 =C2=A0<a href=3D"https://nxr.netbsd.org/xref/src/sys/dev/usb/uhub.c?r=3D3D1=
 .163#529" rel=3D"noreferrer" target=3D"_blank">https://nxr.netbsd.org/xref/=
 src/sys/dev/usb/uhub.c?r=3D3D1.163#529</a><br>
 <br>
 =C2=A0usbd_new_device synchronously attaches autoconf drivers:<br>
 <br>
 =C2=A0 =C2=A0 1394 usbd_status<br>
 =C2=A0 =C2=A0 1395 usbd_new_device(device_t parent, struct usbd_bus *bus, i=
 nt depth, i=3D<br>
 =C2=A0nt speed,<br>
 =C2=A0 =C2=A0 1396=C2=A0 =C2=A0 =C2=A0int port, struct usbd_port *up)<br>
 =C2=A0 =C2=A0 1397 {<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 1606=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (port =3D3D=3D3D 0) { /* r=
 oot hub */<br>
 =C2=A0 =C2=A0 1607=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 K=
 ASSERT(addr =3D3D=3D3D 1);<br>
 =C2=A0 =C2=A0 1608=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 u=
 sbd_attach_roothub(parent, dev);<br>
 =C2=A0 =C2=A0 1609=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 r=
 eturn USBD_NORMAL_COMPLETION;<br>
 =C2=A0 =C2=A0 1610=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
 =C2=A0 =C2=A0 1611=3D20<br>
 =C2=A0 =C2=A0 1612=C2=A0 =C2=A0 =C2=A0 =C2=A0 err =3D3D usbd_probe_and_atta=
 ch(parent, dev, port, addr);<br>
 =C2=A0 =C2=A0 1613=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (err) {<br>
 =C2=A0 =C2=A0 1614=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 u=
 sbd_remove_device(dev, up);<br>
 =C2=A0 =C2=A0 1615=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 r=
 eturn err;<br>
 =C2=A0 =C2=A0 1616=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
 =C2=A0 =C2=A0 1617=3D20<br>
 =C2=A0 =C2=A0 1618=C2=A0 =C2=A0 =C2=A0 =C2=A0 return USBD_NORMAL_COMPLETION=
 ;<br>
 =C2=A0 =C2=A0 1619 }<br>
 <br>
 =C2=A0<a href=3D"https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=
 =3D3D1.281#1388" rel=3D"noreferrer" target=3D"_blank">https://nxr.netbsd.or=
 g/xref/src/sys/dev/usb/usb_subr.c?r=3D3D1.281#1388</a><br>
 <br>
 =C2=A0 =C2=A0 1047 usbd_status<br>
 =C2=A0 =C2=A0 1048 usbd_attach_roothub(device_t parent, struct usbd_device =
 *dev)<br>
 =C2=A0 =C2=A0 1049 {<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 1065=C2=A0 =C2=A0 =C2=A0 =C2=A0 dv =3D3D config_found(parent,=
  &amp;uaa, NULL,<br>
 =C2=A0 =C2=A0 1066=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 CFARGS(.iattr =
 =3D3D &quot;usbroothubif&quot;));<br>
 <br>
 =C2=A0<a href=3D"https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=
 =3D3D1.281#1047" rel=3D"noreferrer" target=3D"_blank">https://nxr.netbsd.or=
 g/xref/src/sys/dev/usb/usb_subr.c?r=3D3D1.281#1047</a><br>
 <br>
 =C2=A0 =C2=A0 1270 usbd_status<br>
 =C2=A0 =C2=A0 1271 usbd_probe_and_attach(device_t parent, struct usbd_devic=
 e *dev,<br>
 =C2=A0 =C2=A0 1272=C2=A0 =C2=A0 =C2=A0int port, int addr)<br>
 =C2=A0 =C2=A0 1273 {<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 1283=C2=A0 =C2=A0 =C2=A0 =C2=A0 err =3D3D usbd_attachwholedev=
 ice(parent, dev, port, 0);<br>
 =C2=A0 =C2=A0 1284=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (dev-&gt;ud_nifaces_claime=
 d || err)<br>
 =C2=A0 =C2=A0 1285=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 r=
 eturn err;<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 1290=C2=A0 =C2=A0 =C2=A0 =C2=A0 for (confi =3D3D 0; confi &lt=
 ; dd-&gt;bNumConfigurations; confi++) {<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 1305=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 e=
 rr =3D3D usbd_attachinterfaces(parent, dev, port, NULL);<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 1313=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 i=
 f (dev-&gt;ud_nifaces_claimed || err)<br>
 =C2=A0 =C2=A0 1314=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return err;<br>
 =C2=A0 =C2=A0 1315=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 1324=C2=A0 =C2=A0 =C2=A0 =C2=A0 err =3D3D usbd_attachwholedev=
 ice(parent, dev, port, 1);<br>
 <br>
 =C2=A0<a href=3D"https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=
 =3D3D1.281#1270" rel=3D"noreferrer" target=3D"_blank">https://nxr.netbsd.or=
 g/xref/src/sys/dev/usb/usb_subr.c?r=3D3D1.281#1270</a><br>
 <br>
 =C2=A0 =C2=A0 1129 static usbd_status<br>
 =C2=A0 =C2=A0 1130 usbd_attachwholedevice(device_t parent, struct usbd_devi=
 ce *dev, in=3D<br>
 =C2=A0t port,<br>
 =C2=A0 =C2=A0 1131=C2=A0 =C2=A0 =C2=A0int usegeneric)<br>
 =C2=A0 =C2=A0 1132 {<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 1161=C2=A0 =C2=A0 =C2=A0 =C2=A0 dv =3D3D config_found(parent,=
  &amp;uaa, usbd_print,<br>
 =C2=A0 =C2=A0 1162=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 CFARGS(.submatch =3D3D config_stdsubmatc=
 h,<br>
 =C2=A0 =C2=A0 1163=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.iattr =3D3D =
 &quot;usbdevif&quot;,<br>
 =C2=A0 =C2=A0 1164=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.locators =3D=
 3D dlocs));<br>
 =C2=A0...<br>
 <br>
 =C2=A0<a href=3D"https://nxr.netbsd.org/xref/src/sys/dev/usb/usb_subr.c?r=
 =3D3D1.281#1129" rel=3D"noreferrer" target=3D"_blank">https://nxr.netbsd.or=
 g/xref/src/sys/dev/usb/usb_subr.c?r=3D3D1.281#1129</a><br>
 <br>
 =C2=A0 =C2=A0 1177 static usbd_status<br>
 =C2=A0 =C2=A0 1178 usbd_attachinterfaces(device_t parent, struct usbd_devic=
 e *dev,<br>
 =C2=A0 =C2=A0 1179=C2=A0 =C2=A0 =C2=A0int port, const int *locators)<br>
 =C2=A0 =C2=A0 1180 {<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 1242=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 d=
 v =3D3D config_found(parent, &amp;uiaa, usbd_ifprint,<br>
 =C2=A0 =C2=A0 1243=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 CFARGS(.subm=
 atch =3D3D config_stdsubmatch,<br>
 =C2=A0 =C2=A0 1244=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0.iattr =3D3D &quot;usbifif&quot;,<br>
 =C2=A0 =C2=A0 1245=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0.locators =3D3D ilocs));<br>
 <br>
 =C2=A0uhub is only at one of these (usbdevif or usbifif), but the point is<=
 br>
 =C2=A0the attach happens synchronously for subordinate hubs, before<br>
 =C2=A0uhub_explore gets to config_pending_decr.<br>
 <br>
 =C2=A0And in uhub_attach, pretty much the first thing it does is<br>
 =C2=A0config_pending_incr -- and it also sets the hub of the USB device to<=
 br>
 =C2=A0be the one it just created, so uhub_attach&#39;s call to uh_explore s=
 hould<br>
 =C2=A0take care of this:<br>
 <br>
 =C2=A0 =C2=A0 =C2=A0299 static void<br>
 =C2=A0 =C2=A0 =C2=A0300 uhub_attach(device_t parent, device_t self, void *a=
 ux)<br>
 =C2=A0 =C2=A0 =C2=A0301 {<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 =C2=A0318=C2=A0 =C2=A0 =C2=A0 =C2=A0 config_pending_incr(self=
 );<br>
 =C2=A0...<br>
 =C2=A0 =C2=A0 =C2=A0371=C2=A0 =C2=A0 =C2=A0 =C2=A0 hub =3D3D kmem_alloc(siz=
 eof(*hub) + (nports-1) * sizeof(struct usbd_=3D<br>
 =C2=A0port),<br>
 =C2=A0 =C2=A0 =C2=A0372=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 KM_SLEEP);=
 <br>
 =C2=A0 =C2=A0 =C2=A0373=C2=A0 =C2=A0 =C2=A0 =C2=A0 dev-&gt;ud_hub =3D3D hub=
 ;<br>
 =C2=A0 =C2=A0 =C2=A0374=C2=A0 =C2=A0 =C2=A0 =C2=A0 dev-&gt;ud_hub-&gt;uh_hu=
 bsoftc =3D3D sc;<br>
 =C2=A0 =C2=A0 =C2=A0375=C2=A0 =C2=A0 =C2=A0 =C2=A0 hub-&gt;uh_explore =3D3D=
  uhub_explore;<br>
 =C2=A0 =C2=A0 =C2=A0376=C2=A0 =C2=A0 =C2=A0 =C2=A0 hub-&gt;uh_hubdesc =3D3D=
  hubdesc;<br>
 <br>
 =C2=A0<a href=3D"https://nxr.netbsd.org/xref/src/sys/dev/usb/uhub.c?r=3D3D1=
 .163#529" rel=3D"noreferrer" target=3D"_blank">https://nxr.netbsd.org/xref/=
 src/sys/dev/usb/uhub.c?r=3D3D1.163#529</a><br>
 <br>
 =C2=A0As noted above, uhub_explore even explores the subordinate hubs<br>
 =C2=A0synchronously too by calling uh_explore!<br>
 <br>
 =C2=A0So, does the USB device not appear to be connected at the time of the=
 <br>
 =C2=A0initial probe, perhaps?<br>
 <br>
 =C2=A0Building with USB_DEBUG and enabling usb_debug=3D3D1 so you can drop =
 into<br>
 =C2=A0ddb and `show kernhist usbhist&#39; might help.<br>
 <br>
 </blockquote></div>
 
 --0000000000009c2a8506583a8c4e--
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.