--- a/sys/bus/u4b/usb_dev.c +++ b/sys/bus/u4b/usb_dev.c @@ -1136,6 +1136,8 @@ /* Wait for re-enumeration, if any */ + int re_enum_tries = 0; /* DF-5423 */ + while (f->udev->re_enumerate_wait != USB_RE_ENUM_DONE) { usb_unref_device(cpd, &refs); @@ -1146,6 +1148,18 @@ err = ENXIO; goto done; } + /* + * DF-5423: the root hub (parent_hub == NULL) has no + * explore path that ever services its re_enumerate_wait + * (uhub_explore_handle_re_enumerate() is only invoked for + * hub children, usb_hub.c:550), so "usbconfig -d ugenX.1 + * reset" used to spin here uninterruptibly forever. + * Bound the wait (~2 s at hz/128 sleeps). + */ + if (++re_enum_tries > 256) { + err = ETIMEDOUT; + goto done; + } } done: