[PATCH] MODALIAS= for macio

Prodive a MODALIAS= enviroment variable for devices on the mac-io bus.
Change the buffer length counter to not waste memory by advancing the
pointer for the next string too far.  Tested on an ibook1 with modular
pmac_zilog.

Signed-off-by: Olaf Hering <olh@suse.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index ed6d317..69596f6 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -140,10 +140,9 @@
 {
 	struct macio_dev * macio_dev;
 	struct of_device * of;
-	char *scratch, *compat;
+	char *scratch, *compat, *compat2;
 	int i = 0;
-	int length = 0;
-	int cplen, seen = 0;
+	int length, cplen, cplen2, seen = 0;
 
 	if (!dev)
 		return -ENODEV;
@@ -153,23 +152,22 @@
 		return -ENODEV;
 
 	of = &macio_dev->ofdev;
-	scratch = buffer;
 
 	/* stuff we want to pass to /sbin/hotplug */
-	envp[i++] = scratch;
-	length += scnprintf (scratch, buffer_size - length, "OF_NAME=%s",
-	                     of->node->name);
-	if ((buffer_size - length <= 0) || (i >= num_envp))
-		return -ENOMEM;
+	envp[i++] = scratch = buffer;
+	length = scnprintf (scratch, buffer_size, "OF_NAME=%s", of->node->name);
 	++length;
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
 	scratch += length;
 
 	envp[i++] = scratch;
-	length += scnprintf (scratch, buffer_size - length, "OF_TYPE=%s",
-	                     of->node->type);
-	if ((buffer_size - length <= 0) || (i >= num_envp))
-		return -ENOMEM;
+	length = scnprintf (scratch, buffer_size, "OF_TYPE=%s", of->node->type);
 	++length;
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
 	scratch += length;
 
         /* Since the compatible field can contain pretty much anything
@@ -177,29 +175,55 @@
          * up using a number of environment variables instead. */
 
 	compat = (char *) get_property(of->node, "compatible", &cplen);
+	compat2 = compat;
+	cplen2= cplen;
 	while (compat && cplen > 0) {
-		int l;
                 envp[i++] = scratch;
-		length += scnprintf (scratch, buffer_size - length,
+		length = scnprintf (scratch, buffer_size,
 		                     "OF_COMPATIBLE_%d=%s", seen, compat);
-		if ((buffer_size - length <= 0) || (i >= num_envp))
+		++length;
+		buffer_size -= length;
+		if ((buffer_size <= 0) || (i >= num_envp))
 			return -ENOMEM;
-		length++;
 		scratch += length;
-		l = strlen (compat) + 1;
-		compat += l;
-		cplen -= l;
+		length = strlen (compat) + 1;
+		compat += length;
+		cplen -= length;
 		seen++;
 	}
 
 	envp[i++] = scratch;
-	length += scnprintf (scratch, buffer_size - length,
-	                     "OF_COMPATIBLE_N=%d", seen);
-	if ((buffer_size - length <= 0) || (i >= num_envp))
-		return -ENOMEM;
+	length = scnprintf (scratch, buffer_size, "OF_COMPATIBLE_N=%d", seen);
 	++length;
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
 	scratch += length;
 
+	envp[i++] = scratch;
+	length = scnprintf (scratch, buffer_size, "MODALIAS=of:N%sT%s",
+			of->node->name, of->node->type);
+	/* overwrite '\0' */
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	scratch += length;
+
+	if (!compat2) {
+		compat2 = "";
+		cplen2 = 1;
+	}
+	while (cplen2 > 0) {
+		length = snprintf (scratch, buffer_size, "C%s", compat2);
+		buffer_size -= length;
+		if (buffer_size <= 0)
+			return -ENOMEM;
+		scratch += length;
+		length = strlen (compat2) + 1;
+		compat2 += length;
+		cplen2 -= length;
+	}
+
 	envp[i] = NULL;
 
 	return 0;