summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_bus.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-01-20 21:59:13 +0000
committerjhb <jhb@FreeBSD.org>2006-01-20 21:59:13 +0000
commit76788b459e8439347a498ab900465722b7a187cf (patch)
treeeec17a9b197066f7f038be2d63c8c1ea557d7d1d /sys/kern/subr_bus.c
parentc959fdcd4e208eb80f6fb484d901544144df4ed5 (diff)
downloadFreeBSD-src-76788b459e8439347a498ab900465722b7a187cf.zip
FreeBSD-src-76788b459e8439347a498ab900465722b7a187cf.tar.gz
When loading a driver that is a subclass of another driver don't set the
devclass's parent pointer if the two drivers share the same devclass. This can happen if the drivers use the same new-bus name. For example, we currently have 3 drivers that use the name "pci": the generic PCI bus driver, the ACPI PCI bus driver, and the OpenFirmware PCI bus driver. If the ACPI PCI bus driver was defined as a subclass of the generic PCI bus driver, then without this check the "pci" devclass would point to itself as its parent and device_probe_child() would spin forever when it encountered the first PCI device that did have a matching driver. Reviewed by: dfr, imp, new-bus@
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r--sys/kern/subr_bus.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 7f7bb93..b19be54 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -781,7 +781,17 @@ devclass_find_internal(const char *classname, const char *parentname,
bus_data_generation_update();
}
- if (parentname && dc && !dc->parent) {
+
+ /*
+ * If a parent class is specified, then set that as our parent so
+ * that this devclass will support drivers for the parent class as
+ * well. If the parent class has the same name don't do this though
+ * as it creates a cycle that can trigger an infinite loop in
+ * device_probe_child() if a device exists for which there is no
+ * suitable driver.
+ */
+ if (parentname && dc && !dc->parent &&
+ strcmp(classname, parentname) != 0) {
dc->parent = devclass_find_internal(parentname, 0, FALSE);
}
OpenPOWER on IntegriCloud