PERFORCE change 123130 for review

Maxim Zhuravlev thioretic at FreeBSD.org
Sun Jul 8 14:35:40 UTC 2007


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

Change 123130 by thioretic at thioretic on 2007/07/08 14:34:58

	Some rethinking of api (eg. no initto in make_device);
	Some logic stuff.

Affected files ...

.. //depot/projects/soc2007/thioretic_gidl/TODO#10 edit
.. //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#8 edit

Differences ...

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

@@ -105,4 +105,22 @@
 		# driver without any probing. Also a device may have multiple parents
 		# and children. At this point it becomes obvious, that we should let
 		# a driver not just process, but also produce and destroy an io request.
-		+		# Inportant note: from above-said one can see, that since now newbus 
+		# won't be a tree, it will be a graph!
+		# New logic:
+		# probe/attach: the dev->driver is set to drv_compat(driver) to be 
+		# probed and attached.
+		# detach: will detach DRV_LOWEST driver and all filters consequently.
+		# As for functional devices (let's call like this all drivers with 
+		# DR_REQDEV flag set), the following scenario looks reasonable:
+		#
+		# driver_handler:	make_dev() & attach_all_parents() & DEVICE_PROBE
+		# DEVICE_PROBE:	driver_probe
+		# driver_probe:	parents = get_all_parents()
+		#		FOR_EACH (parent, parents){
+		#		if (DEVICE_INFO (parent) == bad)
+		#			detach_parent(parent)
+		#		}
+		#
+		# here	driver_handler & DEVICE_PROBE reside in subr_bus
+		#	driver_probe resides in driver
==== //depot/projects/soc2007/thioretic_gidl/kern/subr_bus.c#8 (text+ko) ====

@@ -93,6 +93,7 @@
 typedef TAILQ_HEAD(pdevclass_list, pdevclass) pdevclass_list_t;
 typedef TAILQ_HEAD(driver_list, driverlink) driver_list_t;
 typedef TAILQ_HEAD(device_list, device) device_list_t;
+typedef TAILQ_HEAD(pdevice_list, pdevice) pdevice_list_t;
 
 typedef TAILQ_HEAD(drv_compat_list, drv_compat) drv_compat_list_t;
 typedef TAILQ_HEAD(pdrv_compat_list, pdrv_compat) pdrv_compat_list_t;
@@ -133,8 +134,8 @@
 	TAILQ_ENTRY(device)	link;	/**< list of devices in parent */
 	TAILQ_ENTRY(device)	devlink; /**< global device list membership */
 	//device_t	parent;		/**< parent of this device  */
-	device_list_t	parents;
-	device_list_t	children;	/**< list of child devices */
+	/*device_list_t*/ pdevice_list_t	parents;
+	/*device_list_t*/ pdevice_list_t	children;	/**< list of child devices */
 
 	/*
 	 * Details of this device.
@@ -163,11 +164,18 @@
 	u_char	pad;
 	void	*ivars;			/**< instance variables  */
 	void	*softc;			/**< current driver's variables  */
+	u_long	refs;
 
 	struct sysctl_ctx_list sysctl_ctx; /**< state for sysctl variables  */
 	struct sysctl_oid *sysctl_tree;	/**< state for sysctl variables */
 };
 
+struct pdevice {
+	device_t device_ptr;
+	TAILQ(pdevice) link;
+};
+
+
 static MALLOC_DEFINE(M_BUS, "bus", "Bus data structures");
 static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc");
 
@@ -1335,7 +1343,7 @@
 			dev = dc->devices[i];
 			if (/*dev->driver == driver*/ 
 			is_device_driver(dev, driver) && !TAILQ_EMPTY(&(dev->parents)) &&
-			(TAILQ_FIRST(&(dev->parent->devclass))) == busclass) {
+			(TAILQ_FIRST(&(dev->parents)))->device_ptr->devclass == busclass) {
 				if ((error = device_detach(dev)) != 0)
 					return (error);
 				device_set_driver(dev, NULL);
@@ -1411,7 +1419,7 @@
 			dev = dc->devices[i];
 			if (/*dev->driver == driver*/ 
 			is_device_driver(dev, driver) && !TAILQ_EMPTY(&(dev->parents) &&
-			(TAILQ_FIRST(&(dev->parent)))->devclass == busclass) {
+			(TAILQ_FIRST(&(dev->parents)))->device_ptr->devclass == busclass) {
 				if ((error = device_quiesce(dev)) != 0)
 					return (error);
 			}
@@ -1832,12 +1840,13 @@
  * @returns the new device
  */
 static device_t
-make_device(device_t parent, const char *name, int unit, driver_t *initto)	/*TODO*/
+make_device(device_t parent, const char *name, int unit/*, driver_t *initto*/)	/*TODO*/
 {
 	device_t dev;
 	devclass_t dc;
 	int level;
 	drv_compat_t drvc;
+	pdevice *pd;
 
 	PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));
 
@@ -1856,26 +1865,30 @@
 	if (!dev)
 		return (NULL);
 	TAILQ_INIT(&(dev->parents));
-	TAILQ_INSERT_TAIL(&(dev->parents), *parent, link)
+	pd = malloc(sizeof(struct pdevice), M_BUS, M_NOWAIT|M_ZERO);
+	pd->device_ptr = parent;
+	TAILQ_INSERT_TAIL(&(dev->parents), pd, link);
 	TAILQ_INIT(&(dev->children));
 	//kobj_init((kobj_t) dev, &null_class);
 	kobj_init((kobj_t) dev, &drv_compat_ctrl_driver)
 	//dev->driver = NULL;
 	for (level=DRV_LOWEST; level<=DRV_TOPMOST; level++)
 		TAILQ_INIT(&((dev->drivers)[level]));
-	if (initto){
+	/*if (initto){
 		drvc = drv_compat_find_driver (initto);
 		if (!(drvc->topology_ops = kobj_create (initto, M_BUS, M_NOWAIT|M_ZERO)))
 			/*todo what??*/;
-		dev->devclass = devclass_find (DRIVERNAME(driver));
+	/*	dev->devclass = devclass_find (DRIVERNAME(driver));
 		level = drv_compat_flags2idx(drvc->flags);
 		TAILQ_INSERT_TAIL (&((dev->drivers)[level]), &drvc, link);
 		dev->state = DS_ALIVE;
 	}
-	else{
+	else{*/
 		dev->devclass = NULL;
 		dev->state = DS_NOTPRESENT;
-	}
+	/*}*/
+
+	dev->refs = 0;
 	dev->unit = unit;
 	dev->nameunit = NULL;
 	dev->desc = NULL;
@@ -1965,19 +1978,22 @@
 device_t
 device_add_child_ordered(device_t dev, int order, const char *name, int unit)
 {
-	device_t child;
-	device_t place;
+	/*device_t*/ pdevice *child;
+	/*device_t*/ pdevice *place;
 
 	PDEBUG(("%s at %s with order %d as unit %d",
 	    name, DEVICENAME(dev), order, unit));
 
-	child = make_device(dev, name, unit, NULL);
-	if (child == NULL)
-		return (child);
+	child = malloc (sizeof(pdevice), M_BUS, M_NOWAIT|M_ZERO);
+	child->device_ptr = make_device(dev, name, unit/*, NULL*/);
+	if (child->device_ptr == NULL){
+		free (child);
+		return (NULL);
+	}
 	child->order = order;
 
 	TAILQ_FOREACH(place, &dev->children, link) {
-		if (place->order > order)
+		if (place->device_ptr->order > order)
 			break;
 	}
 
@@ -1994,6 +2010,7 @@
 		 */
 		TAILQ_INSERT_TAIL(&dev->children, child, link);
 	}
+	child->device_ptr->refs++;
 
 	bus_data_generation_update();
 	return (child);
@@ -2013,39 +2030,54 @@
  * @retval non-zero	a unit error code describing the error
  */
 int
-device_delete_child(device_t dev, device_t child)
+device_delete_child(device_t dev, device_t child) /*TODO*/
 {
 	int error;
-	device_t grandchild;
+	/*device_t*/ pdevice *grandchild;
+	pdevice *pd;
 
 	PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
-
+	
+	child->refs--;
+	if (child->refs) goto deletefromparent;
 	/* remove children first */
 	while ( (grandchild = TAILQ_FIRST(&child->children)) ) {
-		error = device_delete_child(child, grandchild);
+		error = device_delete_child(child, grandchild->device_ptr);
 		if (error)
 			return (error);
+		free (grandchild);
 	}
 
 	if ((error = device_detach(child)) != 0)
 		return (error);
 	if (child->devclass)
 		devclass_delete_device(child->devclass, child);
-	TAILQ_REMOVE(&dev->children, child, link);
+deletefromparent:
+	TAILQ_FOREACH_SAFE(pd, &dev->children, link){
+		if (pd->device_ptr == child){
+			TAILQ_REMOVE(&dev->children, child, link);
+			free (pd);
+			break;
+		}
+	}
+
+	if (child->refs) 
+		return (0);
+
 	TAILQ_REMOVE(&bus_data_devices, child, devlink);
 	kobj_delete((kobj_t) child, M_BUS);
-
+	
 	bus_data_generation_update();
 	return (0);
 }
 
 static int
 is_device_parent (device_t dev, device_t child){
-	device_t dc;
+	pdevice *dc;
 	TAILQ_FOREACH (dc, &(child->parents), link){
-		if (dc == dev) return (1);
+		if (dc->device_ptr == dev) return (TRUE);
 	}
-	return (0);
+	return (FALSE);
 }
 
 /**
@@ -2263,8 +2295,11 @@
 device_t
 device_get_parent(device_t dev) /*TODO*/
 {
-	if (!TAILQ_EMPTY(&(dev->parents)))
-		return (TAILQ_FIRST(&(dev->parents)));
+	pdevice *pd;
+	if (!TAILQ_EMPTY(&(dev->parents))){
+		pd = TAILQ_FIRST(&(dev->parents));
+		return (pd->device_ptr);
+	}
 	return (NULL);
 }
 
@@ -2288,7 +2323,7 @@
 device_get_children(device_t dev, device_t **devlistp, int *devcountp)
 {
 	int count;
-	device_t child;
+	/*device_t*/ pdevice *child;
 	device_t *list;
 
 	count = 0;
@@ -2302,7 +2337,7 @@
 
 	count = 0;
 	TAILQ_FOREACH(child, &dev->children, link) {
-		list[count] = child;
+		list[count] = child->device_ptr;
 		count++;
 	}
 
@@ -2584,12 +2619,12 @@
 void
 device_busy(device_t dev)
 {
-	device_t parent;
+	pdevice *parent;
 	if (dev->state < DS_ATTACHED)
 		panic("device_busy: called for unattached device");
 	if (dev->busy == 0 && !TAILQ_EMPTY(&(dev->parents))){
 		TAILQ_FOREACH (parent, &(dev->parents), link){
-			device_busy(parent);
+			device_busy(parent->device_ptr);
 		}
 	}
 	dev->busy++;
@@ -2602,6 +2637,7 @@
 void
 device_unbusy(device_t dev)
 {
+	pdevice *parent;
 	if (dev->state != DS_BUSY)
 		panic("device_unbusy: called for non-busy device %s",
 		    device_get_nameunit(dev));
@@ -2609,7 +2645,7 @@
 	if (dev->busy == 0) {
 		if (/*dev->parent*/!TAILQ_EMPTY(&(dev->parents))){
 			TAILQ_FOREACH (parent, &(dev->parents), link){
-				device_unbusy(parent);
+				device_unbusy(parent->device_ptr);
 			}
 		}
 		//device_unbusy(dev->parent);
@@ -2713,6 +2749,8 @@
 int
 device_set_driver(device_t dev, driver_t *driver)
 {
+	drv_compat_t drvc;
+
 	if (dev->state >= DS_ATTACHED)
 		return (EBUSY);
 
@@ -2723,23 +2761,26 @@
 		free(dev->softc, M_BUS_SC);
 		dev->softc = NULL;
 	}
-	kobj_delete((kobj_t) dev, 0);
-	dev->driver = driver;
+	//kobj_delete((kobj_t) dev, 0);
+	dev->driver = drvc = drv_compat_find_driver (driver);
 	if (driver) {
-		kobj_init((kobj_t) dev, (kobj_class_t) driver);
+		if (!(drvc->topology_ops = kobj_create (initto, M_BUS, M_NOWAIT|M_ZERO)))
+			/*todo what??*/;
+		dev->driver = drvc;
+		//kobj_init((kobj_t) dev, (kobj_class_t) driver);
 		if (!(dev->flags & DF_EXTERNALSOFTC) && driver->size > 0) {
 			dev->softc = malloc(driver->size, M_BUS_SC,
 			    M_NOWAIT | M_ZERO);
 			if (!dev->softc) {
-				kobj_delete((kobj_t) dev, 0);
-				kobj_init((kobj_t) dev, &null_class);
+				//kobj_delete((kobj_t) dev, 0);
+				//kobj_init((kobj_t) dev, &null_class);
 				dev->driver = NULL;
 				return (ENOMEM);
 			}
 		}
-	} else {
+	} /*else {
 		kobj_init((kobj_t) dev, &null_class);
-	}
+	}*/
 
 	bus_data_generation_update();
 	return (0);
@@ -2824,12 +2865,13 @@
 device_attach(device_t dev)
 {
 	int error;
-	device_t parent;
+	pdevice *pd;
+	drv_compat_t drvc;
 
 	device_sysctl_init(dev);
 	if (!device_is_quiet(dev)){
-		TAILQ_FOREACH (parent, &(dev->parents), link){
-			device_print_child(parent, dev);
+		TAILQ_FOREACH (pd, &(dev->parents), link){
+			device_print_child(pd->device_ptr, dev);
 		}
 	}
 	if ((error = DEVICE_ATTACH(dev)) != 0) {
@@ -2842,6 +2884,12 @@
 		device_sysctl_fini(dev);
 		dev->state = DS_NOTPRESENT;
 		return (error);
+	} else {
+		drvc = dev->driver;
+		dev->devclass = devclass_find (DRIVERNAME(drvc->driver));
+		level = drv_compat_flags2idx(drvc->flags);
+		TAILQ_INSERT_TAIL (&((dev->drivers)[level]), &drvc, link);
+		driver = NULL;
 	}
 	dev->state = DS_ATTACHED;
 	devadded(dev);
@@ -2868,7 +2916,7 @@
 device_detach(device_t dev)
 {
 	int error;
-	device_t parent;
+	pdevice *pd;
 
 	GIANT_REQUIRED;
 
@@ -2882,9 +2930,9 @@
 		return (error);
 	devremoved(dev);
 	device_printf(dev, "detached\n");
-	if (!TAILQ_EMPTY(&(dev->parent))){
-		TAILQ_FOREACH (parent, &(dev->parents), link){
-			BUS_CHILD_DETACHED(parent, dev);
+	if (!TAILQ_EMPTY(&(dev->parents))){
+		TAILQ_FOREACH (pd, &(dev->parents), link){
+			BUS_CHILD_DETACHED(pd->device_ptr, dev);
 		}
 	}
 
@@ -3338,10 +3386,10 @@
 int
 bus_generic_attach(device_t dev)
 {
-	device_t child;
+	/*device_t*/ pdevice *child;
 
 	TAILQ_FOREACH(child, &dev->children, link) {
-		device_probe_and_attach(child);
+		device_probe_and_attach(child->device_ptr);
 	}
 
 	return (0);
@@ -4112,7 +4160,7 @@
 	case MOD_LOAD:
 		TAILQ_INIT(&bus_data_devices);
 		kobj_class_compile((kobj_class_t) &root_driver);
-		root_bus = make_device(NULL, "root", 0, NULL);
+		root_bus = make_device(NULL, "root", 0/*, NULL*/);
 		root_bus->desc = "System root bus";
 		kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
 		root_bus->driver = &root_driver;
@@ -4221,6 +4269,7 @@
 	kobj_class_t driver;
 	char* parents[];
 	int count=0, isfilter;
+	device_t dev;
 
 	dmd = (struct driver_module_data *)arg;
 	drv_intnl = dmd->dmd_driver;
@@ -4278,7 +4327,17 @@
 		}
 
 		if(drv_intnl->flags & DR_REQDEV){ /*restrict to DR_LOWEST? */
-			make_device (root_bus, DRIVERNAME(driver), -1, driver);
+			dev = make_device (root_bus, DRIVERNAME(driver), -1/*, driver*/);
+			device_set_driver(dev, driver);
+			/*if (!hasclass)*/
+			device_set_devclass(child, dl->driver->name);
+
+			/* Fetch any flags for the device before probing.
+			resource_int_value(dl->driver->name, child->unit,
+			    "flags", &child->devflags);
+			*/
+
+			result = DEVICE_PROBE(dev);
 			/* todo: set all parents for device
 			 * parents are all devices (alive) in parent
 			 * devclasses


More information about the p4-projects mailing list