Commit 7eff2e7a8b65c25920207324e56611150eb1cd9a

Authored by Kay Sievers
Committed by Greg Kroah-Hartman
1 parent 8380770c84

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>

Showing 47 changed files with 300 additions and 636 deletions Side-by-side Diff

arch/ia64/sn/kernel/tiocx.c
... ... @@ -66,8 +66,7 @@
66 66  
67 67 }
68 68  
69   -static int tiocx_uevent(struct device *dev, char **envp, int num_envp,
70   - char *buffer, int buffer_size)
  69 +static int tiocx_uevent(struct device *dev, struct kobj_uevent_env *env)
71 70 {
72 71 return -ENODEV;
73 72 }
arch/powerpc/kernel/of_device.c
... ... @@ -57,26 +57,21 @@
57 57 return tsize;
58 58 }
59 59  
60   -int of_device_uevent(struct device *dev,
61   - char **envp, int num_envp, char *buffer, int buffer_size)
  60 +int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
62 61 {
63 62 struct of_device *ofdev;
64 63 const char *compat;
65   - int i = 0, length = 0, seen = 0, cplen, sl;
  64 + int seen = 0, cplen, sl;
66 65  
67 66 if (!dev)
68 67 return -ENODEV;
69 68  
70 69 ofdev = to_of_device(dev);
71 70  
72   - if (add_uevent_var(envp, num_envp, &i,
73   - buffer, buffer_size, &length,
74   - "OF_NAME=%s", ofdev->node->name))
  71 + if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name))
75 72 return -ENOMEM;
76 73  
77   - if (add_uevent_var(envp, num_envp, &i,
78   - buffer, buffer_size, &length,
79   - "OF_TYPE=%s", ofdev->node->type))
  74 + if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type))
80 75 return -ENOMEM;
81 76  
82 77 /* Since the compatible field can contain pretty much anything
... ... @@ -85,9 +80,7 @@
85 80  
86 81 compat = of_get_property(ofdev->node, "compatible", &cplen);
87 82 while (compat && *compat && cplen > 0) {
88   - if (add_uevent_var(envp, num_envp, &i,
89   - buffer, buffer_size, &length,
90   - "OF_COMPATIBLE_%d=%s", seen, compat))
  83 + if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
91 84 return -ENOMEM;
92 85  
93 86 sl = strlen (compat) + 1;
94 87  
95 88  
96 89  
... ... @@ -96,25 +89,17 @@
96 89 seen++;
97 90 }
98 91  
99   - if (add_uevent_var(envp, num_envp, &i,
100   - buffer, buffer_size, &length,
101   - "OF_COMPATIBLE_N=%d", seen))
  92 + if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
102 93 return -ENOMEM;
103 94  
104 95 /* modalias is trickier, we add it in 2 steps */
105   - if (add_uevent_var(envp, num_envp, &i,
106   - buffer, buffer_size, &length,
107   - "MODALIAS="))
  96 + if (add_uevent_var(env, "MODALIAS="))
108 97 return -ENOMEM;
109   -
110   - sl = of_device_get_modalias(ofdev, &buffer[length-1],
111   - buffer_size-length);
112   - if (sl >= (buffer_size-length))
  98 + sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
  99 + sizeof(env->buf) - env->buflen);
  100 + if (sl >= (sizeof(env->buf) - env->buflen))
113 101 return -ENOMEM;
114   -
115   - length += sl;
116   -
117   - envp[i] = NULL;
  102 + env->buflen += sl;
118 103  
119 104 return 0;
120 105 }
arch/powerpc/kernel/vio.c
... ... @@ -317,30 +317,20 @@
317 317 return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
318 318 }
319 319  
320   -static int vio_hotplug(struct device *dev, char **envp, int num_envp,
321   - char *buffer, int buffer_size)
  320 +static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env)
322 321 {
323 322 const struct vio_dev *vio_dev = to_vio_dev(dev);
324 323 struct device_node *dn;
325 324 const char *cp;
326   - int length;
327 325  
328   - if (!num_envp)
329   - return -ENOMEM;
330   -
331 326 dn = dev->archdata.of_node;
332 327 if (!dn)
333 328 return -ENODEV;
334   - cp = of_get_property(dn, "compatible", &length);
  329 + cp = of_get_property(dn, "compatible", NULL);
335 330 if (!cp)
336 331 return -ENODEV;
337 332  
338   - envp[0] = buffer;
339   - length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s",
340   - vio_dev->type, cp);
341   - if ((buffer_size - length) <= 0)
342   - return -ENOMEM;
343   - envp[1] = NULL;
  333 + add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, cp);
344 334 return 0;
345 335 }
346 336  
arch/powerpc/platforms/ps3/system-bus.c
... ... @@ -437,18 +437,13 @@
437 437 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
438 438 }
439 439  
440   -static int ps3_system_bus_uevent(struct device *_dev, char **envp,
441   - int num_envp, char *buffer, int buffer_size)
  440 +static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *env)
442 441 {
443 442 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
444 443 int i = 0, length = 0;
445 444  
446   - if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
447   - &length, "MODALIAS=ps3:%d",
448   - dev->match_id))
  445 + if (add_uevent_var(env, "MODALIAS=ps3:%d", dev->match_id))
449 446 return -ENOMEM;
450   -
451   - envp[i] = NULL;
452 447 return 0;
453 448 }
454 449  
... ... @@ -540,60 +540,41 @@
540 540 return ((ktype == &ktype_block) || (ktype == &ktype_part));
541 541 }
542 542  
543   -static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp,
544   - int num_envp, char *buffer, int buffer_size)
  543 +static int block_uevent(struct kset *kset, struct kobject *kobj,
  544 + struct kobj_uevent_env *env)
545 545 {
546 546 struct kobj_type *ktype = get_ktype(kobj);
547 547 struct device *physdev;
548 548 struct gendisk *disk;
549 549 struct hd_struct *part;
550   - int length = 0;
551   - int i = 0;
552 550  
553 551 if (ktype == &ktype_block) {
554 552 disk = container_of(kobj, struct gendisk, kobj);
555   - add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
556   - &length, "MINOR=%u", disk->first_minor);
  553 + add_uevent_var(env, "MINOR=%u", disk->first_minor);
557 554 } else if (ktype == &ktype_part) {
558 555 disk = container_of(kobj->parent, struct gendisk, kobj);
559 556 part = container_of(kobj, struct hd_struct, kobj);
560   - add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
561   - &length, "MINOR=%u",
  557 + add_uevent_var(env, "MINOR=%u",
562 558 disk->first_minor + part->partno);
563 559 } else
564 560 return 0;
565 561  
566   - add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
567   - "MAJOR=%u", disk->major);
  562 + add_uevent_var(env, "MAJOR=%u", disk->major);
568 563  
569 564 /* add physical device, backing this device */
570 565 physdev = disk->driverfs_dev;
571 566 if (physdev) {
572 567 char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
573 568  
574   - add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
575   - &length, "PHYSDEVPATH=%s", path);
  569 + add_uevent_var(env, "PHYSDEVPATH=%s", path);
576 570 kfree(path);
577 571  
578 572 if (physdev->bus)
579   - add_uevent_var(envp, num_envp, &i,
580   - buffer, buffer_size, &length,
581   - "PHYSDEVBUS=%s",
582   - physdev->bus->name);
  573 + add_uevent_var(env, "PHYSDEVBUS=%s", physdev->bus->name);
583 574  
584 575 if (physdev->driver)
585   - add_uevent_var(envp, num_envp, &i,
586   - buffer, buffer_size, &length,
587   - "PHYSDEVDRIVER=%s",
588   - physdev->driver->name);
  576 + add_uevent_var(env, physdev->driver->name);
589 577 }
590   -
591   - /* terminate, set to next free slot, shrink available space */
592   - envp[i] = NULL;
593   - envp = &envp[i];
594   - num_envp -= i;
595   - buffer = &buffer[length];
596   - buffer_size -= length;
597 578  
598 579 return 0;
599 580 }
... ... @@ -319,16 +319,18 @@
319 319 return !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
320 320 }
321 321  
322   -static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
323   - char *buffer, int buffer_size)
  322 +static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
324 323 {
325 324 struct acpi_device *acpi_dev = to_acpi_device(dev);
  325 + int len;
326 326  
327   - strcpy(buffer, "MODALIAS=");
328   - if (create_modalias(acpi_dev, buffer + 9, buffer_size - 9) > 0) {
329   - envp[0] = buffer;
330   - envp[1] = NULL;
331   - }
  327 + if (add_uevent_var(env, "MODALIAS="))
  328 + return -ENOMEM;
  329 + len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
  330 + sizeof(env->buf) - env->buflen);
  331 + if (len >= (sizeof(env->buf) - env->buflen))
  332 + return -ENOMEM;
  333 + env->buflen += len;
332 334 return 0;
333 335 }
334 336  
... ... @@ -44,15 +44,12 @@
44 44 }
45 45  
46 46 #ifdef CONFIG_HOTPLUG
47   -static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
  47 +static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
48 48 {
49 49 struct amba_device *pcdev = to_amba_device(dev);
50   - int retval = 0, i = 0, len = 0;
  50 + int retval = 0;
51 51  
52   - retval = add_uevent_var(envp, nr_env, &i,
53   - buf, bufsz, &len,
54   - "AMBA_ID=%08x", pcdev->periphid);
55   - envp[i] = NULL;
  52 + retval = add_uevent_var(env, "AMBA_ID=%08x", pcdev->periphid);
56 53 return retval;
57 54 }
58 55 #else
drivers/base/class.c
... ... @@ -180,8 +180,7 @@
180 180  
181 181 /* needed to allow these devices to have parent class devices */
182 182 static int class_device_create_uevent(struct class_device *class_dev,
183   - char **envp, int num_envp,
184   - char *buffer, int buffer_size)
  183 + struct kobj_uevent_env *env)
185 184 {
186 185 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
187 186 return 0;
188 187  
189 188  
190 189  
191 190  
192 191  
193 192  
194 193  
195 194  
196 195  
... ... @@ -403,64 +402,43 @@
403 402 { }
404 403 #endif
405 404  
406   -static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
407   - int num_envp, char *buffer, int buffer_size)
  405 +static int class_uevent(struct kset *kset, struct kobject *kobj,
  406 + struct kobj_uevent_env *env)
408 407 {
409 408 struct class_device *class_dev = to_class_dev(kobj);
410 409 struct device *dev = class_dev->dev;
411   - int i = 0;
412   - int length = 0;
413 410 int retval = 0;
414 411  
415 412 pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
416 413  
417 414 if (MAJOR(class_dev->devt)) {
418   - add_uevent_var(envp, num_envp, &i,
419   - buffer, buffer_size, &length,
420   - "MAJOR=%u", MAJOR(class_dev->devt));
  415 + add_uevent_var(env, "MAJOR=%u", MAJOR(class_dev->devt));
421 416  
422   - add_uevent_var(envp, num_envp, &i,
423   - buffer, buffer_size, &length,
424   - "MINOR=%u", MINOR(class_dev->devt));
  417 + add_uevent_var(env, "MINOR=%u", MINOR(class_dev->devt));
425 418 }
426 419  
427 420 if (dev) {
428 421 const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
429 422 if (path) {
430   - add_uevent_var(envp, num_envp, &i,
431   - buffer, buffer_size, &length,
432   - "PHYSDEVPATH=%s", path);
  423 + add_uevent_var(env, "PHYSDEVPATH=%s", path);
433 424 kfree(path);
434 425 }
435 426  
436 427 if (dev->bus)
437   - add_uevent_var(envp, num_envp, &i,
438   - buffer, buffer_size, &length,
439   - "PHYSDEVBUS=%s", dev->bus->name);
  428 + add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
440 429  
441 430 if (dev->driver)
442   - add_uevent_var(envp, num_envp, &i,
443   - buffer, buffer_size, &length,
444   - "PHYSDEVDRIVER=%s", dev->driver->name);
  431 + add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name);
445 432 }
446 433  
447   - /* terminate, set to next free slot, shrink available space */
448   - envp[i] = NULL;
449   - envp = &envp[i];
450   - num_envp -= i;
451   - buffer = &buffer[length];
452   - buffer_size -= length;
453   -
454 434 if (class_dev->uevent) {
455 435 /* have the class device specific function add its stuff */
456   - retval = class_dev->uevent(class_dev, envp, num_envp,
457   - buffer, buffer_size);
  436 + retval = class_dev->uevent(class_dev, env);
458 437 if (retval)
459 438 pr_debug("class_dev->uevent() returned %d\n", retval);
460 439 } else if (class_dev->class->uevent) {
461 440 /* have the class specific function add its stuff */
462   - retval = class_dev->class->uevent(class_dev, envp, num_envp,
463   - buffer, buffer_size);
  441 + retval = class_dev->class->uevent(class_dev, env);
464 442 if (retval)
465 443 pr_debug("class->uevent() returned %d\n", retval);
466 444 }
... ... @@ -141,33 +141,23 @@
141 141 return NULL;
142 142 }
143 143  
144   -static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
145   - int num_envp, char *buffer, int buffer_size)
  144 +static int dev_uevent(struct kset *kset, struct kobject *kobj,
  145 + struct kobj_uevent_env *env)
146 146 {
147 147 struct device *dev = to_dev(kobj);
148   - int i = 0;
149   - int length = 0;
150 148 int retval = 0;
151 149  
152 150 /* add the major/minor if present */
153 151 if (MAJOR(dev->devt)) {
154   - add_uevent_var(envp, num_envp, &i,
155   - buffer, buffer_size, &length,
156   - "MAJOR=%u", MAJOR(dev->devt));
157   - add_uevent_var(envp, num_envp, &i,
158   - buffer, buffer_size, &length,
159   - "MINOR=%u", MINOR(dev->devt));
  152 + add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
  153 + add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
160 154 }
161 155  
162 156 if (dev->type && dev->type->name)
163   - add_uevent_var(envp, num_envp, &i,
164   - buffer, buffer_size, &length,
165   - "DEVTYPE=%s", dev->type->name);
  157 + add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
166 158  
167 159 if (dev->driver)
168   - add_uevent_var(envp, num_envp, &i,
169   - buffer, buffer_size, &length,
170   - "DRIVER=%s", dev->driver->name);
  160 + add_uevent_var(env, "DRIVER=%s", dev->driver->name);
171 161  
172 162 #ifdef CONFIG_SYSFS_DEPRECATED
173 163 if (dev->class) {
174 164  
175 165  
176 166  
177 167  
178 168  
179 169  
180 170  
181 171  
182 172  
183 173  
... ... @@ -181,59 +171,43 @@
181 171  
182 172 path = kobject_get_path(&parent->kobj, GFP_KERNEL);
183 173 if (path) {
184   - add_uevent_var(envp, num_envp, &i,
185   - buffer, buffer_size, &length,
186   - "PHYSDEVPATH=%s", path);
  174 + add_uevent_var(env, "PHYSDEVPATH=%s", path);
187 175 kfree(path);
188 176 }
189 177  
190   - add_uevent_var(envp, num_envp, &i,
191   - buffer, buffer_size, &length,
192   - "PHYSDEVBUS=%s", parent->bus->name);
  178 + add_uevent_var(env, "PHYSDEVBUS=%s", parent->bus->name);
193 179  
194 180 if (parent->driver)
195   - add_uevent_var(envp, num_envp, &i,
196   - buffer, buffer_size, &length,
197   - "PHYSDEVDRIVER=%s", parent->driver->name);
  181 + add_uevent_var(env, "PHYSDEVDRIVER=%s",
  182 + parent->driver->name);
198 183 }
199 184 } else if (dev->bus) {
200   - add_uevent_var(envp, num_envp, &i,
201   - buffer, buffer_size, &length,
202   - "PHYSDEVBUS=%s", dev->bus->name);
  185 + add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
203 186  
204 187 if (dev->driver)
205   - add_uevent_var(envp, num_envp, &i,
206   - buffer, buffer_size, &length,
207   - "PHYSDEVDRIVER=%s", dev->driver->name);
  188 + add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name);
208 189 }
209 190 #endif
210 191  
211   - /* terminate, set to next free slot, shrink available space */
212   - envp[i] = NULL;
213   - envp = &envp[i];
214   - num_envp -= i;
215   - buffer = &buffer[length];
216   - buffer_size -= length;
217   -
  192 + /* have the bus specific function add its stuff */
218 193 if (dev->bus && dev->bus->uevent) {
219   - /* have the bus specific function add its stuff */
220   - retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
  194 + retval = dev->bus->uevent(dev, env);
221 195 if (retval)
222 196 pr_debug ("%s: bus uevent() returned %d\n",
223 197 __FUNCTION__, retval);
224 198 }
225 199  
  200 + /* have the class specific function add its stuff */
226 201 if (dev->class && dev->class->dev_uevent) {
227   - /* have the class specific function add its stuff */
228   - retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
  202 + retval = dev->class->dev_uevent(dev, env);
229 203 if (retval)
230 204 pr_debug("%s: class uevent() returned %d\n",
231 205 __FUNCTION__, retval);
232 206 }
233 207  
  208 + /* have the device type specific fuction add its stuff */
234 209 if (dev->type && dev->type->uevent) {
235   - /* have the device type specific fuction add its stuff */
236   - retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size);
  210 + retval = dev->type->uevent(dev, env);
237 211 if (retval)
238 212 pr_debug("%s: dev_type uevent() returned %d\n",
239 213 __FUNCTION__, retval);
... ... @@ -253,9 +227,7 @@
253 227 {
254 228 struct kobject *top_kobj;
255 229 struct kset *kset;
256   - char *envp[32];
257   - char *data = NULL;
258   - char *pos;
  230 + struct kobj_uevent_env *env = NULL;
259 231 int i;
260 232 size_t count = 0;
261 233 int retval;
262 234  
263 235  
264 236  
... ... @@ -278,26 +250,20 @@
278 250 if (!kset->uevent_ops->filter(kset, &dev->kobj))
279 251 goto out;
280 252  
281   - data = (char *)get_zeroed_page(GFP_KERNEL);
282   - if (!data)
  253 + env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
  254 + if (!env)
283 255 return -ENOMEM;
284 256  
285 257 /* let the kset specific function add its keys */
286   - pos = data;
287   - memset(envp, 0, sizeof(envp));
288   - retval = kset->uevent_ops->uevent(kset, &dev->kobj,
289   - envp, ARRAY_SIZE(envp),
290   - pos, PAGE_SIZE);
  258 + retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
291 259 if (retval)
292 260 goto out;
293 261  
294 262 /* copy keys to file */
295   - for (i = 0; envp[i]; i++) {
296   - pos = &buf[count];
297   - count += sprintf(pos, "%s\n", envp[i]);
298   - }
  263 + for (i = 0; i < env->envp_idx; i++)
  264 + count += sprintf(&buf[count], "%s\n", env->envp[i]);
299 265 out:
300   - free_page((unsigned long)data);
  266 + kfree(env);
301 267 return count;
302 268 }
303 269  
drivers/base/firmware_class.c
... ... @@ -88,19 +88,14 @@
88 88  
89 89 static void fw_dev_release(struct device *dev);
90 90  
91   -static int firmware_uevent(struct device *dev, char **envp, int num_envp,
92   - char *buffer, int buffer_size)
  91 +static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
93 92 {
94 93 struct firmware_priv *fw_priv = dev_get_drvdata(dev);
95   - int i = 0, len = 0;
96 94  
97   - if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
98   - "FIRMWARE=%s", fw_priv->fw_id))
  95 + if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id))
99 96 return -ENOMEM;
100   - if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
101   - "TIMEOUT=%i", loading_timeout))
  97 + if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout))
102 98 return -ENOMEM;
103   - envp[i] = NULL;
104 99  
105 100 return 0;
106 101 }
drivers/base/memory.c
... ... @@ -34,8 +34,7 @@
34 34 return MEMORY_CLASS_NAME;
35 35 }
36 36  
37   -static int memory_uevent(struct kset *kset, struct kobject *kobj, char **envp,
38   - int num_envp, char *buffer, int buffer_size)
  37 +static int memory_uevent(struct kset *kset, struct kobj_uevent_env *env)
39 38 {
40 39 int retval = 0;
41 40  
drivers/base/platform.c
... ... @@ -529,13 +529,11 @@
529 529 __ATTR_NULL,
530 530 };
531 531  
532   -static int platform_uevent(struct device *dev, char **envp, int num_envp,
533   - char *buffer, int buffer_size)
  532 +static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
534 533 {
535 534 struct platform_device *pdev = to_platform_device(dev);
536 535  
537   - envp[0] = buffer;
538   - snprintf(buffer, buffer_size, "MODALIAS=platform:%s", pdev->name);
  536 + add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
539 537 return 0;
540 538 }
541 539  
drivers/eisa/eisa-bus.c
... ... @@ -128,16 +128,11 @@
128 128 return 0;
129 129 }
130 130  
131   -static int eisa_bus_uevent(struct device *dev, char **envp, int num_envp,
132   - char *buffer, int buffer_size)
  131 +static int eisa_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
133 132 {
134 133 struct eisa_device *edev = to_eisa_device(dev);
135   - int i = 0;
136   - int length = 0;
137 134  
138   - add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
139   - "MODALIAS=" EISA_DEVICE_MODALIAS_FMT, edev->id.sig);
140   - envp[i] = NULL;
  135 + add_uevent_var(env, "MODALIAS=" EISA_DEVICE_MODALIAS_FMT, edev->id.sig);
141 136 return 0;
142 137 }
143 138  
drivers/firewire/fw-device.c
... ... @@ -130,22 +130,15 @@
130 130 }
131 131  
132 132 static int
133   -fw_unit_uevent(struct device *dev, char **envp, int num_envp,
134   - char *buffer, int buffer_size)
  133 +fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
135 134 {
136 135 struct fw_unit *unit = fw_unit(dev);
137 136 char modalias[64];
138   - int length = 0;
139   - int i = 0;
140 137  
141 138 get_modalias(unit, modalias, sizeof(modalias));
142 139  
143   - if (add_uevent_var(envp, num_envp, &i,
144   - buffer, buffer_size, &length,
145   - "MODALIAS=%s", modalias))
  140 + if (add_uevent_var(env, "MODALIAS=%s", modalias))
146 141 return -ENOMEM;
147   -
148   - envp[i] = NULL;
149 142  
150 143 return 0;
151 144 }
drivers/firmware/dmi-id.c
... ... @@ -134,14 +134,17 @@
134 134 NULL
135 135 };
136 136  
137   -static int dmi_dev_uevent(struct device *dev, char **envp,
138   - int num_envp, char *buffer, int buffer_size)
  137 +static int dmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
139 138 {
140   - strcpy(buffer, "MODALIAS=");
141   - get_modalias(buffer+9, buffer_size-9);
142   - envp[0] = buffer;
143   - envp[1] = NULL;
  139 + ssize_t len;
144 140  
  141 + if (add_uevent_var(env, "MODALIAS="))
  142 + return -ENOMEM;
  143 + len = get_modalias(&env->buf[env->buflen - 1],
  144 + sizeof(env->buf) - env->buflen);
  145 + if (len >= (sizeof(env->buf) - env->buflen))
  146 + return -ENOMEM;
  147 + env->buflen += len;
145 148 return 0;
146 149 }
147 150  
drivers/i2c/i2c-core.c
... ... @@ -67,20 +67,16 @@
67 67 #ifdef CONFIG_HOTPLUG
68 68  
69 69 /* uevent helps with hotplug: modprobe -q $(MODALIAS) */
70   -static int i2c_device_uevent(struct device *dev, char **envp, int num_envp,
71   - char *buffer, int buffer_size)
  70 +static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
72 71 {
73 72 struct i2c_client *client = to_i2c_client(dev);
74   - int i = 0, length = 0;
75 73  
76 74 /* by definition, legacy drivers can't hotplug */
77 75 if (dev->driver || !client->driver_name)
78 76 return 0;
79 77  
80   - if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
81   - "MODALIAS=%s", client->driver_name))
  78 + if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
82 79 return -ENOMEM;
83   - envp[i] = NULL;
84 80 dev_dbg(dev, "uevent\n");
85 81 return 0;
86 82 }
... ... @@ -1663,20 +1663,13 @@
1663 1663 __ATTR_NULL
1664 1664 };
1665 1665  
1666   -static int ide_uevent(struct device *dev, char **envp, int num_envp,
1667   - char *buffer, int buffer_size)
  1666 +static int ide_uevent(struct device *dev, struct kobj_uevent_env *env)
1668 1667 {
1669 1668 ide_drive_t *drive = to_ide_device(dev);
1670   - int i = 0;
1671   - int length = 0;
1672 1669  
1673   - add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
1674   - "MEDIA=%s", media_string(drive));
1675   - add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
1676   - "DRIVENAME=%s", drive->name);
1677   - add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
1678   - "MODALIAS=ide:m-%s", media_string(drive));
1679   - envp[i] = NULL;
  1670 + add_uevent_var(env, "MEDIA=%s", media_string(drive));
  1671 + add_uevent_var(env, "DRIVENAME=%s", drive->name);
  1672 + add_uevent_var(env, "MODALIAS=ide:m-%s", media_string(drive));
1680 1673 return 0;
1681 1674 }
1682 1675  
drivers/ieee1394/nodemgr.c
... ... @@ -153,8 +153,7 @@
153 153 };
154 154  
155 155 static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
156   -static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
157   - char *buffer, int buffer_size);
  156 +static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env);
158 157 static void nodemgr_resume_ne(struct node_entry *ne);
159 158 static void nodemgr_remove_ne(struct node_entry *ne);
160 159 static struct node_entry *find_entry_by_guid(u64 guid);
161 160  
... ... @@ -1160,12 +1159,9 @@
1160 1159  
1161 1160 #ifdef CONFIG_HOTPLUG
1162 1161  
1163   -static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
1164   - char *buffer, int buffer_size)
  1162 +static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env)
1165 1163 {
1166 1164 struct unit_directory *ud;
1167   - int i = 0;
1168   - int length = 0;
1169 1165 int retval = 0;
1170 1166 /* ieee1394:venNmoNspNverN */
1171 1167 char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1];
... ... @@ -1180,9 +1176,7 @@
1180 1176  
1181 1177 #define PUT_ENVP(fmt,val) \
1182 1178 do { \
1183   - retval = add_uevent_var(envp, num_envp, &i, \
1184   - buffer, buffer_size, &length, \
1185   - fmt, val); \
  1179 + retval = add_uevent_var(env, fmt, val); \
1186 1180 if (retval) \
1187 1181 return retval; \
1188 1182 } while (0)
1189 1183  
... ... @@ -1201,15 +1195,12 @@
1201 1195  
1202 1196 #undef PUT_ENVP
1203 1197  
1204   - envp[i] = NULL;
1205   -
1206 1198 return 0;
1207 1199 }
1208 1200  
1209 1201 #else
1210 1202  
1211   -static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
1212   - char *buffer, int buffer_size)
  1203 +static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env)
1213 1204 {
1214 1205 return -ENODEV;
1215 1206 }
drivers/infiniband/core/sysfs.c
... ... @@ -434,21 +434,18 @@
434 434 kfree(dev);
435 435 }
436 436  
437   -static int ib_device_uevent(struct class_device *cdev, char **envp,
438   - int num_envp, char *buf, int size)
  437 +static int ib_device_uevent(struct class_device *cdev,
  438 + struct kobj_uevent_env *env)
439 439 {
440 440 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
441   - int i = 0, len = 0;
442 441  
443   - if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
444   - "NAME=%s", dev->name))
  442 + if (add_uevent_var(env, "NAME=%s", dev->name))
445 443 return -ENOMEM;
446 444  
447 445 /*
448 446 * It would be nice to pass the node GUID with the event...
449 447 */
450 448  
451   - envp[i] = NULL;
452 449 return 0;
453 450 }
454 451  
drivers/input/input.c
... ... @@ -859,87 +859,66 @@
859 859 * Input uevent interface - loading event handlers based on
860 860 * device bitfields.
861 861 */
862   -static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
863   - char *buffer, int buffer_size, int *cur_len,
  862 +static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
864 863 const char *name, unsigned long *bitmap, int max)
865 864 {
866   - if (*cur_index >= num_envp - 1)
867   - return -ENOMEM;
  865 + int len;
868 866  
869   - envp[*cur_index] = buffer + *cur_len;
870   -
871   - *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name);
872   - if (*cur_len >= buffer_size)
  867 + if (add_uevent_var(env, "%s=", name))
873 868 return -ENOMEM;
874 869  
875   - *cur_len += input_print_bitmap(buffer + *cur_len,
876   - max(buffer_size - *cur_len, 0),
877   - bitmap, max, 0) + 1;
878   - if (*cur_len > buffer_size)
  870 + len = input_print_bitmap(&env->buf[env->buflen - 1],
  871 + sizeof(env->buf) - env->buflen,
  872 + bitmap, max, 0);
  873 + if (len >= (sizeof(env->buf) - env->buflen))
879 874 return -ENOMEM;
880 875  
881   - (*cur_index)++;
  876 + env->buflen += len;
882 877 return 0;
883 878 }
884 879  
885   -static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_index,
886   - char *buffer, int buffer_size, int *cur_len,
  880 +static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
887 881 struct input_dev *dev)
888 882 {
889   - if (*cur_index >= num_envp - 1)
890   - return -ENOMEM;
  883 + int len;
891 884  
892   - envp[*cur_index] = buffer + *cur_len;
893   -
894   - *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0),
895   - "MODALIAS=");
896   - if (*cur_len >= buffer_size)
  885 + if (add_uevent_var(env, "MODALIAS="))
897 886 return -ENOMEM;
898 887  
899   - *cur_len += input_print_modalias(buffer + *cur_len,
900   - max(buffer_size - *cur_len, 0),
901   - dev, 0) + 1;
902   - if (*cur_len > buffer_size)
  888 + len = input_print_modalias(&env->buf[env->buflen - 1],
  889 + sizeof(env->buf) - env->buflen,
  890 + dev, 0);
  891 + if (len >= (sizeof(env->buf) - env->buflen))
903 892 return -ENOMEM;
904 893  
905   - (*cur_index)++;
  894 + env->buflen += len;
906 895 return 0;
907 896 }
908 897  
909 898 #define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \
910 899 do { \
911   - int err = add_uevent_var(envp, num_envp, &i, \
912   - buffer, buffer_size, &len, \
913   - fmt, val); \
  900 + int err = add_uevent_var(env, fmt, val); \
914 901 if (err) \
915 902 return err; \
916 903 } while (0)
917 904  
918 905 #define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \
919 906 do { \
920   - int err = input_add_uevent_bm_var(envp, num_envp, &i, \
921   - buffer, buffer_size, &len, \
922   - name, bm, max); \
  907 + int err = input_add_uevent_bm_var(env, name, bm, max); \
923 908 if (err) \
924 909 return err; \
925 910 } while (0)
926 911  
927 912 #define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \
928 913 do { \
929   - int err = input_add_uevent_modalias_var(envp, \
930   - num_envp, &i, \
931   - buffer, buffer_size, &len, \
932   - dev); \
  914 + int err = input_add_uevent_modalias_var(env, dev); \
933 915 if (err) \
934 916 return err; \
935 917 } while (0)
936 918  
937   -static int input_dev_uevent(struct device *device, char **envp,
938   - int num_envp, char *buffer, int buffer_size)
  919 +static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
939 920 {
940 921 struct input_dev *dev = to_input_dev(device);
941   - int i = 0;
942   - int len = 0;
943 922  
944 923 INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
945 924 dev->id.bustype, dev->id.vendor,
... ... @@ -971,7 +950,6 @@
971 950  
972 951 INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev);
973 952  
974   - envp[i] = NULL;
975 953 return 0;
976 954 }
977 955  
drivers/input/serio/serio.c
... ... @@ -876,18 +876,14 @@
876 876  
877 877 #define SERIO_ADD_UEVENT_VAR(fmt, val...) \
878 878 do { \
879   - int err = add_uevent_var(envp, num_envp, &i, \
880   - buffer, buffer_size, &len, \
881   - fmt, val); \
  879 + int err = add_uevent_var(env, fmt, val); \
882 880 if (err) \
883 881 return err; \
884 882 } while (0)
885 883  
886   -static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
  884 +static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
887 885 {
888 886 struct serio *serio;
889   - int i = 0;
890   - int len = 0;
891 887  
892 888 if (!dev)
893 889 return -ENODEV;
... ... @@ -900,7 +896,6 @@
900 896 SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
901 897 SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
902 898 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
903   - envp[i] = NULL;
904 899  
905 900 return 0;
906 901 }
... ... @@ -908,7 +903,7 @@
908 903  
909 904 #else
910 905  
911   -static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
  906 +static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
912 907 {
913 908 return -ENODEV;
914 909 }
drivers/media/video/pvrusb2/pvrusb2-sysfs.c
... ... @@ -905,8 +905,8 @@
905 905 }
906 906  
907 907  
908   -static int pvr2_sysfs_hotplug(struct device *cd,char **envp,
909   - int numenvp,char *buf,int size)
  908 +static int pvr2_sysfs_hotplug(struct device *d,
  909 + struct kobj_uevent_env *env)
910 910 {
911 911 /* Even though we don't do anything here, we still need this function
912 912 because sysfs will still try to call it. */
drivers/misc/tifm_core.c
... ... @@ -57,16 +57,11 @@
57 57 return 0;
58 58 }
59 59  
60   -static int tifm_uevent(struct device *dev, char **envp, int num_envp,
61   - char *buffer, int buffer_size)
  60 +static int tifm_uevent(struct device *dev, struct kobj_uevent_env *env)
62 61 {
63 62 struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
64   - int i = 0;
65   - int length = 0;
66 63  
67   - if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
68   - "TIFM_CARD_TYPE=%s",
69   - tifm_media_type_name(sock->type, 1)))
  64 + if (add_uevent_var(env, "TIFM_CARD_TYPE=%s", tifm_media_type_name(sock->type, 1)))
70 65 return -ENOMEM;
71 66  
72 67 return 0;
drivers/mmc/core/bus.c
... ... @@ -58,12 +58,11 @@
58 58 }
59 59  
60 60 static int
61   -mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
62   - int buf_size)
  61 +mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
63 62 {
64 63 struct mmc_card *card = dev_to_mmc_card(dev);
65 64 const char *type;
66   - int i = 0, length = 0;
  65 + int retval = 0;
67 66  
68 67 switch (card->type) {
69 68 case MMC_TYPE_MMC:
70 69  
71 70  
... ... @@ -80,20 +79,14 @@
80 79 }
81 80  
82 81 if (type) {
83   - if (add_uevent_var(envp, num_envp, &i,
84   - buf, buf_size, &length,
85   - "MMC_TYPE=%s", type))
86   - return -ENOMEM;
  82 + retval = add_uevent_var(env, "MMC_TYPE=%s", type);
  83 + if (retval)
  84 + return retval;
87 85 }
88 86  
89   - if (add_uevent_var(envp, num_envp, &i,
90   - buf, buf_size, &length,
91   - "MMC_NAME=%s", mmc_card_name(card)))
92   - return -ENOMEM;
  87 + retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card));
93 88  
94   - envp[i] = NULL;
95   -
96   - return 0;
  89 + return retval;
97 90 }
98 91  
99 92 static int mmc_bus_probe(struct device *dev)
drivers/pci/hotplug.c
... ... @@ -3,12 +3,9 @@
3 3 #include <linux/module.h>
4 4 #include "pci.h"
5 5  
6   -int pci_uevent(struct device *dev, char **envp, int num_envp,
7   - char *buffer, int buffer_size)
  6 +int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
8 7 {
9 8 struct pci_dev *pdev;
10   - int i = 0;
11   - int length = 0;
12 9  
13 10 if (!dev)
14 11 return -ENODEV;
15 12  
16 13  
17 14  
18 15  
19 16  
... ... @@ -17,38 +14,25 @@
17 14 if (!pdev)
18 15 return -ENODEV;
19 16  
20   - if (add_uevent_var(envp, num_envp, &i,
21   - buffer, buffer_size, &length,
22   - "PCI_CLASS=%04X", pdev->class))
  17 + if (add_uevent_var(env, "PCI_CLASS=%04X", pdev->class))
23 18 return -ENOMEM;
24 19  
25   - if (add_uevent_var(envp, num_envp, &i,
26   - buffer, buffer_size, &length,
27   - "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
  20 + if (add_uevent_var(env, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
28 21 return -ENOMEM;
29 22  
30   - if (add_uevent_var(envp, num_envp, &i,
31   - buffer, buffer_size, &length,
32   - "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
  23 + if (add_uevent_var(env, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
33 24 pdev->subsystem_device))
34 25 return -ENOMEM;
35 26  
36   - if (add_uevent_var(envp, num_envp, &i,
37   - buffer, buffer_size, &length,
38   - "PCI_SLOT_NAME=%s", pci_name(pdev)))
  27 + if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev)))
39 28 return -ENOMEM;
40 29  
41   - if (add_uevent_var(envp, num_envp, &i,
42   - buffer, buffer_size, &length,
43   - "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
  30 + if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
44 31 pdev->vendor, pdev->device,
45 32 pdev->subsystem_vendor, pdev->subsystem_device,
46 33 (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
47 34 (u8)(pdev->class)))
48 35 return -ENOMEM;
49   -
50   - envp[i] = NULL;
51   -
52 36 return 0;
53 37 }
drivers/pci/pci-driver.c
... ... @@ -532,8 +532,7 @@
532 532 }
533 533  
534 534 #ifndef CONFIG_HOTPLUG
535   -int pci_uevent(struct device *dev, char **envp, int num_envp,
536   - char *buffer, int buffer_size)
  535 +int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
537 536 {
538 537 return -ENODEV;
539 538 }
1 1 /* Functions internal to the PCI core code */
2 2  
3   -extern int pci_uevent(struct device *dev, char **envp, int num_envp,
4   - char *buffer, int buffer_size);
  3 +extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
5 4 extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
6 5 extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
7 6 extern void pci_cleanup_rom(struct pci_dev *dev);
... ... @@ -907,17 +907,13 @@
907 907 EXPORT_SYMBOL(pcmcia_insert_card);
908 908  
909 909  
910   -static int pcmcia_socket_uevent(struct device *dev, char **envp,
911   - int num_envp, char *buffer, int buffer_size)
  910 +static int pcmcia_socket_uevent(struct device *dev,
  911 + struct kobj_uevent_env *env)
912 912 {
913 913 struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
914   - int i = 0, length = 0;
915 914  
916   - if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
917   - &length, "SOCKET_NO=%u", s->sock))
  915 + if (add_uevent_var(env, "SOCKET_NO=%u", s->sock))
918 916 return -ENOMEM;
919   -
920   - envp[i] = NULL;
921 917  
922 918 return 0;
923 919 }
... ... @@ -1064,11 +1064,10 @@
1064 1064  
1065 1065 #ifdef CONFIG_HOTPLUG
1066 1066  
1067   -static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
1068   - char *buffer, int buffer_size)
  1067 +static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
1069 1068 {
1070 1069 struct pcmcia_device *p_dev;
1071   - int i, length = 0;
  1070 + int i;
1072 1071 u32 hash[4] = { 0, 0, 0, 0};
1073 1072  
1074 1073 if (!dev)
1075 1074  
1076 1075  
... ... @@ -1083,23 +1082,13 @@
1083 1082 hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i]));
1084 1083 }
1085 1084  
1086   - i = 0;
1087   -
1088   - if (add_uevent_var(envp, num_envp, &i,
1089   - buffer, buffer_size, &length,
1090   - "SOCKET_NO=%u",
1091   - p_dev->socket->sock))
  1085 + if (add_uevent_var(env, "SOCKET_NO=%u", p_dev->socket->sock))
1092 1086 return -ENOMEM;
1093 1087  
1094   - if (add_uevent_var(envp, num_envp, &i,
1095   - buffer, buffer_size, &length,
1096   - "DEVICE_NO=%02X",
1097   - p_dev->device_no))
  1088 + if (add_uevent_var(env, "DEVICE_NO=%02X", p_dev->device_no))
1098 1089 return -ENOMEM;
1099 1090  
1100   - if (add_uevent_var(envp, num_envp, &i,
1101   - buffer, buffer_size, &length,
1102   - "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
  1091 + if (add_uevent_var(env, "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
1103 1092 "pa%08Xpb%08Xpc%08Xpd%08X",
1104 1093 p_dev->has_manf_id ? p_dev->manf_id : 0,
1105 1094 p_dev->has_card_id ? p_dev->card_id : 0,
1106 1095  
... ... @@ -1112,15 +1101,12 @@
1112 1101 hash[3]))
1113 1102 return -ENOMEM;
1114 1103  
1115   - envp[i] = NULL;
1116   -
1117 1104 return 0;
1118 1105 }
1119 1106  
1120 1107 #else
1121 1108  
1122   -static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
1123   - char *buffer, int buffer_size)
  1109 +static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
1124 1110 {
1125 1111 return -ENODEV;
1126 1112 }
drivers/power/power_supply.h
... ... @@ -14,8 +14,7 @@
14 14  
15 15 extern int power_supply_create_attrs(struct power_supply *psy);
16 16 extern void power_supply_remove_attrs(struct power_supply *psy);
17   -extern int power_supply_uevent(struct device *dev, char **envp, int num_envp,
18   - char *buffer, int buffer_size);
  17 +extern int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env);
19 18  
20 19 #else
21 20  
drivers/power/power_supply_sysfs.c
... ... @@ -195,11 +195,10 @@
195 195 return ret;
196 196 }
197 197  
198   -int power_supply_uevent(struct device *dev, char **envp, int num_envp,
199   - char *buffer, int buffer_size)
  198 +int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
200 199 {
201 200 struct power_supply *psy = dev_get_drvdata(dev);
202   - int i = 0, length = 0, ret = 0, j;
  201 + int ret = 0, j;
203 202 char *prop_buf;
204 203 char *attrname;
205 204  
... ... @@ -212,8 +211,7 @@
212 211  
213 212 dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name);
214 213  
215   - ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
216   - &length, "POWER_SUPPLY_NAME=%s", psy->name);
  214 + ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->name);
217 215 if (ret)
218 216 return ret;
219 217  
... ... @@ -243,9 +241,7 @@
243 241  
244 242 dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf);
245 243  
246   - ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
247   - &length, "POWER_SUPPLY_%s=%s",
248   - attrname, prop_buf);
  244 + ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf);
249 245 kfree(attrname);
250 246 if (ret)
251 247 goto out;
252 248  
... ... @@ -282,14 +278,11 @@
282 278  
283 279 dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf);
284 280  
285   - ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
286   - &length, "POWER_SUPPLY_%s=%s",
287   - attrname, prop_buf);
  281 + ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf);
288 282 kfree(attrname);
289 283 if (ret)
290 284 goto out;
291 285 }
292   - envp[i] = NULL;
293 286  
294 287 out:
295 288 free_page((unsigned long)prop_buf);
drivers/s390/cio/ccwgroup.c
... ... @@ -44,8 +44,7 @@
44 44 return 0;
45 45 }
46 46 static int
47   -ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer,
48   - int buffer_size)
  47 +ccwgroup_uevent (struct device *dev, struct kobj_uevent_env *env)
49 48 {
50 49 /* TODO */
51 50 return 0;
drivers/s390/cio/device.c
... ... @@ -78,49 +78,38 @@
78 78  
79 79 /* Set up environment variables for ccw device uevent. Return 0 on success,
80 80 * non-zero otherwise. */
81   -static int ccw_uevent(struct device *dev, char **envp, int num_envp,
82   - char *buffer, int buffer_size)
  81 +static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env)
83 82 {
84 83 struct ccw_device *cdev = to_ccwdev(dev);
85 84 struct ccw_device_id *id = &(cdev->id);
86   - int i = 0;
87   - int len = 0;
88 85 int ret;
89 86 char modalias_buf[30];
90 87  
91 88 /* CU_TYPE= */
92   - ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
93   - "CU_TYPE=%04X", id->cu_type);
  89 + ret = add_uevent_var(env, "CU_TYPE=%04X", id->cu_type);
94 90 if (ret)
95 91 return ret;
96 92  
97 93 /* CU_MODEL= */
98   - ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
99   - "CU_MODEL=%02X", id->cu_model);
  94 + ret = add_uevent_var(env, "CU_MODEL=%02X", id->cu_model);
100 95 if (ret)
101 96 return ret;
102 97  
103 98 /* The next two can be zero, that's ok for us */
104 99 /* DEV_TYPE= */
105   - ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
106   - "DEV_TYPE=%04X", id->dev_type);
  100 + ret = add_uevent_var(env, "DEV_TYPE=%04X", id->dev_type);
107 101 if (ret)
108 102 return ret;
109 103  
110 104 /* DEV_MODEL= */
111   - ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
112   - "DEV_MODEL=%02X", id->dev_model);
  105 + ret = add_uevent_var(env, "DEV_MODEL=%02X", id->dev_model);
113 106 if (ret)
114 107 return ret;
115 108  
116 109 /* MODALIAS= */
117 110 snprint_alias(modalias_buf, sizeof(modalias_buf), id, "");
118   - ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
119   - "MODALIAS=%s", modalias_buf);
120   - if (ret)
121   - return ret;
122   - envp[i] = NULL;
123   - return 0;
  111 + ret = add_uevent_var(env, "MODALIAS=%s", modalias_buf);
  112 + return ret;
124 113 }
125 114  
126 115 struct bus_type ccw_bus_type;
drivers/s390/crypto/ap_bus.c
... ... @@ -458,28 +458,22 @@
458 458 * uevent function for AP devices. It sets up a single environment
459 459 * variable DEV_TYPE which contains the hardware device type.
460 460 */
461   -static int ap_uevent (struct device *dev, char **envp, int num_envp,
462   - char *buffer, int buffer_size)
  461 +static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
463 462 {
464 463 struct ap_device *ap_dev = to_ap_dev(dev);
465   - int retval = 0, length = 0, i = 0;
  464 + int retval = 0;
466 465  
467 466 if (!ap_dev)
468 467 return -ENODEV;
469 468  
470 469 /* Set up DEV_TYPE environment variable. */
471   - retval = add_uevent_var(envp, num_envp, &i,
472   - buffer, buffer_size, &length,
473   - "DEV_TYPE=%04X", ap_dev->device_type);
  470 + retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type);
474 471 if (retval)
475 472 return retval;
476 473  
477 474 /* Add MODALIAS= */
478   - retval = add_uevent_var(envp, num_envp, &i,
479   - buffer, buffer_size, &length,
480   - "MODALIAS=ap:t%02X", ap_dev->device_type);
  475 + retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type);
481 476  
482   - envp[i] = NULL;
483 477 return retval;
484 478 }
485 479  
drivers/scsi/scsi_sysfs.c
... ... @@ -277,16 +277,11 @@
277 277 return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
278 278 }
279 279  
280   -static int scsi_bus_uevent(struct device *dev, char **envp, int num_envp,
281   - char *buffer, int buffer_size)
  280 +static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
282 281 {
283 282 struct scsi_device *sdev = to_scsi_device(dev);
284   - int i = 0;
285   - int length = 0;
286 283  
287   - add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
288   - "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type);
289   - envp[i] = NULL;
  284 + add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type);
290 285 return 0;
291 286 }
292 287  
... ... @@ -67,14 +67,11 @@
67 67 return strncmp(spi->modalias, drv->name, BUS_ID_SIZE) == 0;
68 68 }
69 69  
70   -static int spi_uevent(struct device *dev, char **envp, int num_envp,
71   - char *buffer, int buffer_size)
  70 +static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
72 71 {
73 72 const struct spi_device *spi = to_spi_device(dev);
74 73  
75   - envp[0] = buffer;
76   - snprintf(buffer, buffer_size, "MODALIAS=%s", spi->modalias);
77   - envp[1] = NULL;
  74 + add_uevent_var(env, "MODALIAS=%s", spi->modalias);
78 75 return 0;
79 76 }
80 77  
drivers/usb/core/driver.c
... ... @@ -576,12 +576,9 @@
576 576 }
577 577  
578 578 #ifdef CONFIG_HOTPLUG
579   -static int usb_uevent(struct device *dev, char **envp, int num_envp,
580   - char *buffer, int buffer_size)
  579 +static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
581 580 {
582 581 struct usb_device *usb_dev;
583   - int i = 0;
584   - int length = 0;
585 582  
586 583 if (!dev)
587 584 return -ENODEV;
588 585  
589 586  
590 587  
591 588  
592 589  
593 590  
... ... @@ -610,51 +607,39 @@
610 607 * all the device descriptors we don't tell them about. Or
611 608 * act as usermode drivers.
612 609 */
613   - if (add_uevent_var(envp, num_envp, &i,
614   - buffer, buffer_size, &length,
615   - "DEVICE=/proc/bus/usb/%03d/%03d",
  610 + if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
616 611 usb_dev->bus->busnum, usb_dev->devnum))
617 612 return -ENOMEM;
618 613 #endif
619 614  
620 615 /* per-device configurations are common */
621   - if (add_uevent_var(envp, num_envp, &i,
622   - buffer, buffer_size, &length,
623   - "PRODUCT=%x/%x/%x",
  616 + if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
624 617 le16_to_cpu(usb_dev->descriptor.idVendor),
625 618 le16_to_cpu(usb_dev->descriptor.idProduct),
626 619 le16_to_cpu(usb_dev->descriptor.bcdDevice)))
627 620 return -ENOMEM;
628 621  
629 622 /* class-based driver binding models */
630   - if (add_uevent_var(envp, num_envp, &i,
631   - buffer, buffer_size, &length,
632   - "TYPE=%d/%d/%d",
  623 + if (add_uevent_var(env, "TYPE=%d/%d/%d",
633 624 usb_dev->descriptor.bDeviceClass,
634 625 usb_dev->descriptor.bDeviceSubClass,
635 626 usb_dev->descriptor.bDeviceProtocol))
636 627 return -ENOMEM;
637 628  
638   - if (add_uevent_var(envp, num_envp, &i,
639   - buffer, buffer_size, &length,
640   - "BUSNUM=%03d",
  629 + if (add_uevent_var(env, "BUSNUM=%03d",
641 630 usb_dev->bus->busnum))
642 631 return -ENOMEM;
643 632  
644   - if (add_uevent_var(envp, num_envp, &i,
645   - buffer, buffer_size, &length,
646   - "DEVNUM=%03d",
  633 + if (add_uevent_var(env, "DEVNUM=%03d",
647 634 usb_dev->devnum))
648 635 return -ENOMEM;
649 636  
650   - envp[i] = NULL;
651 637 return 0;
652 638 }
653 639  
654 640 #else
655 641  
656   -static int usb_uevent(struct device *dev, char **envp,
657   - int num_envp, char *buffer, int buffer_size)
  642 +static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
658 643 {
659 644 return -ENODEV;
660 645 }
drivers/usb/core/message.c
... ... @@ -1339,14 +1339,11 @@
1339 1339 }
1340 1340  
1341 1341 #ifdef CONFIG_HOTPLUG
1342   -static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
1343   - char *buffer, int buffer_size)
  1342 +static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
1344 1343 {
1345 1344 struct usb_device *usb_dev;
1346 1345 struct usb_interface *intf;
1347 1346 struct usb_host_interface *alt;
1348   - int i = 0;
1349   - int length = 0;
1350 1347  
1351 1348 if (!dev)
1352 1349 return -ENODEV;
1353 1350  
1354 1351  
1355 1352  
1356 1353  
... ... @@ -1359,39 +1356,30 @@
1359 1356 alt = intf->cur_altsetting;
1360 1357  
1361 1358 #ifdef CONFIG_USB_DEVICEFS
1362   - if (add_uevent_var(envp, num_envp, &i,
1363   - buffer, buffer_size, &length,
1364   - "DEVICE=/proc/bus/usb/%03d/%03d",
  1359 + if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
1365 1360 usb_dev->bus->busnum, usb_dev->devnum))
1366 1361 return -ENOMEM;
1367 1362 #endif
1368 1363  
1369   - if (add_uevent_var(envp, num_envp, &i,
1370   - buffer, buffer_size, &length,
1371   - "PRODUCT=%x/%x/%x",
  1364 + if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
1372 1365 le16_to_cpu(usb_dev->descriptor.idVendor),
1373 1366 le16_to_cpu(usb_dev->descriptor.idProduct),
1374 1367 le16_to_cpu(usb_dev->descriptor.bcdDevice)))
1375 1368 return -ENOMEM;
1376 1369  
1377   - if (add_uevent_var(envp, num_envp, &i,
1378   - buffer, buffer_size, &length,
1379   - "TYPE=%d/%d/%d",
  1370 + if (add_uevent_var(env, "TYPE=%d/%d/%d",
1380 1371 usb_dev->descriptor.bDeviceClass,
1381 1372 usb_dev->descriptor.bDeviceSubClass,
1382 1373 usb_dev->descriptor.bDeviceProtocol))
1383 1374 return -ENOMEM;
1384 1375  
1385   - if (add_uevent_var(envp, num_envp, &i,
1386   - buffer, buffer_size, &length,
1387   - "INTERFACE=%d/%d/%d",
  1376 + if (add_uevent_var(env, "INTERFACE=%d/%d/%d",
1388 1377 alt->desc.bInterfaceClass,
1389 1378 alt->desc.bInterfaceSubClass,
1390 1379 alt->desc.bInterfaceProtocol))
1391 1380 return -ENOMEM;
1392 1381  
1393   - if (add_uevent_var(envp, num_envp, &i,
1394   - buffer, buffer_size, &length,
  1382 + if (add_uevent_var(env,
1395 1383 "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
1396 1384 le16_to_cpu(usb_dev->descriptor.idVendor),
1397 1385 le16_to_cpu(usb_dev->descriptor.idProduct),
1398 1386  
... ... @@ -1404,14 +1392,12 @@
1404 1392 alt->desc.bInterfaceProtocol))
1405 1393 return -ENOMEM;
1406 1394  
1407   - envp[i] = NULL;
1408 1395 return 0;
1409 1396 }
1410 1397  
1411 1398 #else
1412 1399  
1413   -static int usb_if_uevent(struct device *dev, char **envp,
1414   - int num_envp, char *buffer, int buffer_size)
  1400 +static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
1415 1401 {
1416 1402 return -ENODEV;
1417 1403 }
... ... @@ -197,7 +197,7 @@
197 197 .fops = &w1_default_fops,
198 198 };
199 199  
200   -static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
  200 +static int w1_uevent(struct device *dev, struct kobj_uevent_env *env);
201 201  
202 202 static struct bus_type w1_bus_type = {
203 203 .name = "w1",
204 204  
... ... @@ -396,13 +396,12 @@
396 396 }
397 397  
398 398 #ifdef CONFIG_HOTPLUG
399   -static int w1_uevent(struct device *dev, char **envp, int num_envp,
400   - char *buffer, int buffer_size)
  399 +static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
401 400 {
402 401 struct w1_master *md = NULL;
403 402 struct w1_slave *sl = NULL;
404 403 char *event_owner, *name;
405   - int err, cur_index=0, cur_len=0;
  404 + int err;
406 405  
407 406 if (dev->driver == &w1_master_driver) {
408 407 md = container_of(dev, struct w1_master, dev);
409 408  
410 409  
... ... @@ -423,23 +422,19 @@
423 422 if (dev->driver != &w1_slave_driver || !sl)
424 423 return 0;
425 424  
426   - err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size,
427   - &cur_len, "W1_FID=%02X", sl->reg_num.family);
  425 + err = add_uevent_var(env, "W1_FID=%02X", sl->reg_num.family);
428 426 if (err)
429 427 return err;
430 428  
431   - err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size,
432   - &cur_len, "W1_SLAVE_ID=%024LX",
433   - (unsigned long long)sl->reg_num.id);
434   - envp[cur_index] = NULL;
  429 + err = add_uevent_var(env, "W1_SLAVE_ID=%024LX",
  430 + (unsigned long long)sl->reg_num.id);
435 431 if (err)
436 432 return err;
437 433  
438 434 return 0;
439 435 };
440 436 #else
441   -static int w1_uevent(struct device *dev, char **envp, int num_envp,
442   - char *buffer, int buffer_size)
  437 +static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
443 438 {
444 439 return 0;
445 440 }
include/asm-powerpc/of_device.h
... ... @@ -20,7 +20,7 @@
20 20 extern ssize_t of_device_get_modalias(struct of_device *ofdev,
21 21 char *str, ssize_t len);
22 22 extern int of_device_uevent(struct device *dev,
23   - char **envp, int num_envp, char *buffer, int buffer_size);
  23 + struct kobj_uevent_env *env);
24 24  
25 25 /* This is just here during the transition */
26 26 #include <linux/of_device.h>
include/linux/device.h
... ... @@ -66,8 +66,7 @@
66 66 struct driver_attribute * drv_attrs;
67 67  
68 68 int (*match)(struct device * dev, struct device_driver * drv);
69   - int (*uevent)(struct device *dev, char **envp,
70   - int num_envp, char *buffer, int buffer_size);
  69 + int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
71 70 int (*probe)(struct device * dev);
72 71 int (*remove)(struct device * dev);
73 72 void (*shutdown)(struct device * dev);
... ... @@ -187,10 +186,8 @@
187 186 struct class_device_attribute * class_dev_attrs;
188 187 struct device_attribute * dev_attrs;
189 188  
190   - int (*uevent)(struct class_device *dev, char **envp,
191   - int num_envp, char *buffer, int buffer_size);
192   - int (*dev_uevent)(struct device *dev, char **envp, int num_envp,
193   - char *buffer, int buffer_size);
  189 + int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env);
  190 + int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
194 191  
195 192 void (*release)(struct class_device *dev);
196 193 void (*class_release)(struct class *class);
... ... @@ -266,8 +263,7 @@
266 263 struct attribute_group ** groups; /* optional groups */
267 264  
268 265 void (*release)(struct class_device *dev);
269   - int (*uevent)(struct class_device *dev, char **envp,
270   - int num_envp, char *buffer, int buffer_size);
  266 + int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env);
271 267 char class_id[BUS_ID_SIZE]; /* unique to this class */
272 268 };
273 269  
... ... @@ -335,8 +331,7 @@
335 331 struct device_type {
336 332 const char *name;
337 333 struct attribute_group **groups;
338   - int (*uevent)(struct device *dev, char **envp, int num_envp,
339   - char *buffer, int buffer_size);
  334 + int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
340 335 void (*release)(struct device *dev);
341 336 int (*suspend)(struct device * dev, pm_message_t state);
342 337 int (*resume)(struct device * dev);
include/linux/kobject.h
... ... @@ -29,6 +29,8 @@
29 29  
30 30 #define KOBJ_NAME_LEN 20
31 31 #define UEVENT_HELPER_PATH_LEN 256
  32 +#define UEVENT_NUM_ENVP 32 /* number of env pointers */
  33 +#define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */
32 34  
33 35 /* path to the userspace helper executed on an event */
34 36 extern char uevent_helper[];
35 37  
... ... @@ -111,11 +113,18 @@
111 113 struct attribute ** default_attrs;
112 114 };
113 115  
  116 +struct kobj_uevent_env {
  117 + char *envp[UEVENT_NUM_ENVP];
  118 + int envp_idx;
  119 + char buf[UEVENT_BUFFER_SIZE];
  120 + int buflen;
  121 +};
  122 +
114 123 struct kset_uevent_ops {
115 124 int (*filter)(struct kset *kset, struct kobject *kobj);
116 125 const char *(*name)(struct kset *kset, struct kobject *kobj);
117   - int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp,
118   - int num_envp, char *buffer, int buffer_size);
  126 + int (*uevent)(struct kset *kset, struct kobject *kobj,
  127 + struct kobj_uevent_env *env);
119 128 };
120 129  
121 130 /*
... ... @@ -275,10 +284,8 @@
275 284 int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
276 285 char *envp[]);
277 286  
278   -int add_uevent_var(char **envp, int num_envp, int *cur_index,
279   - char *buffer, int buffer_size, int *cur_len,
280   - const char *format, ...)
281   - __attribute__((format (printf, 7, 8)));
  287 +int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
  288 + __attribute__((format (printf, 2, 3)));
282 289 #else
283 290 static inline int kobject_uevent(struct kobject *kobj, enum kobject_action action)
284 291 { return 0; }
... ... @@ -287,9 +294,7 @@
287 294 char *envp[])
288 295 { return 0; }
289 296  
290   -static inline int add_uevent_var(char **envp, int num_envp, int *cur_index,
291   - char *buffer, int buffer_size, int *cur_len,
292   - const char *format, ...)
  297 +static inline int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
293 298 { return 0; }
294 299 #endif
295 300  
lib/kobject_uevent.c
... ... @@ -22,8 +22,6 @@
22 22 #include <linux/kobject.h>
23 23 #include <net/sock.h>
24 24  
25   -#define BUFFER_SIZE 2048 /* buffer for the variables */
26   -#define NUM_ENVP 32 /* number of env pointers */
27 25  
28 26 /* the strings here must match the enum in include/linux/kobject.h */
29 27 const char *kobject_actions[] = {
30 28  
31 29  
32 30  
33 31  
... ... @@ -54,31 +52,21 @@
54 52 * corresponding error when it fails.
55 53 */
56 54 int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
57   - char *envp_ext[])
  55 + char *envp_ext[])
58 56 {
59   - char **envp;
60   - char *buffer;
61   - char *scratch;
62   - const char *action_string;
  57 + struct kobj_uevent_env *env;
  58 + const char *action_string = kobject_actions[action];
63 59 const char *devpath = NULL;
64 60 const char *subsystem;
65 61 struct kobject *top_kobj;
66 62 struct kset *kset;
67 63 struct kset_uevent_ops *uevent_ops;
68 64 u64 seq;
69   - char *seq_buff;
70 65 int i = 0;
71 66 int retval = 0;
72   - int j;
73 67  
74 68 pr_debug("%s\n", __FUNCTION__);
75 69  
76   - action_string = kobject_actions[action];
77   - if (!action_string) {
78   - pr_debug("kobject attempted to send uevent without action_string!\n");
79   - return -EINVAL;
80   - }
81   -
82 70 /* search the kset we belong to */
83 71 top_kobj = kobj;
84 72 while (!top_kobj->kset && top_kobj->parent) {
... ... @@ -92,7 +80,7 @@
92 80 kset = top_kobj->kset;
93 81 uevent_ops = kset->uevent_ops;
94 82  
95   - /* skip the event, if the filter returns zero. */
  83 + /* skip the event, if the filter returns zero. */
96 84 if (uevent_ops && uevent_ops->filter)
97 85 if (!uevent_ops->filter(kset, kobj)) {
98 86 pr_debug("kobject filter function caused the event to drop!\n");
99 87  
... ... @@ -109,18 +97,11 @@
109 97 return 0;
110 98 }
111 99  
112   - /* environment index */
113   - envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
114   - if (!envp)
  100 + /* environment buffer */
  101 + env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
  102 + if (!env)
115 103 return -ENOMEM;
116 104  
117   - /* environment values */
118   - buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
119   - if (!buffer) {
120   - retval = -ENOMEM;
121   - goto exit;
122   - }
123   -
124 105 /* complete object path */
125 106 devpath = kobject_get_path(kobj, GFP_KERNEL);
126 107 if (!devpath) {
127 108  
128 109  
129 110  
... ... @@ -128,29 +109,29 @@
128 109 goto exit;
129 110 }
130 111  
131   - /* event environemnt for helper process only */
132   - envp[i++] = "HOME=/";
133   - envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
134   -
135 112 /* default keys */
136   - scratch = buffer;
137   - envp [i++] = scratch;
138   - scratch += sprintf(scratch, "ACTION=%s", action_string) + 1;
139   - envp [i++] = scratch;
140   - scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1;
141   - envp [i++] = scratch;
142   - scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1;
143   - for (j = 0; envp_ext && envp_ext[j]; j++)
144   - envp[i++] = envp_ext[j];
145   - /* just reserve the space, overwrite it after kset call has returned */
146   - envp[i++] = seq_buff = scratch;
147   - scratch += strlen("SEQNUM=18446744073709551616") + 1;
  113 + retval = add_uevent_var(env, "ACTION=%s", action_string);
  114 + if (retval)
  115 + goto exit;
  116 + retval = add_uevent_var(env, "DEVPATH=%s", devpath);
  117 + if (retval)
  118 + goto exit;
  119 + retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);
  120 + if (retval)
  121 + goto exit;
148 122  
  123 + /* keys passed in from the caller */
  124 + if (envp_ext) {
  125 + for (i = 0; envp_ext[i]; i++) {
  126 + retval = add_uevent_var(env, envp_ext[i]);
  127 + if (retval)
  128 + goto exit;
  129 + }
  130 + }
  131 +
149 132 /* let the kset specific function add its stuff */
150 133 if (uevent_ops && uevent_ops->uevent) {
151   - retval = uevent_ops->uevent(kset, kobj,
152   - &envp[i], NUM_ENVP - i, scratch,
153   - BUFFER_SIZE - (scratch - buffer));
  134 + retval = uevent_ops->uevent(kset, kobj, env);
154 135 if (retval) {
155 136 pr_debug ("%s - uevent() returned %d\n",
156 137 __FUNCTION__, retval);
157 138  
... ... @@ -158,11 +139,13 @@
158 139 }
159 140 }
160 141  
161   - /* we will send an event, request a new sequence number */
  142 + /* we will send an event, so request a new sequence number */
162 143 spin_lock(&sequence_lock);
163 144 seq = ++uevent_seqnum;
164 145 spin_unlock(&sequence_lock);
165   - sprintf(seq_buff, "SEQNUM=%llu", (unsigned long long)seq);
  146 + retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq);
  147 + if (retval)
  148 + goto exit;
166 149  
167 150 #if defined(CONFIG_NET)
168 151 /* send netlink message */
169 152  
170 153  
171 154  
... ... @@ -172,17 +155,19 @@
172 155  
173 156 /* allocate message with the maximum possible size */
174 157 len = strlen(action_string) + strlen(devpath) + 2;
175   - skb = alloc_skb(len + BUFFER_SIZE, GFP_KERNEL);
  158 + skb = alloc_skb(len + env->buflen, GFP_KERNEL);
176 159 if (skb) {
  160 + char *scratch;
  161 +
177 162 /* add header */
178 163 scratch = skb_put(skb, len);
179 164 sprintf(scratch, "%s@%s", action_string, devpath);
180 165  
181 166 /* copy keys to our continuous event payload buffer */
182   - for (i = 2; envp[i]; i++) {
183   - len = strlen(envp[i]) + 1;
  167 + for (i = 0; i < env->envp_idx; i++) {
  168 + len = strlen(env->envp[i]) + 1;
184 169 scratch = skb_put(skb, len);
185   - strcpy(scratch, envp[i]);
  170 + strcpy(scratch, env->envp[i]);
186 171 }
187 172  
188 173 NETLINK_CB(skb).dst_group = 1;
189 174  
... ... @@ -198,13 +183,19 @@
198 183 argv [0] = uevent_helper;
199 184 argv [1] = (char *)subsystem;
200 185 argv [2] = NULL;
201   - call_usermodehelper (argv[0], argv, envp, UMH_WAIT_EXEC);
  186 + retval = add_uevent_var(env, "HOME=/");
  187 + if (retval)
  188 + goto exit;
  189 + retval = add_uevent_var(env, "PATH=/sbin:/bin:/usr/sbin:/usr/bin");
  190 + if (retval)
  191 + goto exit;
  192 +
  193 + call_usermodehelper (argv[0], argv, env->envp, UMH_WAIT_EXEC);
202 194 }
203 195  
204 196 exit:
205 197 kfree(devpath);
206   - kfree(buffer);
207   - kfree(envp);
  198 + kfree(env);
208 199 return retval;
209 200 }
210 201  
211 202  
212 203  
213 204  
214 205  
215 206  
216 207  
217 208  
218 209  
219 210  
... ... @@ -227,52 +218,38 @@
227 218 EXPORT_SYMBOL_GPL(kobject_uevent);
228 219  
229 220 /**
230   - * add_uevent_var - helper for creating event variables
231   - * @envp: Pointer to table of environment variables, as passed into
232   - * uevent() method.
233   - * @num_envp: Number of environment variable slots available, as
234   - * passed into uevent() method.
235   - * @cur_index: Pointer to current index into @envp. It should be
236   - * initialized to 0 before the first call to add_uevent_var(),
237   - * and will be incremented on success.
238   - * @buffer: Pointer to buffer for environment variables, as passed
239   - * into uevent() method.
240   - * @buffer_size: Length of @buffer, as passed into uevent() method.
241   - * @cur_len: Pointer to current length of space used in @buffer.
242   - * Should be initialized to 0 before the first call to
243   - * add_uevent_var(), and will be incremented on success.
244   - * @format: Format for creating environment variable (of the form
245   - * "XXX=%x") for snprintf().
  221 + * add_uevent_var - add key value string to the environment buffer
  222 + * @env: environment buffer structure
  223 + * @format: printf format for the key=value pair
246 224 *
247 225 * Returns 0 if environment variable was added successfully or -ENOMEM
248 226 * if no space was available.
249 227 */
250   -int add_uevent_var(char **envp, int num_envp, int *cur_index,
251   - char *buffer, int buffer_size, int *cur_len,
252   - const char *format, ...)
  228 +int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
253 229 {
254 230 va_list args;
  231 + int len;
255 232  
256   - /*
257   - * We check against num_envp - 1 to make sure there is at
258   - * least one slot left after we return, since kobject_uevent()
259   - * needs to set the last slot to NULL.
260   - */
261   - if (*cur_index >= num_envp - 1)
  233 + if (env->envp_idx >= ARRAY_SIZE(env->envp)) {
  234 + printk(KERN_ERR "add_uevent_var: too many keys\n");
  235 + WARN_ON(1);
262 236 return -ENOMEM;
  237 + }
263 238  
264   - envp[*cur_index] = buffer + *cur_len;
265   -
266 239 va_start(args, format);
267   - *cur_len += vsnprintf(envp[*cur_index],
268   - max(buffer_size - *cur_len, 0),
269   - format, args) + 1;
  240 + len = vsnprintf(&env->buf[env->buflen],
  241 + sizeof(env->buf) - env->buflen,
  242 + format, args);
270 243 va_end(args);
271 244  
272   - if (*cur_len > buffer_size)
  245 + if (len >= (sizeof(env->buf) - env->buflen)) {
  246 + printk(KERN_ERR "add_uevent_var: buffer size too small\n");
  247 + WARN_ON(1);
273 248 return -ENOMEM;
  249 + }
274 250  
275   - (*cur_index)++;
  251 + env->envp[env->envp_idx++] = &env->buf[env->buflen];
  252 + env->buflen += len + 1;
276 253 return 0;
277 254 }
278 255 EXPORT_SYMBOL_GPL(add_uevent_var);
... ... @@ -105,10 +105,9 @@
105 105 NULL
106 106 };
107 107  
108   -static int atm_uevent(struct class_device *cdev, char **envp, int num_envp, char *buf, int size)
  108 +static int atm_uevent(struct class_device *cdev, struct kobj_uevent_env *env)
109 109 {
110 110 struct atm_dev *adev;
111   - int i = 0, len = 0;
112 111  
113 112 if (!cdev)
114 113 return -ENODEV;
115 114  
... ... @@ -117,11 +116,9 @@
117 116 if (!adev)
118 117 return -ENODEV;
119 118  
120   - if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
121   - "NAME=%s%d", adev->type, adev->number))
  119 + if (add_uevent_var(env, "NAME=%s%d", adev->type, adev->number))
122 120 return -ENOMEM;
123 121  
124   - envp[i] = NULL;
125 122 return 0;
126 123 }
127 124  
net/core/net-sysfs.c
... ... @@ -396,28 +396,22 @@
396 396 #endif /* CONFIG_SYSFS */
397 397  
398 398 #ifdef CONFIG_HOTPLUG
399   -static int netdev_uevent(struct device *d, char **envp,
400   - int num_envp, char *buf, int size)
  399 +static int netdev_uevent(struct device *d, struct kobj_uevent_env *env)
401 400 {
402 401 struct net_device *dev = to_net_dev(d);
403   - int retval, len = 0, i = 0;
  402 + int retval;
404 403  
405 404 /* pass interface to uevent. */
406   - retval = add_uevent_var(envp, num_envp, &i,
407   - buf, size, &len,
408   - "INTERFACE=%s", dev->name);
  405 + retval = add_uevent_var(env, "INTERFACE=%s", dev->name);
409 406 if (retval)
410 407 goto exit;
411 408  
412 409 /* pass ifindex to uevent.
413 410 * ifindex is useful as it won't change (interface name may change)
414 411 * and is what RtNetlink uses natively. */
415   - retval = add_uevent_var(envp, num_envp, &i,
416   - buf, size, &len,
417   - "IFINDEX=%d", dev->ifindex);
  412 + retval = add_uevent_var(env, "IFINDEX=%d", dev->ifindex);
418 413  
419 414 exit:
420   - envp[i] = NULL;
421 415 return retval;
422 416 }
423 417 #endif
net/wireless/sysfs.c
... ... @@ -53,8 +53,7 @@
53 53 }
54 54  
55 55 #ifdef CONFIG_HOTPLUG
56   -static int wiphy_uevent(struct device *dev, char **envp,
57   - int num_envp, char *buf, int size)
  56 +static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
58 57 {
59 58 /* TODO, we probably need stuff here */
60 59 return 0;
sound/aoa/soundbus/core.c
... ... @@ -56,13 +56,12 @@
56 56 }
57 57  
58 58  
59   -static int soundbus_uevent(struct device *dev, char **envp, int num_envp,
60   - char *buffer, int buffer_size)
  59 +static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env)
61 60 {
62 61 struct soundbus_dev * soundbus_dev;
63 62 struct of_device * of;
64 63 const char *compat;
65   - int retval = 0, i = 0, length = 0;
  64 + int retval = 0;
66 65 int cplen, seen = 0;
67 66  
68 67 if (!dev)
69 68  
... ... @@ -75,15 +74,11 @@
75 74 of = &soundbus_dev->ofdev;
76 75  
77 76 /* stuff we want to pass to /sbin/hotplug */
78   - retval = add_uevent_var(envp, num_envp, &i,
79   - buffer, buffer_size, &length,
80   - "OF_NAME=%s", of->node->name);
  77 + retval = add_uevent_var(env, "OF_NAME=%s", of->node->name);
81 78 if (retval)
82 79 return retval;
83 80  
84   - retval = add_uevent_var(envp, num_envp, &i,
85   - buffer, buffer_size, &length,
86   - "OF_TYPE=%s", of->node->type);
  81 + retval = add_uevent_var(env, "OF_TYPE=%s", of->node->type);
87 82 if (retval)
88 83 return retval;
89 84  
90 85  
91 86  
92 87  
... ... @@ -93,27 +88,19 @@
93 88  
94 89 compat = of_get_property(of->node, "compatible", &cplen);
95 90 while (compat && cplen > 0) {
96   - int tmp = length;
97   - retval = add_uevent_var(envp, num_envp, &i,
98   - buffer, buffer_size, &length,
99   - "OF_COMPATIBLE_%d=%s", seen, compat);
  91 + int tmp = env->buflen;
  92 + retval = add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
100 93 if (retval)
101 94 return retval;
102   - compat += length - tmp;
103   - cplen -= length - tmp;
  95 + compat += env->buflen - tmp;
  96 + cplen -= env->buflen - tmp;
104 97 seen += 1;
105 98 }
106 99  
107   - retval = add_uevent_var(envp, num_envp, &i,
108   - buffer, buffer_size, &length,
109   - "OF_COMPATIBLE_N=%d", seen);
  100 + retval = add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
110 101 if (retval)
111 102 return retval;
112   - retval = add_uevent_var(envp, num_envp, &i,
113   - buffer, buffer_size, &length,
114   - "MODALIAS=%s", soundbus_dev->modalias);
115   -
116   - envp[i] = NULL;
  103 + retval = add_uevent_var(env, "MODALIAS=%s", soundbus_dev->modalias);
117 104  
118 105 return retval;
119 106 }