svn commit: r198367 - head/sys/kern

John Baldwin jhb at FreeBSD.org
Thu Oct 22 14:53:44 UTC 2009


Author: jhb
Date: Thu Oct 22 14:53:44 2009
New Revision: 198367
URL: http://svn.freebsd.org/changeset/base/198367

Log:
  Set the devclass_t pointer specified in the DRIVER_MODULE() macro
  sooner so it is always valid when a driver's identify routine is
  called.  Previously, new-bus would attempt to create the devclass for
  a newly loaded driver in two separate places, once in
  devclass_add_driver(), and again after devclass_add_driver() returned
  in driver_module_handler().  Only the second lookup attempted to set a
  device class' parent and set the devclass_t pointer specified in the
  DRIVER_MODULE() macro.  However, by the time it was executed, the
  driver was already added to existing instances of the parent driver at
  which point in time the new driver's identify routine would have been
  invoked.  The fix is to merge the two attempts and only create the
  devclass once in devclass_add_driver() including setting the
  devclass_t pointer passed to DRIVER_MODULE() before the driver is
  added to any existing bus devices.
  
  Reported by:	avg
  Reviewed by:	imp
  MFC after:	2 weeks

Modified:
  head/sys/kern/subr_bus.c

Modified: head/sys/kern/subr_bus.c
==============================================================================
--- head/sys/kern/subr_bus.c	Thu Oct 22 12:48:17 2009	(r198366)
+++ head/sys/kern/subr_bus.c	Thu Oct 22 14:53:44 2009	(r198367)
@@ -1049,9 +1049,10 @@ devclass_driver_added(devclass_t dc, dri
  * @param driver	the driver to register
  */
 static int
-devclass_add_driver(devclass_t dc, driver_t *driver, int pass)
+devclass_add_driver(devclass_t dc, driver_t *driver, int pass, devclass_t *dcp)
 {
 	driverlink_t dl;
+	const char *parentname;
 
 	PDEBUG(("%s", DRIVERNAME(driver)));
 
@@ -1072,9 +1073,17 @@ devclass_add_driver(devclass_t dc, drive
 	kobj_class_compile((kobj_class_t) driver);
 
 	/*
-	 * Make sure the devclass which the driver is implementing exists.
+	 * If the driver has any base classes, make the
+	 * devclass inherit from the devclass of the driver's
+	 * first base class. This will allow the system to
+	 * search for drivers in both devclasses for children
+	 * of a device using this driver.
 	 */
-	devclass_find_internal(driver->name, NULL, TRUE);
+	if (driver->baseclasses)
+		parentname = driver->baseclasses[0]->name;
+	else
+		parentname = NULL;
+	*dcp = devclass_find_internal(driver->name, parentname, TRUE);
 
 	dl->driver = driver;
 	TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
@@ -4157,27 +4166,8 @@ driver_module_handler(module_t mod, int 
 		driver = dmd->dmd_driver;
 		PDEBUG(("Loading module: driver %s on bus %s (pass %d)",
 		    DRIVERNAME(driver), dmd->dmd_busname, pass));
-		error = devclass_add_driver(bus_devclass, driver, pass);
-		if (error)
-			break;
-
-		/*
-		 * If the driver has any base classes, make the
-		 * devclass inherit from the devclass of the driver's
-		 * first base class. This will allow the system to
-		 * search for drivers in both devclasses for children
-		 * of a device using this driver.
-		 */
-		if (driver->baseclasses) {
-			const char *parentname;
-			parentname = driver->baseclasses[0]->name;
-			*dmd->dmd_devclass =
-				devclass_find_internal(driver->name,
-				    parentname, TRUE);
-		} else {
-			*dmd->dmd_devclass =
-				devclass_find_internal(driver->name, NULL, TRUE);
-		}
+		error = devclass_add_driver(bus_devclass, driver, pass,
+		    dmd->dmd_devclass);
 		break;
 
 	case MOD_UNLOAD:


More information about the svn-src-head mailing list