summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvikram <none@none>2008-04-11 12:36:18 -0700
committervikram <none@none>2008-04-11 12:36:18 -0700
commitc29cc3849763ffe2bfc27b75631d11e2268f675c (patch)
treea1926ad1fefd24c03efac66d80460d3b34d0431c
parentc1c61f44e88f4c8c155272ee56d868043146096a (diff)
downloadillumos-gate-c29cc3849763ffe2bfc27b75631d11e2268f675c.tar.gz
6563214 System panics on booting Solaris from USB hard/flash drive if it connected via usb hub
-rw-r--r--usr/src/uts/common/io/usb/usba/hubdi.c9
-rw-r--r--usr/src/uts/common/os/swapgeneric.c13
2 files changed, 21 insertions, 1 deletions
diff --git a/usr/src/uts/common/io/usb/usba/hubdi.c b/usr/src/uts/common/io/usb/usba/hubdi.c
index 8cfb0ea45e..9fe61a8244 100644
--- a/usr/src/uts/common/io/usb/usba/hubdi.c
+++ b/usr/src/uts/common/io/usb/usba/hubdi.c
@@ -1295,8 +1295,15 @@ hubd_bus_config(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
/*
* there must be a smarter way to do this but for
* now, a hack for booting USB storage.
+ *
+ * NOTE: we want to delay the mountroot thread which
+ * exclusively does a BUS_CONFIG_ONE, but not the
+ * USB hotplug threads which do the asynchronous
+ * enumeration exlusively via BUS_CONFIG_ALL. Having
+ * a delay for USB hotplug threads negates the delay for
+ * mountroot resulting in mountroot failing.
*/
- if (!modrootloaded) {
+ if (!modrootloaded && op == BUS_CONFIG_ONE) {
delay(drv_usectohz(1000000));
}
ndi_devi_enter(hubd->h_dip, &circ);
diff --git a/usr/src/uts/common/os/swapgeneric.c b/usr/src/uts/common/os/swapgeneric.c
index d4217c77f3..011a6a3c4d 100644
--- a/usr/src/uts/common/os/swapgeneric.c
+++ b/usr/src/uts/common/os/swapgeneric.c
@@ -906,6 +906,19 @@ load_bootpath_drivers(char *bootpath)
return (NULL);
}
+ /*
+ * The PROM node for hubs have incomplete compatible
+ * properties and therefore do not bind to the hubd driver.
+ * As a result load_bootpath_drivers() loads the usb_mid driver
+ * for hub nodes rather than the hubd driver. This causes
+ * mountroot failures when booting off USB storage. To prevent
+ * this, if we are booting via USB hubs, we preload the hubd driver.
+ */
+ if (strstr(bootpath, "/hub@") && modloadonly("drv", "hubd") == -1) {
+ cmn_err(CE_WARN, "bootpath contains a USB hub, "
+ "but cannot load hubd driver");
+ }
+
/* get rid of minor node at end of copy (if not already done above) */
p = strrchr(pathcopy, '/');
if (p) {