PERFORCE change 122730 for review

Maxim Zhuravlev thioretic at FreeBSD.org
Mon Jul 2 17:41:43 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=122730

Change 122730 by thioretic at thioretic on 2007/07/02 17:41:01

	Start to introduce stack to newbus

Affected files ...

.. //depot/projects/soc2007/thioretic_gidl/TODO#4 edit
.. //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#2 edit
.. //depot/projects/soc2007/thioretic_gidl/sys/bus.h#3 edit

Differences ...

==== //depot/projects/soc2007/thioretic_gidl/TODO#4 (text+ko) ====

@@ -45,4 +45,12 @@
 		#	...  
 3. Implement *drivers* stack namespace.
 	SOLUTION: define stack namespace methods suitable for drivers
-	FILE(S) AFFECTED: kern/sns_drivers.c  +	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.
+		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)...  
==== //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#2 (text+ko) ====

@@ -63,7 +63,8 @@
  */
 typedef struct driverlink *driverlink_t;
 struct driverlink {
-	kobj_class_t	driver;
+//	kobj_class_t	driver;
+	drv_internal_t	driver;
 	TAILQ_ENTRY(driverlink) link;	/* list of drivers in devclass */
 };
 
@@ -107,8 +108,9 @@
 	/*
 	 * Details of this device.
 	 */
-	driver_t	*driver;	/**< current driver */
-	devclass_t	devclass;	/**< current device class */
+//	driver_t	*driver;	/**< current driver */
+	driver_list_t	drivers[DRV_LEVELS];	/**< list of all drivers in stack*/
+	devclass_t	devclass;	/**< current device class */		/*TODO*/
 	int		unit;		/**< current unit number */
 	char*		nameunit;	/**< name+unit e.g. foodev0 */
 	char*		desc;		/**< driver specific description */
@@ -239,8 +241,10 @@
 {
 	device_t dev = (device_t)arg1;
 	const char *value;
-	char *buf;
+	char *buf, *tmpbuf;
 	int error;
+	int level;
+	driverlink_t dl;
 
 	buf = NULL;
 	switch (arg2) {
@@ -248,7 +252,27 @@
 		value = dev->desc ? dev->desc : "";
 		break;
 	case DEVICE_SYSCTL_DRIVER:
-		value = dev->driver ? dev->driver->name : "";
+		value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO);
+		buf[0]='\0';
+		for (level=DRV_LOWEST; level<=DRV_TOPMOST; level++){
+			switch(level){
+				case DRV_LOWEST:	tmpbuf="LOWEST:"; break;
+				case DRV_LOWER:	tmpbuf="LOWER:"; break;
+				case DRV_MIDDLE:	tmpbuf="MIDDLE:"; break;
+				case DRV_UPPER:	tmpbuf="UPPER:"; break;
+				case DRV_TOPMOST:	tmpbuf="TOPMOST:"; break;
+			}
+			if (strlen(tmpbuf)+strlen(buf)>1023) break;
+			TAILQ_FOREACH(dl,&((dev->drivers)[level]),link){
+				if(strlen(dl->driver->devops->name)+strlen(buf)>1022)
+					break;
+				strcat(buf,dl->driver->devops->name);
+				strcat(buf,",");
+			}
+			buf[strlen(buf)]='\0';
+			strcat(buf,"\n");
+		}
+		//value = dev->driver ? dev->driver->name : "";		/**TODO*/
 		break;
 	case DEVICE_SYSCTL_LOCATION:
 		value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO);
@@ -287,10 +311,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),
+	SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),		/**TODO*/
 	    OID_AUTO, "%driver", CTLFLAG_RD,
 	    dev, DEVICE_SYSCTL_DRIVER, device_sysctl_handler, "A",
-	    "device driver name");
+	    "device stacked drivers names");
 	SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
 	    OID_AUTO, "%location", CTLFLAG_RD,
 	    dev, DEVICE_SYSCTL_LOCATION, device_sysctl_handler, "A",
@@ -838,12 +862,12 @@
  * @param driver	the driver to register
  */
 int
-devclass_add_driver(devclass_t dc, driver_t *driver)
+devclass_add_driver(devclass_t dc, /*driver_t **/ drv_internal_t driver)		/**TODO*/
 {
 	driverlink_t dl;
 	int i;
 
-	PDEBUG(("%s", DRIVERNAME(driver)));
+	PDEBUG(("%s", DRIVERNAME(driver->devops)));
 
 	dl = malloc(sizeof *dl, M_BUS, M_NOWAIT|M_ZERO);
 	if (!dl)
@@ -855,12 +879,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);
+	kobj_class_compile((kobj_class_t) (driver->devops));
 
 	/*
 	 * Make sure the devclass which the driver is implementing exists.
 	 */
-	devclass_find_internal(driver->name, 0, TRUE);
+	devclass_find_internal(driver->devops->name, 0, TRUE);
 
 	dl->driver = driver;
 	TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
@@ -877,6 +901,23 @@
 	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
  *
@@ -892,15 +933,16 @@
  * @param driver	the driver to unregister
  */
 int
-devclass_delete_driver(devclass_t busclass, driver_t *driver)
+devclass_delete_driver(devclass_t busclass, /*driver_t **/drv_internal_t driver)		
+/**TODO*/
 {
-	devclass_t dc = devclass_find(driver->name);
+	devclass_t dc = devclass_find(driver->devops->name);
 	driverlink_t dl;
 	device_t dev;
 	int i;
 	int error;
 
-	PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
+	PDEBUG(("%s from devclass %s", driver->devops->name, DEVCLANAME(busclass)));
 
 	if (!dc)
 		return (0);
@@ -914,7 +956,7 @@
 	}
 
 	if (!dl) {
-		PDEBUG(("%s not found in %s list", driver->name,
+		PDEBUG(("%s not found in %s list", driver->devops->name,
 		    busclass->name));
 		return (ENOENT);
 	}
@@ -932,7 +974,8 @@
 	for (i = 0; i < dc->maxunit; i++) {
 		if (dc->devices[i]) {
 			dev = dc->devices[i];
-			if (dev->driver == 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);
@@ -947,7 +990,7 @@
 	/* XXX: kobj_mtx */
 	driver->refs--;
 	if (driver->refs == 0)
-		kobj_class_free((kobj_class_t) driver);
+		kobj_class_free((kobj_class_t) (driver->devops));
 
 	bus_data_generation_update();
 	return (0);
@@ -967,15 +1010,15 @@
  * @param driver	the driver to unregister
  */
 int
-devclass_quiesce_driver(devclass_t busclass, driver_t *driver)
+devclass_quiesce_driver(devclass_t busclass, /*driver_t **/ drv_internal_t driver)		/**TODO*/
 {
-	devclass_t dc = devclass_find(driver->name);
+	devclass_t dc = devclass_find(driver->devops->name);
 	driverlink_t dl;
 	device_t dev;
 	int i;
 	int error;
 
-	PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
+	PDEBUG(("%s from devclass %s", driver->devops->name, DEVCLANAME(busclass)));
 
 	if (!dc)
 		return (0);
@@ -989,7 +1032,7 @@
 	}
 
 	if (!dl) {
-		PDEBUG(("%s not found in %s list", driver->name,
+		PDEBUG(("%s not found in %s list", driver->devops->name,
 		    busclass->name));
 		return (ENOENT);
 	}
@@ -1007,7 +1050,8 @@
 	for (i = 0; i < dc->maxunit; i++) {
 		if (dc->devices[i]) {
 			dev = dc->devices[i];
-			if (dev->driver == 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);
@@ -1022,14 +1066,14 @@
  * @internal
  */
 static driverlink_t
-devclass_find_driver_internal(devclass_t dc, const char *classname)
+devclass_find_driver_internal(devclass_t dc, const char *classname)		/**TODO*/
 {
 	driverlink_t dl;
 
 	PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc)));
 
 	TAILQ_FOREACH(dl, &dc->drivers, link) {
-		if (!strcmp(dl->driver->name, classname))
+		if (!strcmp(dl->driver->devops->name, classname))
 			return (dl);
 	}
 
@@ -1047,8 +1091,8 @@
  * @param dc		the devclass to search
  * @param classname	the driver name to search for
  */
-kobj_class_t
-devclass_find_driver(devclass_t dc, const char *classname)
+/*kobj_class_t*/ drv_internal_t
+devclass_find_driver(devclass_t dc, const char *classname)	/**TODO*/
 {
 	driverlink_t dl;
 
@@ -1164,16 +1208,17 @@
  * @retval ENOMEM	the array allocation failed
  */
 int
-devclass_get_drivers(devclass_t dc, driver_t ***listp, int *countp)
+devclass_get_drivers(devclass_t dc, /*driver_t **/ 
+		drv_internal_t **listp, int *countp) /**TODO*/
 {
 	driverlink_t dl;
-	driver_t **list;
+	/*driver_t **/ drv_internal_t *list;
 	int count;
 
 	count = 0;
 	TAILQ_FOREACH(dl, &dc->drivers, link)
 		count++;
-	list = malloc(count * sizeof(driver_t *), M_TEMP, M_NOWAIT);
+	list = malloc(count * sizeof(/*driver_t **/drv_internal_t), M_TEMP, M_NOWAIT);
 	if (list == NULL)
 		return (ENOMEM);
 
@@ -1429,10 +1474,11 @@
  * @returns the new device
  */
 static device_t
-make_device(device_t parent, const char *name, int unit)
+make_device(device_t parent, const char *name, int unit)	/**TODO*/
 {
 	device_t dev;
 	devclass_t dc;
+	int level;
 
 	PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));
 
@@ -1454,7 +1500,10 @@
 	dev->parent = parent;
 	TAILQ_INIT(&dev->children);
 	kobj_init((kobj_t) dev, &null_class);
-	dev->driver = NULL;
+//	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;
@@ -1661,7 +1710,7 @@
  * @internal
  */
 static driverlink_t
-first_matching_driver(devclass_t dc, device_t dev)
+first_matching_driver(devclass_t dc, device_t dev)			/**TODO*/
 {
 	if (dev->devclass)
 		return (devclass_find_driver_internal(dc, dev->devclass->name));
@@ -1672,12 +1721,12 @@
  * @internal
  */
 static driverlink_t
-next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)
+next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)	/**TODO*/
 {
 	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->name))
+			if (!strcmp(dev->devclass->name, dl->driver->devops->name))
 				return (dl);
 		return (NULL);
 	}
@@ -1688,7 +1737,7 @@
  * @internal
  */
 static int
-device_probe_child(device_t dev, device_t child)
+device_probe_child(device_t dev, device_t child)			/*TODO*/
 {
 	devclass_t dc;
 	driverlink_t best = 0;
@@ -1706,20 +1755,22 @@
 	 * 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)) {
-			PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));
+			if ((child->state == DS_ALIVE && (dl->driver->flags & (DR_LOWEST|DR_STACKAWARE))) || (child->state != DS_ALIVE && (dl->driver->flags & ~(DR_LOWEST|DR_STACKAWARE))))
+				continue;
+			PDEBUG(("Trying %s", DRIVERNAME(dl->driver->devops)));
 			device_set_driver(child, dl->driver);
 			if (!hasclass)
-				device_set_devclass(child, dl->driver->name);
+				device_set_devclass(child, dl->driver->devops->name);
 
 			/* Fetch any flags for the device before probing. */
-			resource_int_value(dl->driver->name, child->unit,
+			resource_int_value(dl->driver->devops->name, child->unit,
 			    "flags", &child->devflags);
 
 			result = DEVICE_PROBE(child);
@@ -1795,9 +1846,9 @@
 
 		/* Set the winning driver, devclass, and flags. */
 		if (!child->devclass)
-			device_set_devclass(child, best->driver->name);
+			device_set_devclass(child, best->driver->devops->name);
 		device_set_driver(child, best->driver);
-		resource_int_value(best->driver->name, child->unit,
+		resource_int_value(best->driver->devops->name, child->unit,
 		    "flags", &child->devflags);
 
 		if (pri < 0) {
@@ -1878,7 +1929,7 @@
  * is no driver currently attached
  */
 driver_t *
-device_get_driver(device_t dev)
+device_get_driver(device_t dev)			/*TODO*/
 {
 	return (dev->driver);
 }
@@ -2258,7 +2309,7 @@
  * @retval ENOMEM	a memory allocation failure occurred
  */
 int
-device_set_driver(device_t dev, driver_t *driver)
+device_set_driver(device_t dev, driver_t *driver)		/*TODO*/
 {
 	if (dev->state >= DS_ATTACHED)
 		return (EBUSY);
@@ -2319,7 +2370,7 @@
  * @retval non-zero	some other unix error code
  */
 int
-device_probe_and_attach(device_t dev)
+device_probe_and_attach(device_t dev)			/*TODO*/
 {
 	int error;
 
@@ -2368,7 +2419,7 @@
  * @retval non-zero	some other unix error code
  */
 int
-device_attach(device_t dev)
+device_attach(device_t dev)			/*TODO*/
 {
 	int error;
 
@@ -2408,7 +2459,7 @@
  * @retval non-zero	some other unix error code
  */
 int
-device_detach(device_t dev)
+device_detach(device_t dev)			/*TODO*/
 {
 	int error;
 
@@ -2855,7 +2906,7 @@
  * devclass.
  */
 int
-bus_generic_probe(device_t dev)
+bus_generic_probe(device_t dev)			/*TODO*/
 {
 	devclass_t dc = dev->devclass;
 	driverlink_t dl;
@@ -2875,7 +2926,7 @@
  * children.
  */
 int
-bus_generic_attach(device_t dev)
+bus_generic_attach(device_t dev)			/*TODO*/
 {
 	device_t child;
 
@@ -3075,7 +3126,7 @@
  * and then calls device_probe_and_attach() for each unattached child.
  */
 void
-bus_generic_driver_added(device_t dev, driver_t *driver)
+bus_generic_driver_added(device_t dev, driver_t *driver)			/*TODO*/
 {
 	device_t child;
 
@@ -3095,7 +3146,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)
+    int flags, driver_intr_t *intr, void *arg, void **cookiep)			/*TODO*/
 {
 	/* Propagate up the bus hierarchy until someone handles it. */
 	if (dev->parent)
@@ -3408,7 +3459,7 @@
  */
 int
 bus_setup_intr(device_t dev, struct resource *r, int flags,
-    driver_intr_t handler, void *arg, void **cookiep)
+    driver_intr_t handler, void *arg, void **cookiep)			/*TODO*/
 {
 	int error;
 
@@ -3619,7 +3670,7 @@
 	return (-1);
 }
 
-static kobj_method_t root_methods[] = {
+static kobj_method_t root_methods[] = {			/*TODO*/
 	/* Device interface */
 	KOBJMETHOD(device_shutdown,	bus_generic_shutdown),
 	KOBJMETHOD(device_suspend,	bus_generic_suspend),
@@ -3645,7 +3696,7 @@
 devclass_t	root_devclass;
 
 static int
-root_bus_module_handler(module_t mod, int what, void* arg)
+root_bus_module_handler(module_t mod, int what, void* arg)			/*TODO*/
 {
 	switch (what) {
 	case MOD_LOAD:
@@ -3704,7 +3755,7 @@
  * driver_module_data structure pointed to by @p arg
  */
 int
-driver_module_handler(module_t mod, int what, void *arg)
+driver_module_handler(module_t mod, int what, void *arg)			/*TODO*/
 {
 	int error;
 	struct driver_module_data *dmd;

==== //depot/projects/soc2007/thioretic_gidl/sys/bus.h#3 (text+ko) ====

@@ -472,31 +472,56 @@
  */
 #include "device_if.h"
 #include "bus_if.h"
+#include <sys/types.h>
 
 struct	module;
 
 int	driver_module_handler(struct module *, int, void *);
 
+#define DRV_LEVELS	5
+#define DRV_LOWEST	0
+#define DRV_LOWER	1
+#define DRV_MIDDLE	2
+#define DRV_UPPER	3
+#define DRV_TOPMOST	4
 /**
  * Module support for automatically adding drivers to busses.
  */
+struct drv_internal {
+	kobj_class_t devops;
+#define DR_STACKAWARE	1
+#define DR_LOWEST	2
+#define DR_LOWER	4
+#define	DR_MIDDLE	8
+#define DR_UPPER	16
+#define DR_TOPMOST	32
+	uint32_t flags;
+};
+
+typedef struct drv_internal *drv_internal_t;
+
 struct driver_module_data {
 	int		(*dmd_chainevh)(struct module *, int, void *);
 	void		*dmd_chainarg;
 	const char	*dmd_busname;
-	kobj_class_t	dmd_driver;
+//	kobj_class_t	dmd_driver;
+	drv_internal_t	dmd_driver;
 	devclass_t	*dmd_devclass;
-	int stackaware;
 };
 
 #define	DRIVER_MODULE(name, busname, driver, devclass, evh, arg)	\
 									\
+static struct drv_internal name##_##busname##_intnl {		\
+	(kobj_class_t)	&driver,		\
+	LOWEST							\
+};									\
+									\
 static struct driver_module_data name##_##busname##_driver_mod = {	\
 	evh, arg,							\
 	#busname,							\
-	(kobj_class_t) &driver,						\
-	&devclass,							\
-	0								\
+/*	(kobj_class_t) &driver,						\ */
+	&name##_##busname##_intnl,							\
+	&devclass							\
 };									\
 									\
 static moduledata_t name##_##busname##_mod = {				\


More information about the p4-projects mailing list