PERFORCE change 122775 for review
Maxim Zhuravlev
thioretic at FreeBSD.org
Tue Jul 3 13:28:54 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=122775
Change 122775 by thioretic at thioretic on 2007/07/03 13:28:45
Yeserday's attempt failed. So now there is being intoduced
the compatibility layer to newbus (drv_compat_*).
It's supposed to be a more *delicate* way to let
old- and new-*fashioned* drivers to coexist. Overwise
all those current drivers could just fall on my head.
:o)
Affected files ...
.. //depot/projects/soc2007/thioretic_gidl/TODO#5 edit
.. //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#4 edit
Differences ...
==== //depot/projects/soc2007/thioretic_gidl/TODO#5 (text+ko) ====
@@ -48,9 +48,10 @@
FILE(S) AFFECTED: kern/sns_drivers.c
a. ADD
a.1.drivers
- SOLUTION: modify newbus so that it's aware about stacked
- structure of a device.
+ SOLUTION: add compatibility layer to newbus
FILE(S) AFFECTED: sys/bus.h, kern/subr_bus.c
# since now internally (and externally) for newbus, driver is
# not just kernel object class to be compiled into device, but
- # also has flags, default driversops (TODO)... + # also has flags, default driversops (TODO)...
+ # all these are hosted by compatibility layer (drv_compat_*)
+#TODO: check drivers, which use chainevh
==== //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#4 (text+ko) ====
@@ -63,17 +63,23 @@
*/
typedef struct driverlink *driverlink_t;
struct driverlink {
-// kobj_class_t driver;
- drv_internal_t driver;
+ kobj_class_t driver;
TAILQ_ENTRY(driverlink) link; /* list of drivers in devclass */
};
+struct drv_compat {
+ kobj_class_t driver;
+ uint32_t flags;
+ TAILQ_ENTRY(drv_compat) link;
+};
+typedef struct drv_compat *drv_compat_t;
/*
* Forward declarations
*/
typedef TAILQ_HEAD(devclass_list, devclass) devclass_list_t;
typedef TAILQ_HEAD(driver_list, driverlink) driver_list_t;
typedef TAILQ_HEAD(device_list, device) device_list_t;
+typedef TAILQ_HEAD(drv_compat_list, drv_compat) drv_compat_list_t;
struct devclass {
TAILQ_ENTRY(devclass) link;
@@ -108,9 +114,10 @@
/*
* Details of this device.
*/
-// driver_t *driver; /**< current driver */
- driver_list_t drivers[DRV_LEVELS]; /**< list of all drivers in stack*/
- devclass_t devclass; /**< current device class */ /*TODO*/
+ //driver_t *driver; /**< current driver */
+ driver_list_t drivers[DRV_LEVELS];
+ int drv_compat_flags;
+ devclass_t devclass; /**< current device class */
int unit; /**< current unit number */
char* nameunit; /**< name+unit e.g. foodev0 */
char* desc; /**< driver specific description */
@@ -241,10 +248,8 @@
{
device_t dev = (device_t)arg1;
const char *value;
- char *buf, *tmpbuf;
+ char *buf;
int error;
- int level;
- driverlink_t dl;
buf = NULL;
switch (arg2) {
@@ -264,9 +269,9 @@
}
if (strlen(tmpbuf)+strlen(buf)>1023) break;
TAILQ_FOREACH(dl,&((dev->drivers)[level]),link){
- if(strlen(dl->driver->devops->name)+strlen(buf)>1022)
+ if(strlen(dl->driver->name)+strlen(buf)>1022)
break;
- strcat(buf,dl->driver->devops->name);
+ strcat(buf,dl->driver->name);
strcat(buf,",");
}
buf[strlen(buf)]='\0';
@@ -311,10 +316,10 @@
OID_AUTO, "%desc", CTLFLAG_RD,
dev, DEVICE_SYSCTL_DESC, device_sysctl_handler, "A",
"device description");
- SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree), /**TODO*/
+ SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
OID_AUTO, "%driver", CTLFLAG_RD,
dev, DEVICE_SYSCTL_DRIVER, device_sysctl_handler, "A",
- "device stacked drivers names");
+ "device driver name"); /*TODO*/
SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
OID_AUTO, "%location", CTLFLAG_RD,
dev, DEVICE_SYSCTL_LOCATION, device_sysctl_handler, "A",
@@ -755,6 +760,161 @@
DEFINE_CLASS(null, null_methods, 0);
/*
+ * Driver compatibility layer implementation
+ */
+
+static drv_compat_list_t drv_compat_layer = TAILQ_HEAD_INITIALIZER(drv_compat_layer);
+
+/**
+ * @internal
+ * @brief Find or add driver compatibility settings
+ *
+ * If a driver is already present in compatibility layer
+ * return it, else, if @p add non-zero, add it.
+ *
+ * @param driver the device class and flags
+ * @param add non-zero to add driver to layer
+ */
+static drv_compat_t
+drv_compat_find_internal (drv_internal_t driver, int add) {
+ drv_compat_t drvc;
+
+ PDEBUG(("looking for driver %s to compatibility layer"), driver->devops->name);
+ if (!driver)
+ return (NULL);
+
+ TAILQ_FOREACH(drvc,&drv_compat_layer,link){
+ if (driver->devops == drvc->driver)
+ break;
+ }
+
+ if (!drvc && add){
+ PDEBUG(("adding driver %s to compatibility layer"), driver->devops->name);
+ drvc = malloc(sizeof(struct drv_compat), M_BUS, M_NOWAIT|M_ZERO);
+ if (!drvc)
+ return (NULL);
+ drvc->driver = driver->devops;
+ drvc->flags = driver->flags;
+ TAILQ_INSERT_TAIL(&drv_compat_layer, drvc, link);
+
+ bus_data_generation_update();
+ }
+ return (drvc);
+}
+
+/**
+ * @internal
+ * @brief find compartibility layer entry, associated
+ * with the driver
+ *
+ * @param driver device kobj_class pointer
+ */
+static drv_compat_t
+drv_compat_find_driver (driver_t *driver) {
+ drv_compat_t drvc;
+
+ TAILQ_FOREACH(drvc,&drv_compat_layer,link){
+ if (driver == drvc->driver)
+ break;
+ }
+
+ return drvc;
+}
+
+/**
+ * @internal
+ * @brief Add driver to compatibility layer
+ *
+ * If driver is already in compartibility layer
+ * return it, else add it
+ *
+ * @param driver devops plus flags
+ */
+static drv_compat_t
+drv_compat_add_driver (drv_internal_t driver) {
+ return (drv_compat_find_internal(driver, TRUE));
+}
+
+/**
+ * @internal
+ * @brief Removes a driver from compatibility layer
+ *
+ * @param driver pointer to device methods
+ * implementation
+ */
+static void
+drv_compat_delete_driver (driver_t *driver) {
+ drv_compat_t drvc;
+ drvc = drv_compat_find_driver(driver);
+ TAILQ_REMOVE(&drv_compat_layer, drvc, link);
+}
+
+/**
+ * @internal
+ * @brief Get compatibility layer's flags for a driver
+ *
+ * @param driver pointer to device methods implementation
+ * @param flags pointer to flags to be stored
+ */
+static int
+drv_compat_get_flags (driver_t *driver, uint32_t *flags){
+ drv_compat_t drvc;
+
+ drvc = drv_compat_find_driver(driver);
+
+ if (!drvc)
+ return (0);
+
+ *flags = drvc->flags;
+ return (1);
+}
+
+/**
+ * @internal
+ * @brief Set compatibility layer's flags for a driver
+ *
+ * @param driver pointer to device methods implementation
+ * @param flags flags to be set
+ */
+static int
+drv_compat_set_flags (driver_t *driver, uint32_t flags){
+ drv_compat_t drvc;
+
+ drvc = drv_compat_find_driver(driver);
+
+ if (!drvc)
+ return (0);
+ drvc->flags = flags;
+ return (1);
+}
+/*
+ * End of compatibility layer implementaion
+ */
+
+int
+is_device_driver (device_t dev, driver_t *driver){ /*TODO*/
+ int level;
+ uint32_t flags;
+ driverlink_t dl;
+
+ if (!drv_compat_get_flags(driver, &flags))
+ /*todo what?*/
+
+ switch ((flags)&(DR_LOWEST|DR_LOWER|DR_MIDDLE|DR_UPPER|DR_TOPMOST)) {
+ case DR_LOWEST: level=DRV_LOWEST; break;
+ case DR_LOWER: level=DRV_LOWER; break;
+ case DR_MIDDLE: level=DRV_MIDDLE; break;
+ case DR_UPPER: level=DRV_UPPER; break;
+ case DR_TOPMOST: level=DRV_TOPMOST; break;
+ }
+ TAILQ_FOREACH(dl,&((dev->drivers)[level]),link){
+ if (dl->driver==driver) return(TRUE);
+ }
+ return(FALSE);
+}
+
+
+/*
* Devclass implementation
*/
@@ -862,12 +1022,12 @@
* @param driver the driver to register
*/
int
-devclass_add_driver(devclass_t dc, /*driver_t **/ drv_internal_t driver) /**TODO*/
+devclass_add_driver(devclass_t dc, driver_t *driver)
{
driverlink_t dl;
int i;
- PDEBUG(("%s", DRIVERNAME(driver->devops)));
+ PDEBUG(("%s", DRIVERNAME(driver)));
dl = malloc(sizeof *dl, M_BUS, M_NOWAIT|M_ZERO);
if (!dl)
@@ -879,12 +1039,12 @@
* goes. This means we can safely use static methods and avoids a
* double-free in devclass_delete_driver.
*/
- kobj_class_compile((kobj_class_t) (driver->devops));
+ kobj_class_compile((kobj_class_t) driver);
/*
* Make sure the devclass which the driver is implementing exists.
*/
- devclass_find_internal(driver->devops->name, 0, TRUE);
+ devclass_find_internal(driver->name, 0, TRUE);
dl->driver = driver;
TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
@@ -901,23 +1061,6 @@
return (0);
}
-int
-is_device_driver (device_t dev, drv_internal_t driver){
- int level;
- driverlink_t dl;
-
- switch ((driver->flags)&(DR_LOWEST|DR_LOWER|DR_MIDDLE|DR_UPPER|DR_TOPMOST)) {
- case DR_LOWEST: level=DRV_LOWEST; break;
- case DR_LOWER: level=DRV_LOWER; break;
- case DR_MIDDLE: level=DRV_MIDDLE; break;
- case DR_UPPER: level=DRV_UPPER; break;
- case DR_TOPMOST: level=DRV_TOPMOST; break;
- }
- TAILQ_FOREACH(dl,&((dev->drivers)[level]),link){
- if (dl->driver==driver) return(1);
- }
- return(0);
-}
/**
* @brief Delete a device driver from a device class
*
@@ -933,16 +1076,15 @@
* @param driver the driver to unregister
*/
int
-devclass_delete_driver(devclass_t busclass, /*driver_t **/drv_internal_t driver)
-/**TODO*/
+devclass_delete_driver(devclass_t busclass, driver_t *driver) /*TODO*/
{
- devclass_t dc = devclass_find(driver->devops->name);
+ devclass_t dc = devclass_find(driver->name);
driverlink_t dl;
device_t dev;
int i;
int error;
- PDEBUG(("%s from devclass %s", driver->devops->name, DEVCLANAME(busclass)));
+ PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
if (!dc)
return (0);
@@ -956,7 +1098,7 @@
}
if (!dl) {
- PDEBUG(("%s not found in %s list", driver->devops->name,
+ PDEBUG(("%s not found in %s list", driver->name,
busclass->name));
return (ENOENT);
}
@@ -974,8 +1116,8 @@
for (i = 0; i < dc->maxunit; i++) {
if (dc->devices[i]) {
dev = dc->devices[i];
- if (/*dev->driver == driver*/
- is_device_driver(dev,driver) && dev->parent &&
+ if (/*dev->driver == driver*/
+ is_device_driver(dev, driver) && dev->parent &&
dev->parent->devclass == busclass) {
if ((error = device_detach(dev)) != 0)
return (error);
@@ -990,7 +1132,7 @@
/* XXX: kobj_mtx */
driver->refs--;
if (driver->refs == 0)
- kobj_class_free((kobj_class_t) (driver->devops));
+ kobj_class_free((kobj_class_t) driver);
bus_data_generation_update();
return (0);
@@ -1010,15 +1152,15 @@
* @param driver the driver to unregister
*/
int
-devclass_quiesce_driver(devclass_t busclass, /*driver_t **/ drv_internal_t driver) /**TODO*/
+devclass_quiesce_driver(devclass_t busclass, driver_t *driver) /*TODO*/
{
- devclass_t dc = devclass_find(driver->devops->name);
+ devclass_t dc = devclass_find(driver->name);
driverlink_t dl;
device_t dev;
int i;
int error;
- PDEBUG(("%s from devclass %s", driver->devops->name, DEVCLANAME(busclass)));
+ PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
if (!dc)
return (0);
@@ -1032,7 +1174,7 @@
}
if (!dl) {
- PDEBUG(("%s not found in %s list", driver->devops->name,
+ PDEBUG(("%s not found in %s list", driver->name,
busclass->name));
return (ENOENT);
}
@@ -1050,8 +1192,8 @@
for (i = 0; i < dc->maxunit; i++) {
if (dc->devices[i]) {
dev = dc->devices[i];
- if (/*dev->driver == driver*/
- is_device_driver(dev,driver) && dev->parent &&
+ if (/*dev->driver == driver*/
+ is_device_driver(dev, driver) && dev->parent &&
dev->parent->devclass == busclass) {
if ((error = device_quiesce(dev)) != 0)
return (error);
@@ -1066,14 +1208,14 @@
* @internal
*/
static driverlink_t
-devclass_find_driver_internal(devclass_t dc, const char *classname) /**TODO*/
+devclass_find_driver_internal(devclass_t dc, const char *classname)
{
driverlink_t dl;
PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc)));
TAILQ_FOREACH(dl, &dc->drivers, link) {
- if (!strcmp(dl->driver->devops->name, classname))
+ if (!strcmp(dl->driver->name, classname))
return (dl);
}
@@ -1091,8 +1233,8 @@
* @param dc the devclass to search
* @param classname the driver name to search for
*/
-/*kobj_class_t*/ drv_internal_t
-devclass_find_driver(devclass_t dc, const char *classname) /**TODO*/
+kobj_class_t
+devclass_find_driver(devclass_t dc, const char *classname)
{
driverlink_t dl;
@@ -1208,17 +1350,16 @@
* @retval ENOMEM the array allocation failed
*/
int
-devclass_get_drivers(devclass_t dc, /*driver_t **/
- drv_internal_t **listp, int *countp) /**TODO*/
+devclass_get_drivers(devclass_t dc, driver_t ***listp, int *countp)
{
driverlink_t dl;
- /*driver_t **/ drv_internal_t *list;
+ driver_t **list;
int count;
count = 0;
TAILQ_FOREACH(dl, &dc->drivers, link)
count++;
- list = malloc(count * sizeof(/*driver_t **/drv_internal_t), M_TEMP, M_NOWAIT);
+ list = malloc(count * sizeof(driver_t *), M_TEMP, M_NOWAIT);
if (list == NULL)
return (ENOMEM);
@@ -1474,7 +1615,7 @@
* @returns the new device
*/
static device_t
-make_device(device_t parent, const char *name, int unit) /**TODO*/
+make_device(device_t parent, const char *name, int unit) /*TODO*/
{
device_t dev;
devclass_t dc;
@@ -1500,10 +1641,9 @@
dev->parent = parent;
TAILQ_INIT(&dev->children);
kobj_init((kobj_t) dev, &null_class);
-// dev->driver = NULL;
- for (level=DRV_LOWEST;level<=DRV_TOPMOST;level++){
+ //dev->driver = NULL;
+ for (level=DRV_LOWEST; level<=DRV_TOPMOST; level++)
TAILQ_INIT(&((dev->drivers)[level]));
- }
dev->devclass = NULL;
dev->unit = unit;
dev->nameunit = NULL;
@@ -1710,7 +1850,7 @@
* @internal
*/
static driverlink_t
-first_matching_driver(devclass_t dc, device_t dev) /**TODO*/
+first_matching_driver(devclass_t dc, device_t dev)
{
if (dev->devclass)
return (devclass_find_driver_internal(dc, dev->devclass->name));
@@ -1721,12 +1861,12 @@
* @internal
*/
static driverlink_t
-next_matching_driver(devclass_t dc, device_t dev, driverlink_t last) /**TODO*/
+next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)
{
if (dev->devclass) {
driverlink_t dl;
for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link))
- if (!strcmp(dev->devclass->name, dl->driver->devops->name))
+ if (!strcmp(dev->devclass->name, dl->driver->name))
return (dl);
return (NULL);
}
@@ -1737,13 +1877,14 @@
* @internal
*/
static int
-device_probe_child(device_t dev, device_t child) /*TODO*/
+device_probe_child(device_t dev, device_t child)
{
devclass_t dc;
driverlink_t best = 0;
driverlink_t dl;
int result, pri = 0;
int hasclass = (child->devclass != 0);
+ uint32_t flags;
GIANT_REQUIRED;
@@ -1755,22 +1896,25 @@
* If the state is already probed, then return. However, don't
* return if we can rebid this object.
*/
- if (/*child->state == DS_ALIVE && */(child->flags & DF_REBID) == 0)
+ if (/*child->state == DS_ALIVE &&*/ (child->flags & DF_REBID) == 0)
return (0);
for (; dc; dc = dc->parent) {
for (dl = first_matching_driver(dc, child);
dl;
dl = next_matching_driver(dc, child, dl)) {
- if ((child->state == DS_ALIVE && dl->driver->flags & DR_STACKAWARE && dl->driver->flags & DR_LOWEST) || (child->state != DS_ALIVE && dl->driver->flags & ~DR_LOWEST))
+ if(!drv_compat_get_flags(dl->driver, &flags))
+ /*todo what?*/;
+ if (child->state == DS_ALIVE && flags & DR_LOWEST ||
+ (child->state != DS_ALIVE && flags & ~(DR_STACKAWARE|DR_LOWEST)))
continue;
- PDEBUG(("Trying %s", DRIVERNAME(dl->driver->devops)));
+ PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));
device_set_driver(child, dl->driver);
if (!hasclass)
- device_set_devclass(child, dl->driver->devops->name);
+ device_set_devclass(child, dl->driver->name);
/* Fetch any flags for the device before probing. */
- resource_int_value(dl->driver->devops->name, child->unit,
+ resource_int_value(dl->driver->name, child->unit,
"flags", &child->devflags);
result = DEVICE_PROBE(child);
@@ -1846,9 +1990,9 @@
/* Set the winning driver, devclass, and flags. */
if (!child->devclass)
- device_set_devclass(child, best->driver->devops->name);
+ device_set_devclass(child, best->driver->name);
device_set_driver(child, best->driver);
- resource_int_value(best->driver->devops->name, child->unit,
+ resource_int_value(best->driver->name, child->unit,
"flags", &child->devflags);
if (pri < 0) {
@@ -1929,9 +2073,14 @@
* is no driver currently attached
*/
driver_t *
-device_get_driver(device_t dev) /*TODO*/
+device_get_driver(device_t dev)
{
- return (dev->driver);
+ driverlink_t dl;
+ if (!TAILQ_EMPTY(&((dev->drivers)[DRV_LOWEST]))){
+ dl=TAILQ_FIRST(&((dev->drivers)[DRV_LOWEST]));
+ return (dl->driver);
+ }
+ return (NULL);
}
/**
@@ -2309,7 +2458,7 @@
* @retval ENOMEM a memory allocation failure occurred
*/
int
-device_set_driver(device_t dev, driver_t *driver) /*TODO*/
+device_set_driver(device_t dev, driver_t *driver)
{
if (dev->state >= DS_ATTACHED)
return (EBUSY);
@@ -2370,7 +2519,7 @@
* @retval non-zero some other unix error code
*/
int
-device_probe_and_attach(device_t dev) /*TODO*/
+device_probe_and_attach(device_t dev)
{
int error;
@@ -2419,7 +2568,7 @@
* @retval non-zero some other unix error code
*/
int
-device_attach(device_t dev) /*TODO*/
+device_attach(device_t dev)
{
int error;
@@ -2459,7 +2608,7 @@
* @retval non-zero some other unix error code
*/
int
-device_detach(device_t dev) /*TODO*/
+device_detach(device_t dev)
{
int error;
@@ -2906,7 +3055,7 @@
* devclass.
*/
int
-bus_generic_probe(device_t dev) /*TODO*/
+bus_generic_probe(device_t dev)
{
devclass_t dc = dev->devclass;
driverlink_t dl;
@@ -2926,7 +3075,7 @@
* children.
*/
int
-bus_generic_attach(device_t dev) /*TODO*/
+bus_generic_attach(device_t dev)
{
device_t child;
@@ -3126,14 +3275,14 @@
* and then calls device_probe_and_attach() for each unattached child.
*/
void
-bus_generic_driver_added(device_t dev, driver_t *driver) /*TODO*/
+bus_generic_driver_added(device_t dev, driver_t *driver)
{
device_t child;
DEVICE_IDENTIFY(driver, dev);
TAILQ_FOREACH(child, &dev->children, link) {
- if (child->state == DS_NOTPRESENT ||
- (child->flags & DF_REBID))
+// if (child->state == DS_NOTPRESENT ||
+// (child->flags & DF_REBID))
device_probe_and_attach(child);
}
}
@@ -3146,7 +3295,7 @@
*/
int
bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
- int flags, driver_intr_t *intr, void *arg, void **cookiep) /*TODO*/
+ int flags, driver_intr_t *intr, void *arg, void **cookiep)
{
/* Propagate up the bus hierarchy until someone handles it. */
if (dev->parent)
@@ -3459,7 +3608,7 @@
*/
int
bus_setup_intr(device_t dev, struct resource *r, int flags,
- driver_intr_t handler, void *arg, void **cookiep) /*TODO*/
+ driver_intr_t handler, void *arg, void **cookiep)
{
int error;
@@ -3670,7 +3819,7 @@
return (-1);
}
-static kobj_method_t root_methods[] = { /*TODO*/
+static kobj_method_t root_methods[] = {
/* Device interface */
KOBJMETHOD(device_shutdown, bus_generic_shutdown),
KOBJMETHOD(device_suspend, bus_generic_suspend),
@@ -3696,7 +3845,7 @@
devclass_t root_devclass;
static int
-root_bus_module_handler(module_t mod, int what, void* arg) /*TODO*/
+root_bus_module_handler(module_t mod, int what, void* arg)
{
switch (what) {
case MOD_LOAD:
@@ -3755,11 +3904,12 @@
* driver_module_data structure pointed to by @p arg
*/
int
-driver_module_handler(module_t mod, int what, void *arg) /*TODO*/
+driver_module_handler(module_t mod, int what, void *arg)
{
int error;
struct driver_module_data *dmd;
devclass_t bus_devclass;
+ drv_internal_t drv_intnl;
kobj_class_t driver;
dmd = (struct driver_module_data *)arg;
@@ -3771,7 +3921,10 @@
if (dmd->dmd_chainevh)
error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
- driver = dmd->dmd_driver;
+ //driver = dmd->dmd_driver;
+ drv_intnl = dmd->dmd_driver;
+ drv_compat_add_driver(drv_intnl);
+ driver = drv_intnl->devops;
PDEBUG(("Loading module: driver %s on bus %s",
DRIVERNAME(driver), dmd->dmd_busname));
error = devclass_add_driver(bus_devclass, driver);
@@ -3798,16 +3951,18 @@
break;
case MOD_UNLOAD:
+ drv_intnl = dmd->dmd_driver;
+ driver = drv_intnl->devops;
PDEBUG(("Unloading module: driver %s from bus %s",
- DRIVERNAME(dmd->dmd_driver),
+ DRIVERNAME(driver),
dmd->dmd_busname));
error = devclass_delete_driver(bus_devclass,
- dmd->dmd_driver);
-
+ driver);
+ drv_compat_delete_driver(driver);
if (!error && dmd->dmd_chainevh)
error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
break;
- case MOD_QUIESCE:
+ case MOD_QUIESCE: /*TODO*/
PDEBUG(("Quiesce module: driver %s from bus %s",
DRIVERNAME(dmd->dmd_driver),
dmd->dmd_busname));
More information about the p4-projects
mailing list