diff options
author | Kay Sievers <kay.sievers@vrfy.org> | 2007-08-14 09:15:12 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:51:01 -0400 |
commit | 7eff2e7a8b65c25920207324e56611150eb1cd9a (patch) | |
tree | 02a0eeba9d25d996233e30c18f258dfae0ae2139 /arch/powerpc/kernel/of_device.c | |
parent | 8380770c842faef3001e44662953d64ad9a93663 (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/kernel/of_device.c')
-rw-r--r-- | arch/powerpc/kernel/of_device.c | 37 |
1 files changed, 11 insertions, 26 deletions
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 89b911e83c04..8f3db32fac8b 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, | |||
57 | return tsize; | 57 | return tsize; |
58 | } | 58 | } |
59 | 59 | ||
60 | int of_device_uevent(struct device *dev, | 60 | int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
61 | char **envp, int num_envp, char *buffer, int buffer_size) | ||
62 | { | 61 | { |
63 | struct of_device *ofdev; | 62 | struct of_device *ofdev; |
64 | const char *compat; | 63 | const char *compat; |
65 | int i = 0, length = 0, seen = 0, cplen, sl; | 64 | int seen = 0, cplen, sl; |
66 | 65 | ||
67 | if (!dev) | 66 | if (!dev) |
68 | return -ENODEV; | 67 | return -ENODEV; |
69 | 68 | ||
70 | ofdev = to_of_device(dev); | 69 | ofdev = to_of_device(dev); |
71 | 70 | ||
72 | if (add_uevent_var(envp, num_envp, &i, | 71 | if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name)) |
73 | buffer, buffer_size, &length, | ||
74 | "OF_NAME=%s", ofdev->node->name)) | ||
75 | return -ENOMEM; | 72 | return -ENOMEM; |
76 | 73 | ||
77 | if (add_uevent_var(envp, num_envp, &i, | 74 | if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type)) |
78 | buffer, buffer_size, &length, | ||
79 | "OF_TYPE=%s", ofdev->node->type)) | ||
80 | return -ENOMEM; | 75 | return -ENOMEM; |
81 | 76 | ||
82 | /* Since the compatible field can contain pretty much anything | 77 | /* Since the compatible field can contain pretty much anything |
@@ -85,9 +80,7 @@ int of_device_uevent(struct device *dev, | |||
85 | 80 | ||
86 | compat = of_get_property(ofdev->node, "compatible", &cplen); | 81 | compat = of_get_property(ofdev->node, "compatible", &cplen); |
87 | while (compat && *compat && cplen > 0) { | 82 | while (compat && *compat && cplen > 0) { |
88 | if (add_uevent_var(envp, num_envp, &i, | 83 | if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) |
89 | buffer, buffer_size, &length, | ||
90 | "OF_COMPATIBLE_%d=%s", seen, compat)) | ||
91 | return -ENOMEM; | 84 | return -ENOMEM; |
92 | 85 | ||
93 | sl = strlen (compat) + 1; | 86 | sl = strlen (compat) + 1; |
@@ -96,25 +89,17 @@ int of_device_uevent(struct device *dev, | |||
96 | seen++; | 89 | seen++; |
97 | } | 90 | } |
98 | 91 | ||
99 | if (add_uevent_var(envp, num_envp, &i, | 92 | if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) |
100 | buffer, buffer_size, &length, | ||
101 | "OF_COMPATIBLE_N=%d", seen)) | ||
102 | return -ENOMEM; | 93 | return -ENOMEM; |
103 | 94 | ||
104 | /* modalias is trickier, we add it in 2 steps */ | 95 | /* modalias is trickier, we add it in 2 steps */ |
105 | if (add_uevent_var(envp, num_envp, &i, | 96 | if (add_uevent_var(env, "MODALIAS=")) |
106 | buffer, buffer_size, &length, | ||
107 | "MODALIAS=")) | ||
108 | return -ENOMEM; | 97 | return -ENOMEM; |
109 | 98 | sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1], | |
110 | sl = of_device_get_modalias(ofdev, &buffer[length-1], | 99 | sizeof(env->buf) - env->buflen); |
111 | buffer_size-length); | 100 | if (sl >= (sizeof(env->buf) - env->buflen)) |
112 | if (sl >= (buffer_size-length)) | ||
113 | return -ENOMEM; | 101 | return -ENOMEM; |
114 | 102 | env->buflen += sl; | |
115 | length += sl; | ||
116 | |||
117 | envp[i] = NULL; | ||
118 | 103 | ||
119 | return 0; | 104 | return 0; |
120 | } | 105 | } |