Hi,
rather than patching uhub(4), i figured this would be less not-ok,
if not ok as-is, given its way more limited scope.
diff below works for me, but i suppose playing w/timeouts is a must,
for root on nfs?
-Artturi
diff --git a/sys/arch/arm64/dev/bcm2835_dwctwo.c
b/sys/arch/arm64/dev/bcm2835_dwctwo.c
index d6cfe61fd2a..af0fe90ad5d 100644
--- a/sys/arch/arm64/dev/bcm2835_dwctwo.c
+++ b/sys/arch/arm64/dev/bcm2835_dwctwo.c
@@ -48,6 +48,10 @@ int bcm_dwctwo_match(struct device *, void *, void *);
void bcm_dwctwo_attach(struct device *, struct device *, void *);
void bcm_dwctwo_deferred(void *);
+void rpi3bp_fix_mue_later(struct device *);
+void rpi3bp_explore_workaround(struct usbd_device *);
+static struct usbd_device *rpi3bp_mue_fix = NULL;
+
const struct cfattach bcmdwctwo_ca = {
sizeof(struct bcm_dwctwo_softc), bcm_dwctwo_match, bcm_dwctwo_attach,
};
@@ -133,4 +137,41 @@ bcm_dwctwo_deferred(void *self)
sc->sc_dwc2.sc_child = config_found(&sc->sc_dwc2.sc_bus.bdev,
&sc->sc_dwc2.sc_bus, usbctlprint);
+
+ if (OF_is_compatible(OF_peer(0), "raspberrypi,3-model-b-plus")) {
+ rpi3bp_mue_fix = sc->sc_dwc2.sc_bus.root_hub;
+ config_mountroot(sc->sc_dwc2.sc_child, rpi3bp_fix_mue_later);
+ }
+}
+
+void
+rpi3bp_fix_mue_later(struct device *dv)
+{
+ rpi3bp_explore_workaround(rpi3bp_mue_fix);
+}
+
+void
+rpi3bp_explore_workaround(struct usbd_device *dev)
+{
+ static int rpi3bp_mue_fix_hubidx = 0;
+ struct usbd_port *up;
+ int port;
+
+ if (!rpi3bp_mue_fix)
+ return;
+
+ for (port = 1; port <= dev->hub->nports; port++) {
+ up = &dev->hub->ports[port-1];
+
+ /* mue0 at uhub2 port 1 ... */
+ if (rpi3bp_mue_fix_hubidx++ == 2) {
+ rpi3bp_mue_fix = NULL;
+ up->reattach = 1;
+ usb_needs_explore(dev, 0);
+ return;
+ }
+ if (up->device != NULL &&
+ up->device->hub != NULL)
+ rpi3bp_explore_workaround(up->device);
+ }
}