summaryrefslogtreecommitdiff
path: root/sys/dev/usb/usb.c
diff options
context:
space:
mode:
authorIan Dowse <iedowse@FreeBSD.org>2005-03-17 19:41:19 +0000
committerIan Dowse <iedowse@FreeBSD.org>2005-03-17 19:41:19 +0000
commita7b66eb1ae1e19ba814930c14ab67bd8152ec5ec (patch)
treefa7ffb5373ffca8a5c7db6aa4b91f42057b4da22 /sys/dev/usb/usb.c
parent7ac139a9041ab3b1140ac50cf8fb9f1f5292b4da (diff)
Notes
Diffstat (limited to 'sys/dev/usb/usb.c')
-rw-r--r--sys/dev/usb/usb.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c
index d10eb4accc53..84420d7f21b3 100644
--- a/sys/dev/usb/usb.c
+++ b/sys/dev/usb/usb.c
@@ -130,6 +130,7 @@ struct usb_softc {
USBBASEDEVICE sc_dev; /* base device */
#ifdef __FreeBSD__
struct cdev *sc_usbdev; /* /dev/usbN device */
+ TAILQ_ENTRY(usb_softc) sc_coldexplist; /* cold needs-explore list */
#endif
usbd_bus_handle sc_bus; /* USB controller */
struct usbd_port sc_port; /* dummy port for root hub */
@@ -178,6 +179,9 @@ Static struct proc *usb_task_thread_proc = NULL;
Static struct cdev *usb_dev; /* The /dev/usb device. */
Static int usb_ndevs; /* Number of /dev/usbN devices. */
Static int usb_taskcreated; /* USB task thread exists. */
+/* Busses to explore at the end of boot-time device configuration. */
+Static TAILQ_HEAD(, usb_softc) usb_coldexplist =
+ TAILQ_HEAD_INITIALIZER(usb_coldexplist);
#endif
#define USB_MAX_EVENTS 100
@@ -298,11 +302,12 @@ USB_ATTACH(usb)
*/
#if defined(__FreeBSD__)
if (cold)
+ TAILQ_INSERT_TAIL(&usb_coldexplist, sc, sc_coldexplist);
#else
if (cold && (sc->sc_dev.dv_cfdata->cf_flags & 1))
-#endif
dev->hub->explore(sc->sc_bus->root_hub);
#endif
+#endif
} else {
printf("%s: root hub problem, error=%d\n",
USBDEVNAME(sc->sc_dev), err);
@@ -947,7 +952,31 @@ usb_child_detached(device_t self, device_t child)
sc->sc_port.device = NULL;
}
+/* Explore all USB busses at the end of device configuration. */
+Static void
+usb_cold_explore(void *arg)
+{
+ struct usb_softc *sc;
+
+ /* XXX, on some archs this is called too late. */
+ if (!cold) {
+ printf("usb_cold_explore: skipping because !cold\n");
+ return;
+ }
+
+ while (!TAILQ_EMPTY(&usb_coldexplist)) {
+ sc = TAILQ_FIRST(&usb_coldexplist);
+ TAILQ_REMOVE(&usb_coldexplist, sc, sc_coldexplist);
+
+ sc->sc_bus->use_polling++;
+ sc->sc_port.device->hub->explore(sc->sc_bus->root_hub);
+ sc->sc_bus->use_polling--;
+ }
+}
+
DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
DRIVER_MODULE(usb, ehci, usb_driver, usb_devclass, 0, 0);
+SYSINIT(usb_cold_explore, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE,
+ usb_cold_explore, NULL);
#endif