Commit 7eff2e7a8b65c25920207324e56611150eb1cd9a
Committed by
Greg Kroah-Hartman
1 parent
8380770c84
Exists in
master
and in
7 other branches
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
- arch/powerpc/kernel/of_device.c
- arch/powerpc/kernel/vio.c
- arch/powerpc/platforms/ps3/system-bus.c
- block/genhd.c
- drivers/acpi/scan.c
- drivers/amba/bus.c
- drivers/base/class.c
- drivers/base/core.c
- drivers/base/firmware_class.c
- drivers/base/memory.c
- drivers/base/platform.c
- drivers/eisa/eisa-bus.c
- drivers/firewire/fw-device.c
- drivers/firmware/dmi-id.c
- drivers/i2c/i2c-core.c
- drivers/ide/ide.c
- drivers/ieee1394/nodemgr.c
- drivers/infiniband/core/sysfs.c
- drivers/input/input.c
- drivers/input/serio/serio.c
- drivers/media/video/pvrusb2/pvrusb2-sysfs.c
- drivers/misc/tifm_core.c
- drivers/mmc/core/bus.c
- drivers/pci/hotplug.c
- drivers/pci/pci-driver.c
- drivers/pci/pci.h
- drivers/pcmcia/cs.c
- drivers/pcmcia/ds.c
- drivers/power/power_supply.h
- drivers/power/power_supply_sysfs.c
- drivers/s390/cio/ccwgroup.c
- drivers/s390/cio/device.c
- drivers/s390/crypto/ap_bus.c
- drivers/scsi/scsi_sysfs.c
- drivers/spi/spi.c
- drivers/usb/core/driver.c
- drivers/usb/core/message.c
- drivers/w1/w1.c
- include/asm-powerpc/of_device.h
- include/linux/device.h
- include/linux/kobject.h
- lib/kobject_uevent.c
- net/atm/atm_sysfs.c
- net/core/net-sysfs.c
- net/wireless/sysfs.c
- sound/aoa/soundbus/core.c
arch/ia64/sn/kernel/tiocx.c
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 |
block/genhd.c
... | ... | @@ -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 | } |
drivers/acpi/scan.c
... | ... | @@ -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 |
drivers/amba/bus.c
... | ... | @@ -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 | } |
drivers/base/core.c
... | ... | @@ -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 | } |
drivers/ide/ide.c
... | ... | @@ -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
drivers/pci/pci.h
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); |
drivers/pcmcia/cs.c
... | ... | @@ -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 | } |
drivers/pcmcia/ds.c
... | ... | @@ -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
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 |
drivers/spi/spi.c
... | ... | @@ -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 | } |
drivers/w1/w1.c
... | ... | @@ -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); |
net/atm/atm_sysfs.c
... | ... | @@ -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 | } |