Subject: Referencing child devices from prop dictionary
To: None <tech-kern@NetBSD.org>
From: Jared D. McNeill <jared.mcneill@alcatel-lucent.com>
List: tech-kern
Date: 06/14/2007 12:05:54
--Apple-Mail-7--480991606
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	delsp=yes;
	format=flowed

Heyas folks --

I have an application that needs to be able to walk the device tree  
from userspace. Is the attached patch OK to commit?

Cheers,
Jared


--Apple-Mail-7--480991606
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0777;
	name=autoconf.diff
Content-Disposition: attachment;
	filename=autoconf.diff

--- /refsrc/src/sys/kern/subr_autoconf.c	2007-03-06 22:06:54.000000000 -0500
+++ subr_autoconf.c	2007-06-14 08:42:25.000000000 -0400
@@ -950,6 +950,7 @@
 	int myunit;
 	char num[10];
 	device_t dev;
+	prop_array_t children;
 	const struct cfiattrdata *ia;
 
 	cd = config_cfdriver_lookup(cf->cf_name);
@@ -1012,6 +1013,9 @@
 	}
 	dev->dv_properties = prop_dictionary_create();
 	KASSERT(dev->dv_properties != NULL);
+	children = prop_array_create();
+	KASSERT(children != NULL);
+	prop_dictionary_set(dev->dv_properties, "child-devices", children);
 
 	return (dev);
 }
@@ -1073,10 +1077,20 @@
 		aprint_naive("%s (root)", dev->dv_xname);
 		aprint_normal("%s (root)", dev->dv_xname);
 	} else {
+		prop_array_t children;
+		prop_string_t cdevname;
+
 		aprint_naive("%s at %s", dev->dv_xname, parent->dv_xname);
 		aprint_normal("%s at %s", dev->dv_xname, parent->dv_xname);
 		if (print)
 			(void) (*print)(aux, NULL);
+
+		children = (prop_array_t)prop_dictionary_get(
+					   parent->dv_properties,
+					   "child-devices");
+		cdevname = prop_string_create_cstring(dev->dv_xname);
+		if (cdevname != NULL)
+			prop_array_add(children, cdevname);
 	}
 
 	/*
@@ -1239,6 +1253,34 @@
 	}
 #endif
 
+	/* remove child device references from parent dev properties */
+	if (dev->dv_parent) {
+		const char *cdevname;
+		prop_array_t children;
+		prop_object_iterator_t it;
+		prop_object_t obj;
+		prop_string_t str;
+		int idx;
+
+		children = (prop_array_t)prop_dictionary_get(
+		    dev->dv_parent->dv_properties, "child-devices");
+		if (children) {
+			idx = 0;
+			it = prop_array_iterator(children);
+			while ((obj = prop_object_iterator_next(it)) != NULL) {
+				str = (prop_string_t)obj;
+				cdevname = prop_string_cstring_nocopy(str);
+				if (cdevname &&
+				    strcmp(cdevname, dev->dv_xname) == 0) {
+					prop_array_remove(children, idx);
+					break;
+				}
+				++idx;
+			}
+			prop_object_iterator_release(it);
+		}
+	}
+
 	/* notify the parent that the child is gone */
 	if (dev->dv_parent) {
 		device_t p = dev->dv_parent;

--Apple-Mail-7--480991606--