[PATCH] openfirmware: implement hotplug for macio devices
authorJeff Mahoney <jeffm@suse.com>
Wed, 6 Jul 2005 19:45:09 +0000 (15:45 -0400)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 6 Jul 2005 19:55:20 +0000 (12:55 -0700)
This adds the hotplug routine for generating hotplug events when devices
are seen on the macio bus.  It uses the attributed created by the sysfs
nodes to generate the hotplug environment vars for userspace.

Since the characters allowed inside the 'compatible' field are NUL
terminated, they are exported as individual OF_COMPATIBLE_# variables,
with OF_COMPATIBLE_N maintaining a count of how many there are.

In order for hotplug to work with macio devices, patches to
module-init-tools and hotplug must be applied.  Those patches are
available at:

ftp://ftp.suse.com/pub/people/jeffm/linux/macio-hotplug/

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/macintosh/macio_asic.c

index 7fa369cfccebfd627c3c153f72d8159f8d7d8918..1ee003346923d7ca6a74a1fd0e6ba4ab7c773083 100644 (file)
@@ -126,11 +126,82 @@ static int macio_device_resume(struct device * dev)
        return 0;
 }
 
+static int macio_hotplug (struct device *dev, char **envp, int num_envp,
+                          char *buffer, int buffer_size)
+{
+       struct macio_dev * macio_dev;
+       struct of_device * of;
+       char *scratch, *compat;
+       int i = 0;
+       int length = 0;
+       int cplen, seen = 0;
+
+       if (!dev)
+               return -ENODEV;
+
+       macio_dev = to_macio_device(dev);
+       if (!macio_dev)
+               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;
+       ++length;
+       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;
+       scratch += length;
+
+        /* Since the compatible field can contain pretty much anything
+         * it's not really legal to split it out with commas. We split it
+         * up using a number of environment variables instead. */
+
+       compat = (char *) get_property(of->node, "compatible", &cplen);
+       while (compat && cplen > 0) {
+               int l;
+                envp[i++] = scratch;
+               length += scnprintf (scratch, buffer_size - length,
+                                    "OF_COMPATIBLE_%d=%s", seen, compat);
+               if ((buffer_size - length <= 0) || (i >= num_envp))
+                       return -ENOMEM;
+               length++;
+               scratch += length;
+               l = strlen (compat) + 1;
+               compat += l;
+               cplen -= l;
+               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;
+       scratch += length;
+
+       envp[i] = NULL;
+
+       return 0;
+}
+
 extern struct device_attribute macio_dev_attrs[];
 
 struct bus_type macio_bus_type = {
        .name   = "macio",
        .match  = macio_bus_match,
+       .hotplug = macio_hotplug,
        .suspend        = macio_device_suspend,
        .resume = macio_device_resume,
        .dev_attrs = macio_dev_attrs,