Subject: Device Properties: The Last Incarnation #2
To: None <tech-kern@netbsd.org>
From: None <eeh@netbsd.org>
List: tech-kern
Date: 03/03/2001 01:58:18
This is an example of how properties could be used
to attach devices.  SBus and zs have been modified
to use properties.  Unfortunately, zstty pokes at
zs private structures, so it also needed to be modified
slightly.

Eduardo

Index: dev/sbus/sbusvar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/sbus/sbusvar.h,v
retrieving revision 1.11
diff -u -r1.11 sbusvar.h
--- dev/sbus/sbusvar.h	2000/11/01 06:18:45	1.11
+++ dev/sbus/sbusvar.h	2001/03/03 01:44:09
@@ -105,7 +105,7 @@
 
 void	sbus_establish __P((struct sbusdev *, struct device *));
 
-int	sbus_setup_attach_args __P((
+struct device *sbus_setup_attach_args __P((
 		struct sbus_softc *,
 		bus_space_tag_t,
 		bus_dma_tag_t,
Index: arch/sparc64/dev/sbus.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/dev/sbus.c,v
retrieving revision 1.39
diff -u -r1.39 sbus.c
--- arch/sparc64/dev/sbus.c	2000/12/06 01:47:49	1.39
+++ arch/sparc64/dev/sbus.c	2001/03/03 01:44:10
@@ -294,7 +294,9 @@
 	printf(": clock = %s MHz\n", clockfreq(sc->sc_clockfreq));
 
 	sbt = sbus_alloc_bustag(sc);
+	dev_setprop(self, "bustag", &sbt, sizeof(sbt), PROP_WAIT);
 	sc->sc_dmatag = sbus_alloc_dmatag(sc);
+	dev_setprop(self, "dmatag", &sc->sc_dmatag, sizeof(sc->sc_dmatag), PROP_WAIT);
 
 	/*
 	 * Get the SBus burst transfer size if burst transfers are supported
@@ -333,18 +335,20 @@
 	node0 = firstchild(node);
 	for (node = node0; node; node = nextsibling(node)) {
 		char *name = getpropstring(node, "name");
+		struct device *child;
 
-		if (sbus_setup_attach_args(sc, sbt, sc->sc_dmatag,
-					   node, &sa) != 0) {
+		if ((child = sbus_setup_attach_args(sc, sbt, sc->sc_dmatag,
+						    node, &sa)) == 0) {
 			printf("sbus_attach: %s: incomplete\n", name);
 			continue;
 		}
-		(void) config_found(&sc->sc_dev, (void *)&sa, sbus_print);
+		(void) config_found_sad(&sc->sc_dev, (void *)&sa, sbus_print, 
+					NULL, child);
 		sbus_destroy_attach_args(&sa);
 	}
 }
 
-int
+struct device *
 sbus_setup_attach_args(sc, bustag, dmatag, node, sa)
 	struct sbus_softc	*sc;
 	bus_space_tag_t		bustag;
@@ -352,20 +356,30 @@
 	int			node;
 	struct sbus_attach_args	*sa;
 {
-	/*struct	sbus_reg sbusreg;*/
-	/*int	base;*/
+	struct device *dev;
 	int	error;
 	int n;
 
+	/* XXX the following assumes that dev == softc. */
+	dev = dev_config_create((struct device *)sc, PROP_WAIT);
+	if (!dev) 
+		return (NULL);
+	dev_setprop(dev, "node", &node, sizeof(node), PROP_WAIT);
+
 	bzero(sa, sizeof(struct sbus_attach_args));
 	error = getprop(node, "name", 1, &n, (void **)&sa->sa_name);
-	if (error != 0)
-		return (error);
+	if (error != 0) {
+		config_detach(dev, 0);
+		return (NULL);
+	}
 	sa->sa_name[n] = '\0';
+	dev_setprop(dev, "name", (void *)sa->sa_name, 
+		    strlen(sa->sa_name)+1, PROP_WAIT|PROP_STRING);
 
 	sa->sa_bustag = bustag;
 	sa->sa_dmatag = dmatag;
 	sa->sa_node = node;
+	dev_setprop(dev, "node", &node, sizeof(node), PROP_WAIT);
 	sa->sa_frequency = sc->sc_clockfreq;
 
 	error = getprop(node, "reg", sizeof(struct sbus_reg),
@@ -375,8 +389,10 @@
 		if (error != ENOENT ||
 		    !node_has_property(node, "device_type") ||
 		    strcmp(getpropstringA(node, "device_type", buf),
-			   "hierarchical") != 0)
-			return (error);
+			   "hierarchical") != 0) {
+			config_detach(dev, 0);
+			return (NULL);
+		}
 	}
 	for (n = 0; n < sa->sa_nreg; n++) {
 		/* Convert to relative addressing, if necessary */
@@ -386,17 +402,36 @@
 			sa->sa_reg[n].sbr_offset = SBUS_ABS_TO_OFFSET(base);
 		}
 	}
+	/* Whole `reg' for those w/multiple registers */
+	dev_setprop(dev, "reg", (void *)sa->sa_reg, 
+		    sa->sa_nreg * sizeof(struct sbus_reg), PROP_WAIT);
+
+	dev_setprop(dev, "slot", (void *)&sa->sa_reg[0].sbr_slot, 
+		    sizeof(sa->sa_reg[0].sbr_slot), PROP_WAIT);
+	dev_setprop(dev, "offset", (void *)&sa->sa_reg[0].sbr_offset, 
+		    sizeof(sa->sa_reg[0].sbr_offset), PROP_WAIT);
+	dev_setprop(dev, "size", (void *)&sa->sa_reg[0].sbr_size, 
+		    sizeof(sa->sa_reg[0].sbr_size), PROP_WAIT);
 
 	if ((error = sbus_get_intr(sc, node, &sa->sa_intr, &sa->sa_nintr,
-	    sa->sa_slot)) != 0)
-		return (error);
+				   sa->sa_slot)) != 0) {
+		config_detach(dev, 0);
+		return (NULL);
+	}
+	dev_setprop(dev, "sbus-intr", (void *)sa->sa_intr, 
+		    sa->sa_nintr * sizeof(struct sbus_intr), PROP_WAIT);
 
 	error = getprop(node, "address", sizeof(u_int32_t),
 			 &sa->sa_npromvaddrs, (void **)&sa->sa_promvaddrs);
-	if (error != 0 && error != ENOENT)
-		return (error);
+	if (sa->sa_npromvaddrs)
+		dev_setprop(dev, "address", (void *)sa->sa_promvaddrs, 
+			    sa->sa_npromvaddrs * sizeof(u_int32_t), PROP_WAIT);
+	if (error != 0 && error != ENOENT) {
+		config_detach(dev, 0);
+		return (NULL);
+	}
 
-	return (0);
+	return (dev);
 }
 
 void
Index: arch/sparc64/dev/zs.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/dev/zs.c,v
retrieving revision 1.28
diff -u -r1.28 zs.c
--- arch/sparc64/dev/zs.c	2000/12/03 14:49:50	1.28
+++ arch/sparc64/dev/zs.c	2001/03/03 01:44:10
@@ -157,20 +157,14 @@
  ****************************************************************/
 
 /* Definition of the driver for autoconfig. */
-static int  zs_match_mainbus __P((struct device *, struct cfdata *, void *));
-static void zs_attach_mainbus __P((struct device *, struct device *, void *));
+static int  zs_match_sbus __P((struct device *, struct cfdata *, void *));
+static void zs_attach_sbus __P((struct device *, struct device *, void *));
 
-static void zs_attach __P((struct zsc_softc *, struct zsdevice *, int));
+static void zs_attach __P((struct device *, struct zsdevice *, int));
 static int  zs_print __P((void *, const char *name));
 
-/* Do we really need this ? */
-struct cfattach zs_ca = {
-	sizeof(struct zsc_softc), zs_match_mainbus, zs_attach_mainbus
-};
-
-struct cfattach zs_mainbus_ca = {
-	sizeof(struct zsc_softc), zs_match_mainbus, zs_attach_mainbus
-};
+/* XXXX -- struct device should be removed from struct zsc_softc */
+DEV_CFA_DECL(zs_ca, sizeof(struct zsc_softc), zs_match_sbus, zs_attach_sbus);
 
 extern struct cfdriver zs_cd;
 extern int stdinnode;
@@ -194,38 +188,52 @@
  * Is the zs chip present?
  */
 static int
-zs_match_mainbus(parent, cf, aux)
+zs_match_sbus(parent, cf, aux)
 	struct device *parent;
 	struct cfdata *cf;
 	void *aux;
 {
-	struct sbus_attach_args *sa = aux;
+	struct device *dev = (struct device *)aux;
+	char name[32];
 
-	if (strcmp(cf->cf_driver->cd_name, sa->sa_name) != 0)
+	dev_getprop(dev, "name", &name, sizeof(name), 0);
+
+	printf("cd_name %s name %s\n", cf->cf_driver->cd_name, name);
+	if (strcmp(cf->cf_driver->cd_name, name) != 0)
 		return (0);
 
 	return (1);
 }
 
 static void
-zs_attach_mainbus(parent, self, aux)
+zs_attach_sbus(parent, self, aux)
 	struct device *parent;
 	struct device *self;
 	void *aux;
 {
-	struct zsc_softc *zsc = (void *) self;
-	struct sbus_attach_args *sa = aux;
-	int zs_unit = zsc->zsc_dev.dv_unit;
+	struct zsc_softc *zsc = (void *)DEV_PRIVATE(self);
+	int zs_unit = self->dv_unit;
+	u_int32_t intr_pri;
 
-	if (sa->sa_nintr == 0) {
+	if (dev_getprop(self, "sbus-intr", &intr_pri, sizeof(intr_pri), 0) == -1) {
 		printf(" no interrupt lines\n");
 		return;
 	}
 
+	/* Fetch important properties */
+	dev_getprop(self, "node", &zsc->zsc_node, sizeof(zsc->zsc_node), 0);
+	zsc->zsc_promunit = getpropint(zsc->zsc_node, "slave", -2);
+	dev_getprop(self, "bustag", &zsc->zsc_bustag, 
+		    sizeof(zsc->zsc_bustag), PROP_SEARCH);
+	dev_getprop(self, "dmatag", &zsc->zsc_dmatag, 
+		    sizeof(zsc->zsc_dmatag), PROP_SEARCH);
+
 	/* Use the mapping setup by the Sun PROM. */
 	if (zsaddr[zs_unit] == NULL) {
+		u_int32_t addr;
+		
 		/* Only map registers once. */
-		if (sa->sa_npromvaddrs) {
+		if ((dev_getprop(self, "address", &addr, sizeof(addr), 0) != -1)) {
 			/*
 			 * We're converting from a 32-bit pointer to a 64-bit
 			 * pointer.  Since the 32-bit entity is negative, but
@@ -238,13 +246,17 @@
 			 */
 			zsaddr[zs_unit] = 
 				(struct zsdevice *)
-				(uintptr_t)sa->sa_promvaddrs[0];
+				(uintptr_t)addr;
 		} else {
 			bus_space_handle_t kvaddr;
+			u_int32_t slot, offset, size;
+			
+			/* Get props */
+			dev_getprop(self, "slot", &slot, sizeof(slot), 0);
+			dev_getprop(self, "offset", &offset, sizeof(offset), 0);
+			dev_getprop(self, "size", &size, sizeof(size), 0);
 
-			if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
-					 sa->sa_offset,
-					 sa->sa_size,
+			if (sbus_bus_map(zsc->zsc_bustag, slot, offset, size,
 					 BUS_SPACE_MAP_LINEAR,
 					 0, &kvaddr) != 0) {
 				printf("%s @ sbus: cannot map registers\n",
@@ -255,11 +267,7 @@
 				(uintptr_t)kvaddr;
 		}
 	}
-	zsc->zsc_bustag = sa->sa_bustag;
-	zsc->zsc_dmatag = sa->sa_dmatag;
-	zsc->zsc_promunit = getpropint(sa->sa_node, "slave", -2);
-	zsc->zsc_node = sa->sa_node;
-	zs_attach(zsc, zsaddr[zs_unit], sa->sa_pri);
+	zs_attach(self, zsaddr[zs_unit], intr_pri);
 }
 
 /*
@@ -269,11 +277,12 @@
  * SOFT CARRIER, AND keyboard PROPERTY FOR KEYBOARD/MOUSE?
  */
 static void
-zs_attach(zsc, zsd, pri)
-	struct zsc_softc *zsc;
+zs_attach(self, zsd, pri)
+	struct device *self;
 	struct zsdevice *zsd;
 	int pri;
 {
+	struct zsc_softc *zsc = DEV_PRIVATE(self);
 	struct zsc_attach_args zsc_args;
 	struct zs_chanstate *cs;
 	int s, channel, softpri = PIL_TTY;
@@ -352,7 +361,7 @@
 		 * The child attach will setup the hardware.
 		 */
 		if (!(child = 
-		      config_found(&zsc->zsc_dev, (void *)&zsc_args, zs_print))) {
+		      config_found(self, (void *)&zsc_args, zs_print))) {
 			/* No sub-driver.  Just reset it. */
 			u_char reset = (channel == 0) ?
 				ZSWR9_A_RESET : ZSWR9_B_RESET;
@@ -409,7 +418,7 @@
 		panic("zsattach: could not establish soft interrupt\n");
 
 	evcnt_attach_dynamic(&zsc->zsc_intrcnt, EVCNT_TYPE_INTR, NULL,
-	    zsc->zsc_dev.dv_xname, "intr");
+	    self->dv_xname, "intr");
 
 
 	/*
@@ -477,7 +486,7 @@
 	rval = 0;
 	for (unit = 0; unit < zs_cd.cd_ndevs; unit++) {
 
-		zsc = zs_cd.cd_devs[unit];
+		zsc = DEV_PRIVATE((struct device *)zs_cd.cd_devs[unit]);
 		if (zsc == NULL)
 			continue;
 		rval = (zshard((void *)zsc) || rval);
Index: dev/ic/z8530tty.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/z8530tty.c,v
retrieving revision 1.72
diff -u -r1.72 z8530tty.c
--- dev/ic/z8530tty.c	2000/11/08 23:13:03	1.72
+++ dev/ic/z8530tty.c	2001/03/03 01:44:11
@@ -268,8 +268,8 @@
 	void   *aux;
 
 {
-	struct zsc_softc *zsc = (void *) parent;
-	struct zstty_softc *zst = (void *) self;
+	struct zsc_softc *zsc = (void *)DEV_PRIVATE(parent);
+	struct zstty_softc *zst = (void *)DEV_PRIVATE(self);
 	struct cfdata *cf = self->dv_cfdata;
 	struct zsc_attach_args *args = aux;
 	struct zs_chanstate *cs;
@@ -418,7 +418,8 @@
 zstty(dev)
 	dev_t dev;
 {
-	struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev));
+	struct device *d = device_lookup(&zstty_cd, ZSUNIT(dev));
+	struct zstty_softc *zst = DEV_PRIVATE(d);
 
 	return (zst->zst_tty);
 }
@@ -483,13 +484,15 @@
 	int mode;
 	struct proc *p;
 {
+	struct device *d;
 	struct zstty_softc *zst;
 	struct zs_chanstate *cs;
 	struct tty *tp;
 	int s, s2;
 	int error;
-
-	zst = device_lookup(&zstty_cd, ZSUNIT(dev));
+	
+	d = device_lookup(&zstty_cd, ZSUNIT(dev));
+	zst = DEV_PRIVATE(d);
 	if (zst == NULL)
 		return (ENXIO);
 
@@ -633,7 +636,8 @@
 	int mode;
 	struct proc *p;
 {
-	struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev));
+	struct device *d = device_lookup(&zstty_cd, ZSUNIT(dev));
+	struct zstty_softc *zst = DEV_PRIVATE(d);
 	struct tty *tp = zst->zst_tty;
 
 	/* XXX This is for cons.c. */
@@ -664,7 +668,8 @@
 	struct uio *uio;
 	int flags;
 {
-	struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev));
+	struct device *d = device_lookup(&zstty_cd, ZSUNIT(dev));
+	struct zstty_softc *zst = DEV_PRIVATE(d);
 	struct tty *tp = zst->zst_tty;
 
 	return ((*tp->t_linesw->l_read)(tp, uio, flags));
@@ -676,7 +681,8 @@
 	struct uio *uio;
 	int flags;
 {
-	struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev));
+	struct device *d = device_lookup(&zstty_cd, ZSUNIT(dev));
+	struct zstty_softc *zst = DEV_PRIVATE(d);
 	struct tty *tp = zst->zst_tty;
 
 	return ((*tp->t_linesw->l_write)(tp, uio, flags));
@@ -690,7 +696,8 @@
 	int flag;
 	struct proc *p;
 {
-	struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev));
+	struct device *d = device_lookup(&zstty_cd, ZSUNIT(dev));
+	struct zstty_softc *zst = DEV_PRIVATE(d);
 	struct zs_chanstate *cs = zst->zst_cs;
 	struct tty *tp = zst->zst_tty;
 	int error;
@@ -909,7 +916,8 @@
 zsstart(tp)
 	struct tty *tp;
 {
-	struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+	struct device *d = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+	struct zstty_softc *zst = DEV_PRIVATE(d);
 	struct zs_chanstate *cs = zst->zst_cs;
 	int s;
 
@@ -972,7 +980,8 @@
 	struct tty *tp;
 	int flag;
 {
-	struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+	struct device *d = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+	struct zstty_softc *zst = DEV_PRIVATE(d);
 	int s;
 
 	s = splzs();
@@ -996,7 +1005,8 @@
 	struct tty *tp;
 	struct termios *t;
 {
-	struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+	struct device *d = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+	struct zstty_softc *zst = DEV_PRIVATE(d);
 	struct zs_chanstate *cs = zst->zst_cs;
 	int ospeed, cflag;
 	u_char tmp3, tmp4, tmp5;
@@ -1296,7 +1306,8 @@
 	struct tty *tp;
 	int block;
 {
-	struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+	struct device *d = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+	struct zstty_softc *zst = DEV_PRIVATE(d);
 	struct zs_chanstate *cs = zst->zst_cs;
 	int s;