bus: Allow subclass to have the same name as the parent class.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 7 Apr 2011 10:06:03 +0000 (18:06 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 7 Apr 2011 10:27:13 +0000 (18:27 +0800)
Obtained-from: FreeBSD (Revision 154598 by jhb@freebsd.org)

  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.

sys/kern/subr_bus.c

index caeaeca..45b9453 100644 (file)
@@ -606,7 +606,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, NULL, FALSE);
 
        return(dc);