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
This commit is contained in:
John Baldwin 2009-10-22 14:53:44 +00:00
parent bcda02c3e4
commit 3eec6f034a

View File

@ -1049,9 +1049,10 @@ devclass_driver_added(devclass_t dc, driver_t *driver)
* @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, driver_t *driver, int pass)
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 what, void *arg)
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: