Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Jul 2007 13:28:53 GMT
From:      Maxim Zhuravlev <thioretic@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 122775 for review
Message-ID:  <200707031328.l63DSrEm056929@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=122775

Change 122775 by thioretic@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));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707031328.l63DSrEm056929>