summaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2007-08-14 15:15:12 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-12 14:51:01 -0700
commit7eff2e7a8b65c25920207324e56611150eb1cd9a (patch)
tree02a0eeba9d25d996233e30c18f258dfae0ae2139 /arch/powerpc
parent8380770c842faef3001e44662953d64ad9a93663 (diff)
Driver core: change add_uevent_var to use a struct
This changes the uevent buffer functions to use a struct instead of a long list of parameters. It does no longer require the caller to do the proper buffer termination and size accounting, which is currently wrong in some places. It fixes a known bug where parts of the uevent environment are overwritten because of wrong index calculations. Many thanks to Mathieu Desnoyers for finding bugs and improving the error handling. Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Cc: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/of_device.c37
-rw-r--r--arch/powerpc/kernel/vio.c16
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c9
3 files changed, 16 insertions, 46 deletions
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 89b911e83c0..8f3db32fac8 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -57,26 +57,21 @@ ssize_t of_device_get_modalias(struct of_device *ofdev,
return tsize;
}
-int of_device_uevent(struct device *dev,
- char **envp, int num_envp, char *buffer, int buffer_size)
+int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct of_device *ofdev;
const char *compat;
- int i = 0, length = 0, seen = 0, cplen, sl;
+ int seen = 0, cplen, sl;
if (!dev)
return -ENODEV;
ofdev = to_of_device(dev);
- if (add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "OF_NAME=%s", ofdev->node->name))
+ if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name))
return -ENOMEM;
- if (add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "OF_TYPE=%s", ofdev->node->type))
+ if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type))
return -ENOMEM;
/* Since the compatible field can contain pretty much anything
@@ -85,9 +80,7 @@ int of_device_uevent(struct device *dev,
compat = of_get_property(ofdev->node, "compatible", &cplen);
while (compat && *compat && cplen > 0) {
- if (add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "OF_COMPATIBLE_%d=%s", seen, compat))
+ if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
return -ENOMEM;
sl = strlen (compat) + 1;
@@ -96,25 +89,17 @@ int of_device_uevent(struct device *dev,
seen++;
}
- if (add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "OF_COMPATIBLE_N=%d", seen))
+ if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
return -ENOMEM;
/* modalias is trickier, we add it in 2 steps */
- if (add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "MODALIAS="))
+ if (add_uevent_var(env, "MODALIAS="))
return -ENOMEM;
-
- sl = of_device_get_modalias(ofdev, &buffer[length-1],
- buffer_size-length);
- if (sl >= (buffer_size-length))
+ sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
+ sizeof(env->buf) - env->buflen);
+ if (sl >= (sizeof(env->buf) - env->buflen))
return -ENOMEM;
-
- length += sl;
-
- envp[i] = NULL;
+ env->buflen += sl;
return 0;
}
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index cb22a3557c4..19a5656001c 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -317,30 +317,20 @@ static int vio_bus_match(struct device *dev, struct device_driver *drv)
return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
}
-static int vio_hotplug(struct device *dev, char **envp, int num_envp,
- char *buffer, int buffer_size)
+static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env)
{
const struct vio_dev *vio_dev = to_vio_dev(dev);
struct device_node *dn;
const char *cp;
- int length;
-
- if (!num_envp)
- return -ENOMEM;
dn = dev->archdata.of_node;
if (!dn)
return -ENODEV;
- cp = of_get_property(dn, "compatible", &length);
+ cp = of_get_property(dn, "compatible", NULL);
if (!cp)
return -ENODEV;
- envp[0] = buffer;
- length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s",
- vio_dev->type, cp);
- if ((buffer_size - length) <= 0)
- return -ENOMEM;
- envp[1] = NULL;
+ add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, cp);
return 0;
}
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 4bb634a17e4..ea0b2c79041 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -437,18 +437,13 @@ static void ps3_system_bus_shutdown(struct device *_dev)
dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
}
-static int ps3_system_bus_uevent(struct device *_dev, char **envp,
- int num_envp, char *buffer, int buffer_size)
+static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *env)
{
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
int i = 0, length = 0;
- if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
- &length, "MODALIAS=ps3:%d",
- dev->match_id))
+ if (add_uevent_var(env, "MODALIAS=ps3:%d", dev->match_id))
return -ENOMEM;
-
- envp[i] = NULL;
return 0;
}