NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

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



The following reply was made to PR port-arm/60021; it has been noted by GNATS.

From: Michael Cheponis <michael.cheponis%gmail.com@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: port-arm-maintainer%netbsd.org@localhost, gnats-admin%netbsd.org@localhost, 
	netbsd-bugs%netbsd.org@localhost, mac%culver.net@localhost
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 <
 gnats-admin%netbsd.org@localhost> wrote:
 
 > The following reply was made to PR port-arm/60021; it has been noted by
 > GNATS.
 >
 > From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
 > To: Nick Hudson <nick.hudson%gmx.co.uk@localhost>
 > Cc: mac%culver.net@localhost, gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
 > 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 <nick.hudson%gmx.co.uk@localhost>
 >  >=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:gnats-admin%netbsd.org@localhost";>gnats-admin%netbsd.org@localhost</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;riastradh%NetBSD.org@localhost&gt;<br>
 To: Nick Hudson &lt;<a href=3D"mailto:nick.hudson%gmx.co.uk@localhost"; target=3D"_bla=
 nk">nick.hudson%gmx.co.uk@localhost</a>&gt;<br>
 Cc: <a href=3D"mailto:mac%culver.net@localhost"; target=3D"_blank">mac%culver.net@localhost</a>,=
  gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost<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:nick.hudson%gmx.co.uk@localhost"; t=
 arget=3D"_blank">nick.hudson%gmx.co.uk@localhost</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--
 



Home | Main Index | Thread Index | Old Index