aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/powerpc/eeh-pci-error-recovery.txt31
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/common/amba.c6
-rw-r--r--arch/ia64/sn/kernel/tiocx.c4
-rw-r--r--arch/powerpc/kernel/vio.c2
-rw-r--r--block/genhd.c48
-rw-r--r--drivers/acpi/container.c8
-rw-r--r--drivers/acpi/processor_core.c8
-rw-r--r--drivers/acpi/scan.c14
-rw-r--r--drivers/base/Kconfig4
-rw-r--r--drivers/base/bus.c41
-rw-r--r--drivers/base/class.c66
-rw-r--r--drivers/base/core.c42
-rw-r--r--drivers/base/cpu.c4
-rw-r--r--drivers/base/dd.c15
-rw-r--r--drivers/base/firmware_class.c45
-rw-r--r--drivers/base/memory.c12
-rw-r--r--drivers/base/platform.c68
-rw-r--r--drivers/base/power/runtime.c2
-rw-r--r--drivers/ide/ide-cd.c1
-rw-r--r--drivers/ide/ide-disk.c1
-rw-r--r--drivers/ide/ide-floppy.c1
-rw-r--r--drivers/ide/ide-tape.c1
-rw-r--r--drivers/ide/ide.c60
-rw-r--r--drivers/ieee1394/nodemgr.c20
-rw-r--r--drivers/infiniband/core/sysfs.c16
-rw-r--r--drivers/input/input.c54
-rw-r--r--drivers/input/serio/serio.c22
-rw-r--r--drivers/macintosh/macio_asic.c4
-rw-r--r--drivers/mmc/mmc_sysfs.c4
-rw-r--r--drivers/pci/hotplug.c44
-rw-r--r--drivers/pci/pci-driver.c6
-rw-r--r--drivers/pci/pci.h4
-rw-r--r--drivers/pcmcia/cs.c10
-rw-r--r--drivers/pcmcia/ds.c50
-rw-r--r--drivers/pnp/pnpbios/core.c8
-rw-r--r--drivers/s390/cio/ccwgroup.c4
-rw-r--r--drivers/s390/cio/device.c4
-rw-r--r--drivers/s390/crypto/z90main.c1
-rw-r--r--drivers/scsi/ipr.c2
-rw-r--r--drivers/usb/core/usb.c84
-rw-r--r--drivers/usb/host/hc_crisv10.c2
-rw-r--r--drivers/w1/w1.c14
-rw-r--r--fs/partitions/check.c33
-rw-r--r--fs/super.c15
-rw-r--r--fs/sysfs/dir.c6
-rw-r--r--include/linux/device.h14
-rw-r--r--include/linux/firmware.h2
-rw-r--r--include/linux/input.h79
-rw-r--r--include/linux/kobject.h54
-rw-r--r--include/linux/kobject_uevent.h57
-rw-r--r--include/linux/platform_device.h1
-rw-r--r--include/linux/sysctl.h2
-rw-r--r--include/linux/usb.h2
-rw-r--r--init/Kconfig36
-rw-r--r--kernel/ksysfs.c30
-rw-r--r--kernel/sysctl.c8
-rw-r--r--lib/klist.c2
-rw-r--r--lib/kobject.c4
-rw-r--r--lib/kobject_uevent.c349
-rw-r--r--net/bluetooth/hci_sysfs.c4
-rw-r--r--net/bridge/br_sysfs_if.c4
-rw-r--r--net/core/net-sysfs.c76
-rw-r--r--scripts/mod/file2alias.c62
64 files changed, 869 insertions, 814 deletions
diff --git a/Documentation/powerpc/eeh-pci-error-recovery.txt b/Documentation/powerpc/eeh-pci-error-recovery.txt
index e75d7474322..67a11a36270 100644
--- a/Documentation/powerpc/eeh-pci-error-recovery.txt
+++ b/Documentation/powerpc/eeh-pci-error-recovery.txt
@@ -115,7 +115,7 @@ Current PPC64 Linux EEH Implementation
115At this time, a generic EEH recovery mechanism has been implemented, 115At this time, a generic EEH recovery mechanism has been implemented,
116so that individual device drivers do not need to be modified to support 116so that individual device drivers do not need to be modified to support
117EEH recovery. This generic mechanism piggy-backs on the PCI hotplug 117EEH recovery. This generic mechanism piggy-backs on the PCI hotplug
118infrastructure, and percolates events up through the hotplug/udev 118infrastructure, and percolates events up through the userspace/udev
119infrastructure. Followiing is a detailed description of how this is 119infrastructure. Followiing is a detailed description of how this is
120accomplished. 120accomplished.
121 121
@@ -172,7 +172,7 @@ A handler for the EEH notifier_block events is implemented in
172drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events(). 172drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events().
173It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter(). 173It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter().
174This last call causes the device driver for the card to be stopped, 174This last call causes the device driver for the card to be stopped,
175which causes hotplug events to go out to user space. This triggers 175which causes uevents to go out to user space. This triggers
176user-space scripts that might issue commands such as "ifdown eth0" 176user-space scripts that might issue commands such as "ifdown eth0"
177for ethernet cards, and so on. This handler then sleeps for 5 seconds, 177for ethernet cards, and so on. This handler then sleeps for 5 seconds,
178hoping to give the user-space scripts enough time to complete. 178hoping to give the user-space scripts enough time to complete.
@@ -258,29 +258,30 @@ rpa_php_unconfig_pci_adapter() { // in rpaphp_pci.c
258 calls 258 calls
259 pci_destroy_dev (struct pci_dev *) { 259 pci_destroy_dev (struct pci_dev *) {
260 calls 260 calls
261 device_unregister (&dev->dev) { // in /drivers/base/core.c 261 device_unregister (&dev->dev) { // in /drivers/base/core.c
262 calls 262 calls
263 device_del(struct device * dev) { // in /drivers/base/core.c 263 device_del(struct device * dev) { // in /drivers/base/core.c
264 calls 264 calls
265 kobject_del() { //in /libs/kobject.c 265 kobject_del() { //in /libs/kobject.c
266 calls 266 calls
267 kobject_hotplug() { // in /libs/kobject.c 267 kobject_uevent() { // in /libs/kobject.c
268 calls 268 calls
269 kset_hotplug() { // in /lib/kobject.c 269 kset_uevent() { // in /lib/kobject.c
270 calls 270 calls
271 kset->hotplug_ops->hotplug() which is really just 271 kset->uevent_ops->uevent() // which is really just
272 a call to 272 a call to
273 dev_hotplug() { // in /drivers/base/core.c 273 dev_uevent() { // in /drivers/base/core.c
274 calls 274 calls
275 dev->bus->hotplug() which is really just a call to 275 dev->bus->uevent() which is really just a call to
276 pci_hotplug () { // in drivers/pci/hotplug.c 276 pci_uevent () { // in drivers/pci/hotplug.c
277 which prints device name, etc.... 277 which prints device name, etc....
278 } 278 }
279 } 279 }
280 then kset_hotplug() calls 280 then kobject_uevent() sends a netlink uevent to userspace
281 call_usermodehelper () with 281 --> userspace uevent
282 argv[0]=hotplug_path[] which is "/sbin/hotplug" 282 (during early boot, nobody listens to netlink events and
283 --> event to userspace, 283 kobject_uevent() executes uevent_helper[], which runs the
284 event process /sbin/hotplug)
284 } 285 }
285 } 286 }
286 kobject_del() then calls sysfs_remove_dir(), which would 287 kobject_del() then calls sysfs_remove_dir(), which would
diff --git a/MAINTAINERS b/MAINTAINERS
index 1e59d396601..6246b7f1163 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1480,12 +1480,6 @@ W: http://nfs.sourceforge.net/
1480W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/ 1480W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
1481S: Maintained 1481S: Maintained
1482 1482
1483KERNEL EVENT LAYER (KOBJECT_UEVENT)
1484P: Robert Love
1485M: rml@novell.com
1486L: linux-kernel@vger.kernel.org
1487S: Maintained
1488
1489KEXEC 1483KEXEC
1490P: Eric Biederman 1484P: Eric Biederman
1491P: Randy Dunlap 1485P: Randy Dunlap
diff --git a/arch/arm/common/amba.c b/arch/arm/common/amba.c
index e1013112c35..c95ec9eab99 100644
--- a/arch/arm/common/amba.c
+++ b/arch/arm/common/amba.c
@@ -45,7 +45,7 @@ static int amba_match(struct device *dev, struct device_driver *drv)
45} 45}
46 46
47#ifdef CONFIG_HOTPLUG 47#ifdef CONFIG_HOTPLUG
48static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, int bufsz) 48static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
49{ 49{
50 struct amba_device *pcdev = to_amba_device(dev); 50 struct amba_device *pcdev = to_amba_device(dev);
51 51
@@ -58,7 +58,7 @@ static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf,
58 return 0; 58 return 0;
59} 59}
60#else 60#else
61#define amba_hotplug NULL 61#define amba_uevent NULL
62#endif 62#endif
63 63
64static int amba_suspend(struct device *dev, pm_message_t state) 64static int amba_suspend(struct device *dev, pm_message_t state)
@@ -88,7 +88,7 @@ static int amba_resume(struct device *dev)
88static struct bus_type amba_bustype = { 88static struct bus_type amba_bustype = {
89 .name = "amba", 89 .name = "amba",
90 .match = amba_match, 90 .match = amba_match,
91 .hotplug = amba_hotplug, 91 .uevent = amba_uevent,
92 .suspend = amba_suspend, 92 .suspend = amba_suspend,
93 .resume = amba_resume, 93 .resume = amba_resume,
94}; 94};
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index 0d8592a745a..768c21deb2e 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -65,7 +65,7 @@ static int tiocx_match(struct device *dev, struct device_driver *drv)
65 65
66} 66}
67 67
68static int tiocx_hotplug(struct device *dev, char **envp, int num_envp, 68static int tiocx_uevent(struct device *dev, char **envp, int num_envp,
69 char *buffer, int buffer_size) 69 char *buffer, int buffer_size)
70{ 70{
71 return -ENODEV; 71 return -ENODEV;
@@ -79,7 +79,7 @@ static void tiocx_bus_release(struct device *dev)
79struct bus_type tiocx_bus_type = { 79struct bus_type tiocx_bus_type = {
80 .name = "tiocx", 80 .name = "tiocx",
81 .match = tiocx_match, 81 .match = tiocx_match,
82 .hotplug = tiocx_hotplug, 82 .uevent = tiocx_uevent,
83}; 83};
84 84
85/** 85/**
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 71a6addf9f7..13c41495fe0 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -293,6 +293,6 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
293 293
294struct bus_type vio_bus_type = { 294struct bus_type vio_bus_type = {
295 .name = "vio", 295 .name = "vio",
296 .hotplug = vio_hotplug, 296 .uevent = vio_hotplug,
297 .match = vio_bus_match, 297 .match = vio_bus_match,
298}; 298};
diff --git a/block/genhd.c b/block/genhd.c
index f04609d553b..f1ed83f3f08 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -358,7 +358,7 @@ static struct sysfs_ops disk_sysfs_ops = {
358static ssize_t disk_uevent_store(struct gendisk * disk, 358static ssize_t disk_uevent_store(struct gendisk * disk,
359 const char *buf, size_t count) 359 const char *buf, size_t count)
360{ 360{
361 kobject_hotplug(&disk->kobj, KOBJ_ADD); 361 kobject_uevent(&disk->kobj, KOBJ_ADD);
362 return count; 362 return count;
363} 363}
364static ssize_t disk_dev_read(struct gendisk * disk, char *page) 364static ssize_t disk_dev_read(struct gendisk * disk, char *page)
@@ -455,14 +455,14 @@ static struct kobj_type ktype_block = {
455 455
456extern struct kobj_type ktype_part; 456extern struct kobj_type ktype_part;
457 457
458static int block_hotplug_filter(struct kset *kset, struct kobject *kobj) 458static int block_uevent_filter(struct kset *kset, struct kobject *kobj)
459{ 459{
460 struct kobj_type *ktype = get_ktype(kobj); 460 struct kobj_type *ktype = get_ktype(kobj);
461 461
462 return ((ktype == &ktype_block) || (ktype == &ktype_part)); 462 return ((ktype == &ktype_block) || (ktype == &ktype_part));
463} 463}
464 464
465static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp, 465static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp,
466 int num_envp, char *buffer, int buffer_size) 466 int num_envp, char *buffer, int buffer_size)
467{ 467{
468 struct kobj_type *ktype = get_ktype(kobj); 468 struct kobj_type *ktype = get_ktype(kobj);
@@ -474,40 +474,40 @@ static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
474 474
475 if (ktype == &ktype_block) { 475 if (ktype == &ktype_block) {
476 disk = container_of(kobj, struct gendisk, kobj); 476 disk = container_of(kobj, struct gendisk, kobj);
477 add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, 477 add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
478 &length, "MINOR=%u", disk->first_minor); 478 &length, "MINOR=%u", disk->first_minor);
479 } else if (ktype == &ktype_part) { 479 } else if (ktype == &ktype_part) {
480 disk = container_of(kobj->parent, struct gendisk, kobj); 480 disk = container_of(kobj->parent, struct gendisk, kobj);
481 part = container_of(kobj, struct hd_struct, kobj); 481 part = container_of(kobj, struct hd_struct, kobj);
482 add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, 482 add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
483 &length, "MINOR=%u", 483 &length, "MINOR=%u",
484 disk->first_minor + part->partno); 484 disk->first_minor + part->partno);
485 } else 485 } else
486 return 0; 486 return 0;
487 487
488 add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &length, 488 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
489 "MAJOR=%u", disk->major); 489 "MAJOR=%u", disk->major);
490 490
491 /* add physical device, backing this device */ 491 /* add physical device, backing this device */
492 physdev = disk->driverfs_dev; 492 physdev = disk->driverfs_dev;
493 if (physdev) { 493 if (physdev) {
494 char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL); 494 char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
495 495
496 add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, 496 add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
497 &length, "PHYSDEVPATH=%s", path); 497 &length, "PHYSDEVPATH=%s", path);
498 kfree(path); 498 kfree(path);
499 499
500 if (physdev->bus) 500 if (physdev->bus)
501 add_hotplug_env_var(envp, num_envp, &i, 501 add_uevent_var(envp, num_envp, &i,
502 buffer, buffer_size, &length, 502 buffer, buffer_size, &length,
503 "PHYSDEVBUS=%s", 503 "PHYSDEVBUS=%s",
504 physdev->bus->name); 504 physdev->bus->name);
505 505
506 if (physdev->driver) 506 if (physdev->driver)
507 add_hotplug_env_var(envp, num_envp, &i, 507 add_uevent_var(envp, num_envp, &i,
508 buffer, buffer_size, &length, 508 buffer, buffer_size, &length,
509 "PHYSDEVDRIVER=%s", 509 "PHYSDEVDRIVER=%s",
510 physdev->driver->name); 510 physdev->driver->name);
511 } 511 }
512 512
513 /* terminate, set to next free slot, shrink available space */ 513 /* terminate, set to next free slot, shrink available space */
@@ -520,13 +520,13 @@ static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
520 return 0; 520 return 0;
521} 521}
522 522
523static struct kset_hotplug_ops block_hotplug_ops = { 523static struct kset_uevent_ops block_uevent_ops = {
524 .filter = block_hotplug_filter, 524 .filter = block_uevent_filter,
525 .hotplug = block_hotplug, 525 .uevent = block_uevent,
526}; 526};
527 527
528/* declare block_subsys. */ 528/* declare block_subsys. */
529static decl_subsys(block, &ktype_block, &block_hotplug_ops); 529static decl_subsys(block, &ktype_block, &block_uevent_ops);
530 530
531 531
532/* 532/*
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 27ec12c1fab..b69a8cad82b 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -172,21 +172,21 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
172 if (ACPI_FAILURE(status) || !device) { 172 if (ACPI_FAILURE(status) || !device) {
173 result = container_device_add(&device, handle); 173 result = container_device_add(&device, handle);
174 if (!result) 174 if (!result)
175 kobject_hotplug(&device->kobj, 175 kobject_uevent(&device->kobj,
176 KOBJ_ONLINE); 176 KOBJ_ONLINE);
177 else 177 else
178 printk("Failed to add container\n"); 178 printk("Failed to add container\n");
179 } 179 }
180 } else { 180 } else {
181 if (ACPI_SUCCESS(status)) { 181 if (ACPI_SUCCESS(status)) {
182 /* device exist and this is a remove request */ 182 /* device exist and this is a remove request */
183 kobject_hotplug(&device->kobj, KOBJ_OFFLINE); 183 kobject_uevent(&device->kobj, KOBJ_OFFLINE);
184 } 184 }
185 } 185 }
186 break; 186 break;
187 case ACPI_NOTIFY_EJECT_REQUEST: 187 case ACPI_NOTIFY_EJECT_REQUEST:
188 if (!acpi_bus_get_device(handle, &device) && device) { 188 if (!acpi_bus_get_device(handle, &device) && device) {
189 kobject_hotplug(&device->kobj, KOBJ_OFFLINE); 189 kobject_uevent(&device->kobj, KOBJ_OFFLINE);
190 } 190 }
191 break; 191 break;
192 default: 192 default:
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 0c561c571f2..1278aca96fe 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -748,7 +748,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
748 return_VALUE(-ENODEV); 748 return_VALUE(-ENODEV);
749 749
750 if ((pr->id >= 0) && (pr->id < NR_CPUS)) { 750 if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
751 kobject_hotplug(&(*device)->kobj, KOBJ_ONLINE); 751 kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
752 } 752 }
753 return_VALUE(0); 753 return_VALUE(0);
754} 754}
@@ -788,13 +788,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
788 } 788 }
789 789
790 if (pr->id >= 0 && (pr->id < NR_CPUS)) { 790 if (pr->id >= 0 && (pr->id < NR_CPUS)) {
791 kobject_hotplug(&device->kobj, KOBJ_OFFLINE); 791 kobject_uevent(&device->kobj, KOBJ_OFFLINE);
792 break; 792 break;
793 } 793 }
794 794
795 result = acpi_processor_start(device); 795 result = acpi_processor_start(device);
796 if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) { 796 if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
797 kobject_hotplug(&device->kobj, KOBJ_ONLINE); 797 kobject_uevent(&device->kobj, KOBJ_ONLINE);
798 } else { 798 } else {
799 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 799 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
800 "Device [%s] failed to start\n", 800 "Device [%s] failed to start\n",
@@ -818,7 +818,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
818 } 818 }
819 819
820 if ((pr->id < NR_CPUS) && (cpu_present(pr->id))) 820 if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
821 kobject_hotplug(&device->kobj, KOBJ_OFFLINE); 821 kobject_uevent(&device->kobj, KOBJ_OFFLINE);
822 break; 822 break;
823 default: 823 default:
824 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 824 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 31218e1d2a1..0745d20afb8 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -78,7 +78,7 @@ static struct kobj_type ktype_acpi_ns = {
78 .release = acpi_device_release, 78 .release = acpi_device_release,
79}; 79};
80 80
81static int namespace_hotplug(struct kset *kset, struct kobject *kobj, 81static int namespace_uevent(struct kset *kset, struct kobject *kobj,
82 char **envp, int num_envp, char *buffer, 82 char **envp, int num_envp, char *buffer,
83 int buffer_size) 83 int buffer_size)
84{ 84{
@@ -89,8 +89,8 @@ static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
89 if (!dev->driver) 89 if (!dev->driver)
90 return 0; 90 return 0;
91 91
92 if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len, 92 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
93 "PHYSDEVDRIVER=%s", dev->driver->name)) 93 "PHYSDEVDRIVER=%s", dev->driver->name))
94 return -ENOMEM; 94 return -ENOMEM;
95 95
96 envp[i] = NULL; 96 envp[i] = NULL;
@@ -98,8 +98,8 @@ static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
98 return 0; 98 return 0;
99} 99}
100 100
101static struct kset_hotplug_ops namespace_hotplug_ops = { 101static struct kset_uevent_ops namespace_uevent_ops = {
102 .hotplug = &namespace_hotplug, 102 .uevent = &namespace_uevent,
103}; 103};
104 104
105static struct kset acpi_namespace_kset = { 105static struct kset acpi_namespace_kset = {
@@ -108,7 +108,7 @@ static struct kset acpi_namespace_kset = {
108 }, 108 },
109 .subsys = &acpi_subsys, 109 .subsys = &acpi_subsys,
110 .ktype = &ktype_acpi_ns, 110 .ktype = &ktype_acpi_ns,
111 .hotplug_ops = &namespace_hotplug_ops, 111 .uevent_ops = &namespace_uevent_ops,
112}; 112};
113 113
114static void acpi_device_register(struct acpi_device *device, 114static void acpi_device_register(struct acpi_device *device,
@@ -347,7 +347,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
347} 347}
348 348
349/* -------------------------------------------------------------------------- 349/* --------------------------------------------------------------------------
350 ACPI hotplug sysfs device file support 350 ACPI sysfs device file support
351 -------------------------------------------------------------------------- */ 351 -------------------------------------------------------------------------- */
352static ssize_t acpi_eject_store(struct acpi_device *device, 352static ssize_t acpi_eject_store(struct acpi_device *device,
353 const char *buf, size_t count); 353 const char *buf, size_t count);
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 934149c1512..f0eff3dac58 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -19,11 +19,11 @@ config PREVENT_FIRMWARE_BUILD
19 If unsure say Y here. 19 If unsure say Y here.
20 20
21config FW_LOADER 21config FW_LOADER
22 tristate "Hotplug firmware loading support" 22 tristate "Userspace firmware loading support"
23 select HOTPLUG 23 select HOTPLUG
24 ---help--- 24 ---help---
25 This option is provided for the case where no in-kernel-tree modules 25 This option is provided for the case where no in-kernel-tree modules
26 require hotplug firmware loading support, but a module built outside 26 require userspace firmware loading support, but a module built outside
27 the kernel tree does. 27 the kernel tree does.
28 28
29config DEBUG_DRIVER 29config DEBUG_DRIVER
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index fa601b085eb..29f6af554e7 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -152,7 +152,11 @@ static ssize_t driver_unbind(struct device_driver *drv,
152 152
153 dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); 153 dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
154 if (dev && dev->driver == drv) { 154 if (dev && dev->driver == drv) {
155 if (dev->parent) /* Needed for USB */
156 down(&dev->parent->sem);
155 device_release_driver(dev); 157 device_release_driver(dev);
158 if (dev->parent)
159 up(&dev->parent->sem);
156 err = count; 160 err = count;
157 } 161 }
158 put_device(dev); 162 put_device(dev);
@@ -175,9 +179,13 @@ static ssize_t driver_bind(struct device_driver *drv,
175 179
176 dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); 180 dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
177 if (dev && dev->driver == NULL) { 181 if (dev && dev->driver == NULL) {
182 if (dev->parent) /* Needed for USB */
183 down(&dev->parent->sem);
178 down(&dev->sem); 184 down(&dev->sem);
179 err = driver_probe_device(drv, dev); 185 err = driver_probe_device(drv, dev);
180 up(&dev->sem); 186 up(&dev->sem);
187 if (dev->parent)
188 up(&dev->parent->sem);
181 } 189 }
182 put_device(dev); 190 put_device(dev);
183 put_bus(bus); 191 put_bus(bus);
@@ -420,6 +428,26 @@ static void driver_remove_attrs(struct bus_type * bus, struct device_driver * dr
420 } 428 }
421} 429}
422 430
431#ifdef CONFIG_HOTPLUG
432/*
433 * Thanks to drivers making their tables __devinit, we can't allow manual
434 * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled.
435 */
436static void add_bind_files(struct device_driver *drv)
437{
438 driver_create_file(drv, &driver_attr_unbind);
439 driver_create_file(drv, &driver_attr_bind);
440}
441
442static void remove_bind_files(struct device_driver *drv)
443{
444 driver_remove_file(drv, &driver_attr_bind);
445 driver_remove_file(drv, &driver_attr_unbind);
446}
447#else
448static inline void add_bind_files(struct device_driver *drv) {}
449static inline void remove_bind_files(struct device_driver *drv) {}
450#endif
423 451
424/** 452/**
425 * bus_add_driver - Add a driver to the bus. 453 * bus_add_driver - Add a driver to the bus.
@@ -449,8 +477,7 @@ int bus_add_driver(struct device_driver * drv)
449 module_add_driver(drv->owner, drv); 477 module_add_driver(drv->owner, drv);
450 478
451 driver_add_attrs(bus, drv); 479 driver_add_attrs(bus, drv);
452 driver_create_file(drv, &driver_attr_unbind); 480 add_bind_files(drv);
453 driver_create_file(drv, &driver_attr_bind);
454 } 481 }
455 return error; 482 return error;
456} 483}
@@ -468,8 +495,7 @@ int bus_add_driver(struct device_driver * drv)
468void bus_remove_driver(struct device_driver * drv) 495void bus_remove_driver(struct device_driver * drv)
469{ 496{
470 if (drv->bus) { 497 if (drv->bus) {
471 driver_remove_file(drv, &driver_attr_bind); 498 remove_bind_files(drv);
472 driver_remove_file(drv, &driver_attr_unbind);
473 driver_remove_attrs(drv->bus, drv); 499 driver_remove_attrs(drv->bus, drv);
474 klist_remove(&drv->knode_bus); 500 klist_remove(&drv->knode_bus);
475 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); 501 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
@@ -484,8 +510,13 @@ void bus_remove_driver(struct device_driver * drv)
484/* Helper for bus_rescan_devices's iter */ 510/* Helper for bus_rescan_devices's iter */
485static int bus_rescan_devices_helper(struct device *dev, void *data) 511static int bus_rescan_devices_helper(struct device *dev, void *data)
486{ 512{
487 if (!dev->driver) 513 if (!dev->driver) {
514 if (dev->parent) /* Needed for USB */
515 down(&dev->parent->sem);
488 device_attach(dev); 516 device_attach(dev);
517 if (dev->parent)
518 up(&dev->parent->sem);
519 }
489 return 0; 520 return 0;
490} 521}
491 522
diff --git a/drivers/base/class.c b/drivers/base/class.c
index db65fd0babe..df7fdabd073 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -178,7 +178,7 @@ static void class_device_create_release(struct class_device *class_dev)
178} 178}
179 179
180/* needed to allow these devices to have parent class devices */ 180/* needed to allow these devices to have parent class devices */
181static int class_device_create_hotplug(struct class_device *class_dev, 181static int class_device_create_uevent(struct class_device *class_dev,
182 char **envp, int num_envp, 182 char **envp, int num_envp,
183 char *buffer, int buffer_size) 183 char *buffer, int buffer_size)
184{ 184{
@@ -331,7 +331,7 @@ static struct kobj_type ktype_class_device = {
331 .release = class_dev_release, 331 .release = class_dev_release,
332}; 332};
333 333
334static int class_hotplug_filter(struct kset *kset, struct kobject *kobj) 334static int class_uevent_filter(struct kset *kset, struct kobject *kobj)
335{ 335{
336 struct kobj_type *ktype = get_ktype(kobj); 336 struct kobj_type *ktype = get_ktype(kobj);
337 337
@@ -343,14 +343,14 @@ static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
343 return 0; 343 return 0;
344} 344}
345 345
346static const char *class_hotplug_name(struct kset *kset, struct kobject *kobj) 346static const char *class_uevent_name(struct kset *kset, struct kobject *kobj)
347{ 347{
348 struct class_device *class_dev = to_class_dev(kobj); 348 struct class_device *class_dev = to_class_dev(kobj);
349 349
350 return class_dev->class->name; 350 return class_dev->class->name;
351} 351}
352 352
353static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp, 353static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
354 int num_envp, char *buffer, int buffer_size) 354 int num_envp, char *buffer, int buffer_size)
355{ 355{
356 struct class_device *class_dev = to_class_dev(kobj); 356 struct class_device *class_dev = to_class_dev(kobj);
@@ -365,29 +365,29 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
365 struct device *dev = class_dev->dev; 365 struct device *dev = class_dev->dev;
366 char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); 366 char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
367 367
368 add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, 368 add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
369 &length, "PHYSDEVPATH=%s", path); 369 &length, "PHYSDEVPATH=%s", path);
370 kfree(path); 370 kfree(path);
371 371
372 if (dev->bus) 372 if (dev->bus)
373 add_hotplug_env_var(envp, num_envp, &i, 373 add_uevent_var(envp, num_envp, &i,
374 buffer, buffer_size, &length, 374 buffer, buffer_size, &length,
375 "PHYSDEVBUS=%s", dev->bus->name); 375 "PHYSDEVBUS=%s", dev->bus->name);
376 376
377 if (dev->driver) 377 if (dev->driver)
378 add_hotplug_env_var(envp, num_envp, &i, 378 add_uevent_var(envp, num_envp, &i,
379 buffer, buffer_size, &length, 379 buffer, buffer_size, &length,
380 "PHYSDEVDRIVER=%s", dev->driver->name); 380 "PHYSDEVDRIVER=%s", dev->driver->name);
381 } 381 }
382 382
383 if (MAJOR(class_dev->devt)) { 383 if (MAJOR(class_dev->devt)) {
384 add_hotplug_env_var(envp, num_envp, &i, 384 add_uevent_var(envp, num_envp, &i,
385 buffer, buffer_size, &length, 385 buffer, buffer_size, &length,
386 "MAJOR=%u", MAJOR(class_dev->devt)); 386 "MAJOR=%u", MAJOR(class_dev->devt));
387 387
388 add_hotplug_env_var(envp, num_envp, &i, 388 add_uevent_var(envp, num_envp, &i,
389 buffer, buffer_size, &length, 389 buffer, buffer_size, &length,
390 "MINOR=%u", MINOR(class_dev->devt)); 390 "MINOR=%u", MINOR(class_dev->devt));
391 } 391 }
392 392
393 /* terminate, set to next free slot, shrink available space */ 393 /* terminate, set to next free slot, shrink available space */
@@ -397,30 +397,30 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
397 buffer = &buffer[length]; 397 buffer = &buffer[length];
398 buffer_size -= length; 398 buffer_size -= length;
399 399
400 if (class_dev->hotplug) { 400 if (class_dev->uevent) {
401 /* have the class device specific function add its stuff */ 401 /* have the class device specific function add its stuff */
402 retval = class_dev->hotplug(class_dev, envp, num_envp, 402 retval = class_dev->uevent(class_dev, envp, num_envp,
403 buffer, buffer_size); 403 buffer, buffer_size);
404 if (retval) 404 if (retval)
405 pr_debug("class_dev->hotplug() returned %d\n", retval); 405 pr_debug("class_dev->uevent() returned %d\n", retval);
406 } else if (class_dev->class->hotplug) { 406 } else if (class_dev->class->uevent) {
407 /* have the class specific function add its stuff */ 407 /* have the class specific function add its stuff */
408 retval = class_dev->class->hotplug(class_dev, envp, num_envp, 408 retval = class_dev->class->uevent(class_dev, envp, num_envp,
409 buffer, buffer_size); 409 buffer, buffer_size);
410 if (retval) 410 if (retval)
411 pr_debug("class->hotplug() returned %d\n", retval); 411 pr_debug("class->uevent() returned %d\n", retval);
412 } 412 }
413 413
414 return retval; 414 return retval;
415} 415}
416 416
417static struct kset_hotplug_ops class_hotplug_ops = { 417static struct kset_uevent_ops class_uevent_ops = {
418 .filter = class_hotplug_filter, 418 .filter = class_uevent_filter,
419 .name = class_hotplug_name, 419 .name = class_uevent_name,
420 .hotplug = class_hotplug, 420 .uevent = class_uevent,
421}; 421};
422 422
423static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops); 423static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops);
424 424
425 425
426static int class_device_add_attrs(struct class_device * cd) 426static int class_device_add_attrs(struct class_device * cd)
@@ -464,7 +464,7 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
464static ssize_t store_uevent(struct class_device *class_dev, 464static ssize_t store_uevent(struct class_device *class_dev,
465 const char *buf, size_t count) 465 const char *buf, size_t count)
466{ 466{
467 kobject_hotplug(&class_dev->kobj, KOBJ_ADD); 467 kobject_uevent(&class_dev->kobj, KOBJ_ADD);
468 return count; 468 return count;
469} 469}
470 470
@@ -559,7 +559,7 @@ int class_device_add(struct class_device *class_dev)
559 class_name); 559 class_name);
560 } 560 }
561 561
562 kobject_hotplug(&class_dev->kobj, KOBJ_ADD); 562 kobject_uevent(&class_dev->kobj, KOBJ_ADD);
563 563
564 /* notify any interfaces this device is now here */ 564 /* notify any interfaces this device is now here */
565 if (parent_class) { 565 if (parent_class) {
@@ -632,7 +632,7 @@ struct class_device *class_device_create(struct class *cls,
632 class_dev->class = cls; 632 class_dev->class = cls;
633 class_dev->parent = parent; 633 class_dev->parent = parent;
634 class_dev->release = class_device_create_release; 634 class_dev->release = class_device_create_release;
635 class_dev->hotplug = class_device_create_hotplug; 635 class_dev->uevent = class_device_create_uevent;
636 636
637 va_start(args, fmt); 637 va_start(args, fmt);
638 vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args); 638 vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@@ -674,7 +674,7 @@ void class_device_del(struct class_device *class_dev)
674 class_device_remove_file(class_dev, class_dev->devt_attr); 674 class_device_remove_file(class_dev, class_dev->devt_attr);
675 class_device_remove_attrs(class_dev); 675 class_device_remove_attrs(class_dev);
676 676
677 kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE); 677 kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
678 kobject_del(&class_dev->kobj); 678 kobject_del(&class_dev->kobj);
679 679
680 class_device_put(parent_device); 680 class_device_put(parent_device);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 8615b42b517..fd8059920db 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -90,7 +90,7 @@ static struct kobj_type ktype_device = {
90}; 90};
91 91
92 92
93static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj) 93static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
94{ 94{
95 struct kobj_type *ktype = get_ktype(kobj); 95 struct kobj_type *ktype = get_ktype(kobj);
96 96
@@ -102,14 +102,14 @@ static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
102 return 0; 102 return 0;
103} 103}
104 104
105static const char *dev_hotplug_name(struct kset *kset, struct kobject *kobj) 105static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
106{ 106{
107 struct device *dev = to_dev(kobj); 107 struct device *dev = to_dev(kobj);
108 108
109 return dev->bus->name; 109 return dev->bus->name;
110} 110}
111 111
112static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp, 112static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
113 int num_envp, char *buffer, int buffer_size) 113 int num_envp, char *buffer, int buffer_size)
114{ 114{
115 struct device *dev = to_dev(kobj); 115 struct device *dev = to_dev(kobj);
@@ -119,15 +119,15 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
119 119
120 /* add bus name of physical device */ 120 /* add bus name of physical device */
121 if (dev->bus) 121 if (dev->bus)
122 add_hotplug_env_var(envp, num_envp, &i, 122 add_uevent_var(envp, num_envp, &i,
123 buffer, buffer_size, &length, 123 buffer, buffer_size, &length,
124 "PHYSDEVBUS=%s", dev->bus->name); 124 "PHYSDEVBUS=%s", dev->bus->name);
125 125
126 /* add driver name of physical device */ 126 /* add driver name of physical device */
127 if (dev->driver) 127 if (dev->driver)
128 add_hotplug_env_var(envp, num_envp, &i, 128 add_uevent_var(envp, num_envp, &i,
129 buffer, buffer_size, &length, 129 buffer, buffer_size, &length,
130 "PHYSDEVDRIVER=%s", dev->driver->name); 130 "PHYSDEVDRIVER=%s", dev->driver->name);
131 131
132 /* terminate, set to next free slot, shrink available space */ 132 /* terminate, set to next free slot, shrink available space */
133 envp[i] = NULL; 133 envp[i] = NULL;
@@ -136,11 +136,11 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
136 buffer = &buffer[length]; 136 buffer = &buffer[length];
137 buffer_size -= length; 137 buffer_size -= length;
138 138
139 if (dev->bus && dev->bus->hotplug) { 139 if (dev->bus && dev->bus->uevent) {
140 /* have the bus specific function add its stuff */ 140 /* have the bus specific function add its stuff */
141 retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size); 141 retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
142 if (retval) { 142 if (retval) {
143 pr_debug ("%s - hotplug() returned %d\n", 143 pr_debug ("%s - uevent() returned %d\n",
144 __FUNCTION__, retval); 144 __FUNCTION__, retval);
145 } 145 }
146 } 146 }
@@ -148,16 +148,16 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
148 return retval; 148 return retval;
149} 149}
150 150
151static struct kset_hotplug_ops device_hotplug_ops = { 151static struct kset_uevent_ops device_uevent_ops = {
152 .filter = dev_hotplug_filter, 152 .filter = dev_uevent_filter,
153 .name = dev_hotplug_name, 153 .name = dev_uevent_name,
154 .hotplug = dev_hotplug, 154 .uevent = dev_uevent,
155}; 155};
156 156
157static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, 157static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
158 const char *buf, size_t count) 158 const char *buf, size_t count)
159{ 159{
160 kobject_hotplug(&dev->kobj, KOBJ_ADD); 160 kobject_uevent(&dev->kobj, KOBJ_ADD);
161 return count; 161 return count;
162} 162}
163 163
@@ -165,7 +165,7 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
165 * device_subsys - structure to be registered with kobject core. 165 * device_subsys - structure to be registered with kobject core.
166 */ 166 */
167 167
168decl_subsys(devices, &ktype_device, &device_hotplug_ops); 168decl_subsys(devices, &ktype_device, &device_uevent_ops);
169 169
170 170
171/** 171/**
@@ -274,7 +274,7 @@ int device_add(struct device *dev)
274 dev->uevent_attr.store = store_uevent; 274 dev->uevent_attr.store = store_uevent;
275 device_create_file(dev, &dev->uevent_attr); 275 device_create_file(dev, &dev->uevent_attr);
276 276
277 kobject_hotplug(&dev->kobj, KOBJ_ADD); 277 kobject_uevent(&dev->kobj, KOBJ_ADD);
278 if ((error = device_pm_add(dev))) 278 if ((error = device_pm_add(dev)))
279 goto PMError; 279 goto PMError;
280 if ((error = bus_add_device(dev))) 280 if ((error = bus_add_device(dev)))
@@ -291,7 +291,7 @@ int device_add(struct device *dev)
291 BusError: 291 BusError:
292 device_pm_remove(dev); 292 device_pm_remove(dev);
293 PMError: 293 PMError:
294 kobject_hotplug(&dev->kobj, KOBJ_REMOVE); 294 kobject_uevent(&dev->kobj, KOBJ_REMOVE);
295 kobject_del(&dev->kobj); 295 kobject_del(&dev->kobj);
296 Error: 296 Error:
297 if (parent) 297 if (parent)
@@ -374,7 +374,7 @@ void device_del(struct device * dev)
374 platform_notify_remove(dev); 374 platform_notify_remove(dev);
375 bus_remove_device(dev); 375 bus_remove_device(dev);
376 device_pm_remove(dev); 376 device_pm_remove(dev);
377 kobject_hotplug(&dev->kobj, KOBJ_REMOVE); 377 kobject_uevent(&dev->kobj, KOBJ_REMOVE);
378 kobject_del(&dev->kobj); 378 kobject_del(&dev->kobj);
379 if (parent) 379 if (parent)
380 put_device(parent); 380 put_device(parent);
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index a95844790f7..281d26784d2 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -41,14 +41,14 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
41 case '0': 41 case '0':
42 ret = cpu_down(cpu->sysdev.id); 42 ret = cpu_down(cpu->sysdev.id);
43 if (!ret) 43 if (!ret)
44 kobject_hotplug(&dev->kobj, KOBJ_OFFLINE); 44 kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
45 break; 45 break;
46 case '1': 46 case '1':
47 ret = smp_prepare_cpu(cpu->sysdev.id); 47 ret = smp_prepare_cpu(cpu->sysdev.id);
48 if (!ret) 48 if (!ret)
49 ret = cpu_up(cpu->sysdev.id); 49 ret = cpu_up(cpu->sysdev.id);
50 if (!ret) 50 if (!ret)
51 kobject_hotplug(&dev->kobj, KOBJ_ONLINE); 51 kobject_uevent(&dev->kobj, KOBJ_ONLINE);
52 break; 52 break;
53 default: 53 default:
54 ret = -EINVAL; 54 ret = -EINVAL;
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 3b419c9a1e7..2b905016664 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -65,7 +65,8 @@ void device_bind_driver(struct device * dev)
65 * This function returns 1 if a match is found, an error if one 65 * This function returns 1 if a match is found, an error if one
66 * occurs (that is not -ENODEV or -ENXIO), and 0 otherwise. 66 * occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
67 * 67 *
68 * This function must be called with @dev->sem held. 68 * This function must be called with @dev->sem held. When called
69 * for a USB interface, @dev->parent->sem must be held as well.
69 */ 70 */
70int driver_probe_device(struct device_driver * drv, struct device * dev) 71int driver_probe_device(struct device_driver * drv, struct device * dev)
71{ 72{
@@ -123,6 +124,8 @@ static int __device_attach(struct device_driver * drv, void * data)
123 * 124 *
124 * Returns 1 if the device was bound to a driver; 125 * Returns 1 if the device was bound to a driver;
125 * 0 if no matching device was found; error code otherwise. 126 * 0 if no matching device was found; error code otherwise.
127 *
128 * When called for a USB interface, @dev->parent->sem must be held.
126 */ 129 */
127int device_attach(struct device * dev) 130int device_attach(struct device * dev)
128{ 131{
@@ -152,10 +155,14 @@ static int __driver_attach(struct device * dev, void * data)
152 * is an error. 155 * is an error.
153 */ 156 */
154 157
158 if (dev->parent) /* Needed for USB */
159 down(&dev->parent->sem);
155 down(&dev->sem); 160 down(&dev->sem);
156 if (!dev->driver) 161 if (!dev->driver)
157 driver_probe_device(drv, dev); 162 driver_probe_device(drv, dev);
158 up(&dev->sem); 163 up(&dev->sem);
164 if (dev->parent)
165 up(&dev->parent->sem);
159 166
160 return 0; 167 return 0;
161} 168}
@@ -181,6 +188,8 @@ void driver_attach(struct device_driver * drv)
181 * Manually detach device from driver. 188 * Manually detach device from driver.
182 * 189 *
183 * __device_release_driver() must be called with @dev->sem held. 190 * __device_release_driver() must be called with @dev->sem held.
191 * When called for a USB interface, @dev->parent->sem must be held
192 * as well.
184 */ 193 */
185 194
186static void __device_release_driver(struct device * dev) 195static void __device_release_driver(struct device * dev)
@@ -233,10 +242,14 @@ void driver_detach(struct device_driver * drv)
233 get_device(dev); 242 get_device(dev);
234 spin_unlock(&drv->klist_devices.k_lock); 243 spin_unlock(&drv->klist_devices.k_lock);
235 244
245 if (dev->parent) /* Needed for USB */
246 down(&dev->parent->sem);
236 down(&dev->sem); 247 down(&dev->sem);
237 if (dev->driver == drv) 248 if (dev->driver == drv)
238 __device_release_driver(dev); 249 __device_release_driver(dev);
239 up(&dev->sem); 250 up(&dev->sem);
251 if (dev->parent)
252 up(&dev->parent->sem);
240 put_device(dev); 253 put_device(dev);
241 } 254 }
242} 255}
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 59dacb6552c..5b3d5e9ddcb 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -85,17 +85,17 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count)
85static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); 85static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
86 86
87static void fw_class_dev_release(struct class_device *class_dev); 87static void fw_class_dev_release(struct class_device *class_dev);
88int firmware_class_hotplug(struct class_device *dev, char **envp, 88int firmware_class_uevent(struct class_device *dev, char **envp,
89 int num_envp, char *buffer, int buffer_size); 89 int num_envp, char *buffer, int buffer_size);
90 90
91static struct class firmware_class = { 91static struct class firmware_class = {
92 .name = "firmware", 92 .name = "firmware",
93 .hotplug = firmware_class_hotplug, 93 .uevent = firmware_class_uevent,
94 .release = fw_class_dev_release, 94 .release = fw_class_dev_release,
95}; 95};
96 96
97int 97int
98firmware_class_hotplug(struct class_device *class_dev, char **envp, 98firmware_class_uevent(struct class_device *class_dev, char **envp,
99 int num_envp, char *buffer, int buffer_size) 99 int num_envp, char *buffer, int buffer_size)
100{ 100{
101 struct firmware_priv *fw_priv = class_get_devdata(class_dev); 101 struct firmware_priv *fw_priv = class_get_devdata(class_dev);
@@ -104,13 +104,12 @@ firmware_class_hotplug(struct class_device *class_dev, char **envp,
104 if (!test_bit(FW_STATUS_READY, &fw_priv->status)) 104 if (!test_bit(FW_STATUS_READY, &fw_priv->status))
105 return -ENODEV; 105 return -ENODEV;
106 106
107 if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len, 107 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
108 "FIRMWARE=%s", fw_priv->fw_id)) 108 "FIRMWARE=%s", fw_priv->fw_id))
109 return -ENOMEM; 109 return -ENOMEM;
110 if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len, 110 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
111 "TIMEOUT=%i", loading_timeout)) 111 "TIMEOUT=%i", loading_timeout))
112 return -ENOMEM; 112 return -ENOMEM;
113
114 envp[i] = NULL; 113 envp[i] = NULL;
115 114
116 return 0; 115 return 0;
@@ -352,7 +351,7 @@ error_kfree:
352 351
353static int 352static int
354fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p, 353fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
355 const char *fw_name, struct device *device, int hotplug) 354 const char *fw_name, struct device *device, int uevent)
356{ 355{
357 struct class_device *class_dev; 356 struct class_device *class_dev;
358 struct firmware_priv *fw_priv; 357 struct firmware_priv *fw_priv;
@@ -384,7 +383,7 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
384 goto error_unreg; 383 goto error_unreg;
385 } 384 }
386 385
387 if (hotplug) 386 if (uevent)
388 set_bit(FW_STATUS_READY, &fw_priv->status); 387 set_bit(FW_STATUS_READY, &fw_priv->status);
389 else 388 else
390 set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status); 389 set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status);
@@ -399,7 +398,7 @@ out:
399 398
400static int 399static int
401_request_firmware(const struct firmware **firmware_p, const char *name, 400_request_firmware(const struct firmware **firmware_p, const char *name,
402 struct device *device, int hotplug) 401 struct device *device, int uevent)
403{ 402{
404 struct class_device *class_dev; 403 struct class_device *class_dev;
405 struct firmware_priv *fw_priv; 404 struct firmware_priv *fw_priv;
@@ -418,19 +417,19 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
418 } 417 }
419 418
420 retval = fw_setup_class_device(firmware, &class_dev, name, device, 419 retval = fw_setup_class_device(firmware, &class_dev, name, device,
421 hotplug); 420 uevent);
422 if (retval) 421 if (retval)
423 goto error_kfree_fw; 422 goto error_kfree_fw;
424 423
425 fw_priv = class_get_devdata(class_dev); 424 fw_priv = class_get_devdata(class_dev);
426 425
427 if (hotplug) { 426 if (uevent) {
428 if (loading_timeout > 0) { 427 if (loading_timeout > 0) {
429 fw_priv->timeout.expires = jiffies + loading_timeout * HZ; 428 fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
430 add_timer(&fw_priv->timeout); 429 add_timer(&fw_priv->timeout);
431 } 430 }
432 431
433 kobject_hotplug(&class_dev->kobj, KOBJ_ADD); 432 kobject_uevent(&class_dev->kobj, KOBJ_ADD);
434 wait_for_completion(&fw_priv->completion); 433 wait_for_completion(&fw_priv->completion);
435 set_bit(FW_STATUS_DONE, &fw_priv->status); 434 set_bit(FW_STATUS_DONE, &fw_priv->status);
436 del_timer_sync(&fw_priv->timeout); 435 del_timer_sync(&fw_priv->timeout);
@@ -456,7 +455,7 @@ out:
456} 455}
457 456
458/** 457/**
459 * request_firmware: - request firmware to hotplug and wait for it 458 * request_firmware: - send firmware request and wait for it
460 * @firmware_p: pointer to firmware image 459 * @firmware_p: pointer to firmware image
461 * @name: name of firmware file 460 * @name: name of firmware file
462 * @device: device for which firmware is being loaded 461 * @device: device for which firmware is being loaded
@@ -466,7 +465,7 @@ out:
466 * 465 *
467 * Should be called from user context where sleeping is allowed. 466 * Should be called from user context where sleeping is allowed.
468 * 467 *
469 * @name will be used as $FIRMWARE in the hotplug environment and 468 * @name will be used as $FIRMWARE in the uevent environment and
470 * should be distinctive enough not to be confused with any other 469 * should be distinctive enough not to be confused with any other
471 * firmware image for this or any other device. 470 * firmware image for this or any other device.
472 **/ 471 **/
@@ -474,8 +473,8 @@ int
474request_firmware(const struct firmware **firmware_p, const char *name, 473request_firmware(const struct firmware **firmware_p, const char *name,
475 struct device *device) 474 struct device *device)
476{ 475{
477 int hotplug = 1; 476 int uevent = 1;
478 return _request_firmware(firmware_p, name, device, hotplug); 477 return _request_firmware(firmware_p, name, device, uevent);
479} 478}
480 479
481/** 480/**
@@ -518,7 +517,7 @@ struct firmware_work {
518 struct device *device; 517 struct device *device;
519 void *context; 518 void *context;
520 void (*cont)(const struct firmware *fw, void *context); 519 void (*cont)(const struct firmware *fw, void *context);
521 int hotplug; 520 int uevent;
522}; 521};
523 522
524static int 523static int
@@ -533,7 +532,7 @@ request_firmware_work_func(void *arg)
533 } 532 }
534 daemonize("%s/%s", "firmware", fw_work->name); 533 daemonize("%s/%s", "firmware", fw_work->name);
535 ret = _request_firmware(&fw, fw_work->name, fw_work->device, 534 ret = _request_firmware(&fw, fw_work->name, fw_work->device,
536 fw_work->hotplug); 535 fw_work->uevent);
537 if (ret < 0) 536 if (ret < 0)
538 fw_work->cont(NULL, fw_work->context); 537 fw_work->cont(NULL, fw_work->context);
539 else { 538 else {
@@ -548,7 +547,7 @@ request_firmware_work_func(void *arg)
548/** 547/**
549 * request_firmware_nowait: asynchronous version of request_firmware 548 * request_firmware_nowait: asynchronous version of request_firmware
550 * @module: module requesting the firmware 549 * @module: module requesting the firmware
551 * @hotplug: invokes hotplug event to copy the firmware image if this flag 550 * @uevent: sends uevent to copy the firmware image if this flag
552 * is non-zero else the firmware copy must be done manually. 551 * is non-zero else the firmware copy must be done manually.
553 * @name: name of firmware file 552 * @name: name of firmware file
554 * @device: device for which firmware is being loaded 553 * @device: device for which firmware is being loaded
@@ -562,7 +561,7 @@ request_firmware_work_func(void *arg)
562 **/ 561 **/
563int 562int
564request_firmware_nowait( 563request_firmware_nowait(
565 struct module *module, int hotplug, 564 struct module *module, int uevent,
566 const char *name, struct device *device, void *context, 565 const char *name, struct device *device, void *context,
567 void (*cont)(const struct firmware *fw, void *context)) 566 void (*cont)(const struct firmware *fw, void *context))
568{ 567{
@@ -583,7 +582,7 @@ request_firmware_nowait(
583 .device = device, 582 .device = device,
584 .context = context, 583 .context = context,
585 .cont = cont, 584 .cont = cont,
586 .hotplug = hotplug, 585 .uevent = uevent,
587 }; 586 };
588 587
589 ret = kernel_thread(request_firmware_work_func, fw_work, 588 ret = kernel_thread(request_firmware_work_func, fw_work,
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index bc3ca6a656b..7e1d077874d 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -29,12 +29,12 @@ static struct sysdev_class memory_sysdev_class = {
29 set_kset_name(MEMORY_CLASS_NAME), 29 set_kset_name(MEMORY_CLASS_NAME),
30}; 30};
31 31
32static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj) 32static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj)
33{ 33{
34 return MEMORY_CLASS_NAME; 34 return MEMORY_CLASS_NAME;
35} 35}
36 36
37static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp, 37static int memory_uevent(struct kset *kset, struct kobject *kobj, char **envp,
38 int num_envp, char *buffer, int buffer_size) 38 int num_envp, char *buffer, int buffer_size)
39{ 39{
40 int retval = 0; 40 int retval = 0;
@@ -42,9 +42,9 @@ static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
42 return retval; 42 return retval;
43} 43}
44 44
45static struct kset_hotplug_ops memory_hotplug_ops = { 45static struct kset_uevent_ops memory_uevent_ops = {
46 .name = memory_hotplug_name, 46 .name = memory_uevent_name,
47 .hotplug = memory_hotplug, 47 .uevent = memory_uevent,
48}; 48};
49 49
50static struct notifier_block *memory_chain; 50static struct notifier_block *memory_chain;
@@ -431,7 +431,7 @@ int __init memory_dev_init(void)
431 unsigned int i; 431 unsigned int i;
432 int ret; 432 int ret;
433 433
434 memory_sysdev_class.kset.hotplug_ops = &memory_hotplug_ops; 434 memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops;
435 ret = sysdev_class_register(&memory_sysdev_class); 435 ret = sysdev_class_register(&memory_sysdev_class);
436 436
437 /* 437 /*
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 8827dafba94..0f81731bdfa 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -25,6 +25,7 @@
25struct device platform_bus = { 25struct device platform_bus = {
26 .bus_id = "platform", 26 .bus_id = "platform",
27}; 27};
28EXPORT_SYMBOL_GPL(platform_bus);
28 29
29/** 30/**
30 * platform_get_resource - get a resource for a device 31 * platform_get_resource - get a resource for a device
@@ -49,6 +50,7 @@ platform_get_resource(struct platform_device *dev, unsigned int type,
49 } 50 }
50 return NULL; 51 return NULL;
51} 52}
53EXPORT_SYMBOL_GPL(platform_get_resource);
52 54
53/** 55/**
54 * platform_get_irq - get an IRQ for a device 56 * platform_get_irq - get an IRQ for a device
@@ -61,6 +63,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
61 63
62 return r ? r->start : 0; 64 return r ? r->start : 0;
63} 65}
66EXPORT_SYMBOL_GPL(platform_get_irq);
64 67
65/** 68/**
66 * platform_get_resource_byname - get a resource for a device by name 69 * platform_get_resource_byname - get a resource for a device by name
@@ -84,6 +87,7 @@ platform_get_resource_byname(struct platform_device *dev, unsigned int type,
84 } 87 }
85 return NULL; 88 return NULL;
86} 89}
90EXPORT_SYMBOL_GPL(platform_get_resource_byname);
87 91
88/** 92/**
89 * platform_get_irq - get an IRQ for a device 93 * platform_get_irq - get an IRQ for a device
@@ -96,6 +100,7 @@ int platform_get_irq_byname(struct platform_device *dev, char *name)
96 100
97 return r ? r->start : 0; 101 return r ? r->start : 0;
98} 102}
103EXPORT_SYMBOL_GPL(platform_get_irq_byname);
99 104
100/** 105/**
101 * platform_add_devices - add a numbers of platform devices 106 * platform_add_devices - add a numbers of platform devices
@@ -117,6 +122,7 @@ int platform_add_devices(struct platform_device **devs, int num)
117 122
118 return ret; 123 return ret;
119} 124}
125EXPORT_SYMBOL_GPL(platform_add_devices);
120 126
121struct platform_object { 127struct platform_object {
122 struct platform_device pdev; 128 struct platform_device pdev;
@@ -168,7 +174,7 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id)
168 pa->pdev.dev.release = platform_device_release; 174 pa->pdev.dev.release = platform_device_release;
169 } 175 }
170 176
171 return pa ? &pa->pdev : NULL; 177 return pa ? &pa->pdev : NULL;
172} 178}
173EXPORT_SYMBOL_GPL(platform_device_alloc); 179EXPORT_SYMBOL_GPL(platform_device_alloc);
174 180
@@ -257,7 +263,7 @@ int platform_device_add(struct platform_device *pdev)
257 p = &ioport_resource; 263 p = &ioport_resource;
258 } 264 }
259 265
260 if (p && request_resource(p, r)) { 266 if (p && insert_resource(p, r)) {
261 printk(KERN_ERR 267 printk(KERN_ERR
262 "%s: failed to claim resource %d\n", 268 "%s: failed to claim resource %d\n",
263 pdev->dev.bus_id, i); 269 pdev->dev.bus_id, i);
@@ -282,24 +288,13 @@ int platform_device_add(struct platform_device *pdev)
282EXPORT_SYMBOL_GPL(platform_device_add); 288EXPORT_SYMBOL_GPL(platform_device_add);
283 289
284/** 290/**
285 * platform_device_register - add a platform-level device 291 * platform_device_del - remove a platform-level device
286 * @pdev: platform device we're adding
287 *
288 */
289int platform_device_register(struct platform_device * pdev)
290{
291 device_initialize(&pdev->dev);
292 return platform_device_add(pdev);
293}
294
295/**
296 * platform_device_unregister - remove a platform-level device
297 * @pdev: platform device we're removing 292 * @pdev: platform device we're removing
298 * 293 *
299 * Note that this function will also release all memory- and port-based 294 * Note that this function will also release all memory- and port-based
300 * resources owned by the device (@dev->resource). 295 * resources owned by the device (@dev->resource).
301 */ 296 */
302void platform_device_unregister(struct platform_device * pdev) 297void platform_device_del(struct platform_device *pdev)
303{ 298{
304 int i; 299 int i;
305 300
@@ -310,9 +305,37 @@ void platform_device_unregister(struct platform_device * pdev)
310 release_resource(r); 305 release_resource(r);
311 } 306 }
312 307
313 device_unregister(&pdev->dev); 308 device_del(&pdev->dev);
314 } 309 }
315} 310}
311EXPORT_SYMBOL_GPL(platform_device_del);
312
313/**
314 * platform_device_register - add a platform-level device
315 * @pdev: platform device we're adding
316 *
317 */
318int platform_device_register(struct platform_device * pdev)
319{
320 device_initialize(&pdev->dev);
321 return platform_device_add(pdev);
322}
323EXPORT_SYMBOL_GPL(platform_device_register);
324
325/**
326 * platform_device_unregister - unregister a platform-level device
327 * @pdev: platform device we're unregistering
328 *
329 * Unregistration is done in 2 steps. Fisrt we release all resources
330 * and remove it from the sybsystem, then we drop reference count by
331 * calling platform_device_put().
332 */
333void platform_device_unregister(struct platform_device * pdev)
334{
335 platform_device_del(pdev);
336 platform_device_put(pdev);
337}
338EXPORT_SYMBOL_GPL(platform_device_unregister);
316 339
317/** 340/**
318 * platform_device_register_simple 341 * platform_device_register_simple
@@ -355,6 +378,7 @@ error:
355 platform_device_put(pdev); 378 platform_device_put(pdev);
356 return ERR_PTR(retval); 379 return ERR_PTR(retval);
357} 380}
381EXPORT_SYMBOL_GPL(platform_device_register_simple);
358 382
359static int platform_drv_probe(struct device *_dev) 383static int platform_drv_probe(struct device *_dev)
360{ 384{
@@ -476,6 +500,7 @@ struct bus_type platform_bus_type = {
476 .suspend = platform_suspend, 500 .suspend = platform_suspend,
477 .resume = platform_resume, 501 .resume = platform_resume,
478}; 502};
503EXPORT_SYMBOL_GPL(platform_bus_type);
479 504
480int __init platform_bus_init(void) 505int __init platform_bus_init(void)
481{ 506{
@@ -504,14 +529,3 @@ u64 dma_get_required_mask(struct device *dev)
504} 529}
505EXPORT_SYMBOL_GPL(dma_get_required_mask); 530EXPORT_SYMBOL_GPL(dma_get_required_mask);
506#endif 531#endif
507
508EXPORT_SYMBOL_GPL(platform_bus);
509EXPORT_SYMBOL_GPL(platform_bus_type);
510EXPORT_SYMBOL_GPL(platform_add_devices);
511EXPORT_SYMBOL_GPL(platform_device_register);
512EXPORT_SYMBOL_GPL(platform_device_register_simple);
513EXPORT_SYMBOL_GPL(platform_device_unregister);
514EXPORT_SYMBOL_GPL(platform_get_irq);
515EXPORT_SYMBOL_GPL(platform_get_resource);
516EXPORT_SYMBOL_GPL(platform_get_irq_byname);
517EXPORT_SYMBOL_GPL(platform_get_resource_byname);
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index adbc3148c03..4bafef83e79 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -64,6 +64,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
64} 64}
65 65
66 66
67#if 0
67/** 68/**
68 * dpm_set_power_state - Update power_state field. 69 * dpm_set_power_state - Update power_state field.
69 * @dev: Device. 70 * @dev: Device.
@@ -80,3 +81,4 @@ void dpm_set_power_state(struct device * dev, pm_message_t state)
80 dev->power.power_state = state; 81 dev->power.power_state = state;
81 up(&dpm_sem); 82 up(&dpm_sem);
82} 83}
84#endif /* 0 */
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index b4d7a3efb90..70aeb3a6012 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3509,6 +3509,7 @@ static int __init ide_cdrom_init(void)
3509 return driver_register(&ide_cdrom_driver.gen_driver); 3509 return driver_register(&ide_cdrom_driver.gen_driver);
3510} 3510}
3511 3511
3512MODULE_ALIAS("ide:*m-cdrom*");
3512module_init(ide_cdrom_init); 3513module_init(ide_cdrom_init);
3513module_exit(ide_cdrom_exit); 3514module_exit(ide_cdrom_exit);
3514MODULE_LICENSE("GPL"); 3515MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 449522f0540..4e5767968d7 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1271,6 +1271,7 @@ static int __init idedisk_init(void)
1271 return driver_register(&idedisk_driver.gen_driver); 1271 return driver_register(&idedisk_driver.gen_driver);
1272} 1272}
1273 1273
1274MODULE_ALIAS("ide:*m-disk*");
1274module_init(idedisk_init); 1275module_init(idedisk_init);
1275module_exit(idedisk_exit); 1276module_exit(idedisk_exit);
1276MODULE_LICENSE("GPL"); 1277MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 9e293c8063d..fba3fffc2d6 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2197,6 +2197,7 @@ static int __init idefloppy_init(void)
2197 return driver_register(&idefloppy_driver.gen_driver); 2197 return driver_register(&idefloppy_driver.gen_driver);
2198} 2198}
2199 2199
2200MODULE_ALIAS("ide:*m-floppy*");
2200module_init(idefloppy_init); 2201module_init(idefloppy_init);
2201module_exit(idefloppy_exit); 2202module_exit(idefloppy_exit);
2202MODULE_LICENSE("GPL"); 2203MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 7d7944ed415..fab9b2b0250 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -4947,6 +4947,7 @@ out:
4947 return error; 4947 return error;
4948} 4948}
4949 4949
4950MODULE_ALIAS("ide:*m-tape*");
4950module_init(idetape_init); 4951module_init(idetape_init);
4951module_exit(idetape_exit); 4952module_exit(idetape_exit);
4952MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR); 4953MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR);
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 8af179b531c..4b524f6b3ec 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1904,9 +1904,69 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv)
1904 return 1; 1904 return 1;
1905} 1905}
1906 1906
1907static char *media_string(ide_drive_t *drive)
1908{
1909 switch (drive->media) {
1910 case ide_disk:
1911 return "disk";
1912 case ide_cdrom:
1913 return "cdrom";
1914 case ide_tape:
1915 return "tape";
1916 case ide_floppy:
1917 return "floppy";
1918 default:
1919 return "UNKNOWN";
1920 }
1921}
1922
1923static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)
1924{
1925 ide_drive_t *drive = to_ide_device(dev);
1926 return sprintf(buf, "%s\n", media_string(drive));
1927}
1928
1929static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)
1930{
1931 ide_drive_t *drive = to_ide_device(dev);
1932 return sprintf(buf, "%s\n", drive->name);
1933}
1934
1935static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
1936{
1937 ide_drive_t *drive = to_ide_device(dev);
1938 return sprintf(buf, "ide:m-%s\n", media_string(drive));
1939}
1940
1941static struct device_attribute ide_dev_attrs[] = {
1942 __ATTR_RO(media),
1943 __ATTR_RO(drivename),
1944 __ATTR_RO(modalias),
1945 __ATTR_NULL
1946};
1947
1948static int ide_uevent(struct device *dev, char **envp, int num_envp,
1949 char *buffer, int buffer_size)
1950{
1951 ide_drive_t *drive = to_ide_device(dev);
1952 int i = 0;
1953 int length = 0;
1954
1955 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
1956 "MEDIA=%s", media_string(drive));
1957 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
1958 "DRIVENAME=%s", drive->name);
1959 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
1960 "MODALIAS=ide:m-%s", media_string(drive));
1961 envp[i] = NULL;
1962 return 0;
1963}
1964
1907struct bus_type ide_bus_type = { 1965struct bus_type ide_bus_type = {
1908 .name = "ide", 1966 .name = "ide",
1909 .match = ide_bus_match, 1967 .match = ide_bus_match,
1968 .uevent = ide_uevent,
1969 .dev_attrs = ide_dev_attrs,
1910 .suspend = generic_ide_suspend, 1970 .suspend = generic_ide_suspend,
1911 .resume = generic_ide_resume, 1971 .resume = generic_ide_resume,
1912}; 1972};
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 0ea37b1bccb..f2453668acf 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -121,8 +121,8 @@ struct host_info {
121}; 121};
122 122
123static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); 123static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
124static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp, 124static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
125 char *buffer, int buffer_size); 125 char *buffer, int buffer_size);
126static void nodemgr_resume_ne(struct node_entry *ne); 126static void nodemgr_resume_ne(struct node_entry *ne);
127static void nodemgr_remove_ne(struct node_entry *ne); 127static void nodemgr_remove_ne(struct node_entry *ne);
128static struct node_entry *find_entry_by_guid(u64 guid); 128static struct node_entry *find_entry_by_guid(u64 guid);
@@ -162,7 +162,7 @@ static void ud_cls_release(struct class_device *class_dev)
162static struct class nodemgr_ud_class = { 162static struct class nodemgr_ud_class = {
163 .name = "ieee1394", 163 .name = "ieee1394",
164 .release = ud_cls_release, 164 .release = ud_cls_release,
165 .hotplug = nodemgr_hotplug, 165 .uevent = nodemgr_uevent,
166}; 166};
167 167
168static struct hpsb_highlevel nodemgr_highlevel; 168static struct hpsb_highlevel nodemgr_highlevel;
@@ -966,7 +966,7 @@ static struct unit_directory *nodemgr_process_unit_directory
966 if (ud_child == NULL) 966 if (ud_child == NULL)
967 break; 967 break;
968 968
969 /* inherit unspecified values so hotplug picks it up */ 969 /* inherit unspecified values, the driver core picks it up */
970 if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) && 970 if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) &&
971 !(ud_child->flags & UNIT_DIRECTORY_MODEL_ID)) 971 !(ud_child->flags & UNIT_DIRECTORY_MODEL_ID))
972 { 972 {
@@ -1062,8 +1062,8 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
1062 1062
1063#ifdef CONFIG_HOTPLUG 1063#ifdef CONFIG_HOTPLUG
1064 1064
1065static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp, 1065static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
1066 char *buffer, int buffer_size) 1066 char *buffer, int buffer_size)
1067{ 1067{
1068 struct unit_directory *ud; 1068 struct unit_directory *ud;
1069 int i = 0; 1069 int i = 0;
@@ -1112,8 +1112,8 @@ do { \
1112 1112
1113#else 1113#else
1114 1114
1115static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp, 1115static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
1116 char *buffer, int buffer_size) 1116 char *buffer, int buffer_size)
1117{ 1117{
1118 return -ENODEV; 1118 return -ENODEV;
1119} 1119}
@@ -1618,8 +1618,8 @@ static int nodemgr_host_thread(void *__hi)
1618 1618
1619 /* Scan our nodes to get the bus options and create node 1619 /* Scan our nodes to get the bus options and create node
1620 * entries. This does not do the sysfs stuff, since that 1620 * entries. This does not do the sysfs stuff, since that
1621 * would trigger hotplug callbacks and such, which is a 1621 * would trigger uevents and such, which is a bad idea at
1622 * bad idea at this point. */ 1622 * this point. */
1623 nodemgr_node_scan(hi, generation); 1623 nodemgr_node_scan(hi, generation);
1624 1624
1625 /* This actually does the full probe, with sysfs 1625 /* This actually does the full probe, with sysfs
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 08648b1a387..1f1743c5c9a 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -434,24 +434,24 @@ static void ib_device_release(struct class_device *cdev)
434 kfree(dev); 434 kfree(dev);
435} 435}
436 436
437static int ib_device_hotplug(struct class_device *cdev, char **envp, 437static int ib_device_uevent(struct class_device *cdev, char **envp,
438 int num_envp, char *buf, int size) 438 int num_envp, char *buf, int size)
439{ 439{
440 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); 440 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
441 int i = 0, len = 0; 441 int i = 0, len = 0;
442 442
443 if (add_hotplug_env_var(envp, num_envp, &i, buf, size, &len, 443 if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
444 "NAME=%s", dev->name)) 444 "NAME=%s", dev->name))
445 return -ENOMEM; 445 return -ENOMEM;
446 446
447 /* 447 /*
448 * It might be nice to pass the node GUID to hotplug, but 448 * It might be nice to pass the node GUID with the event, but
449 * right now the only way to get it is to query the device 449 * right now the only way to get it is to query the device
450 * provider, and this can crash during device removal because 450 * provider, and this can crash during device removal because
451 * we are will be running after driver removal has started. 451 * we are will be running after driver removal has started.
452 * We could add a node_guid field to struct ib_device, or we 452 * We could add a node_guid field to struct ib_device, or we
453 * could just let the hotplug script read the node GUID from 453 * could just let userspace read the node GUID from sysfs when
454 * sysfs when devices are added. 454 * devices are added.
455 */ 455 */
456 456
457 envp[i] = NULL; 457 envp[i] = NULL;
@@ -653,7 +653,7 @@ static struct class_device_attribute *ib_class_attributes[] = {
653static struct class ib_class = { 653static struct class ib_class = {
654 .name = "infiniband", 654 .name = "infiniband",
655 .release = ib_device_release, 655 .release = ib_device_release,
656 .hotplug = ib_device_hotplug, 656 .uevent = ib_device_uevent,
657}; 657};
658 658
659int ib_device_register_sysfs(struct ib_device *device) 659int ib_device_register_sysfs(struct ib_device *device)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index bdd2a7fc268..ef5824c8846 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -18,7 +18,6 @@
18#include <linux/random.h> 18#include <linux/random.h>
19#include <linux/major.h> 19#include <linux/major.h>
20#include <linux/proc_fs.h> 20#include <linux/proc_fs.h>
21#include <linux/kobject_uevent.h>
22#include <linux/interrupt.h> 21#include <linux/interrupt.h>
23#include <linux/poll.h> 22#include <linux/poll.h>
24#include <linux/device.h> 23#include <linux/device.h>
@@ -529,10 +528,49 @@ INPUT_DEV_STRING_ATTR_SHOW(name);
529INPUT_DEV_STRING_ATTR_SHOW(phys); 528INPUT_DEV_STRING_ATTR_SHOW(phys);
530INPUT_DEV_STRING_ATTR_SHOW(uniq); 529INPUT_DEV_STRING_ATTR_SHOW(uniq);
531 530
531static int print_modalias_bits(char *buf, char prefix, unsigned long *arr,
532 unsigned int min, unsigned int max)
533{
534 int len, i;
535
536 len = sprintf(buf, "%c", prefix);
537 for (i = min; i < max; i++)
538 if (arr[LONG(i)] & BIT(i))
539 len += sprintf(buf+len, "%X,", i);
540 return len;
541}
542
543static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
544{
545 struct input_dev *id = to_input_dev(dev);
546 ssize_t len = 0;
547
548 len += sprintf(buf+len, "input:b%04Xv%04Xp%04Xe%04X-",
549 id->id.bustype,
550 id->id.vendor,
551 id->id.product,
552 id->id.version);
553
554 len += print_modalias_bits(buf+len, 'e', id->evbit, 0, EV_MAX);
555 len += print_modalias_bits(buf+len, 'k', id->keybit,
556 KEY_MIN_INTERESTING, KEY_MAX);
557 len += print_modalias_bits(buf+len, 'r', id->relbit, 0, REL_MAX);
558 len += print_modalias_bits(buf+len, 'a', id->absbit, 0, ABS_MAX);
559 len += print_modalias_bits(buf+len, 'm', id->mscbit, 0, MSC_MAX);
560 len += print_modalias_bits(buf+len, 'l', id->ledbit, 0, LED_MAX);
561 len += print_modalias_bits(buf+len, 's', id->sndbit, 0, SND_MAX);
562 len += print_modalias_bits(buf+len, 'f', id->ffbit, 0, FF_MAX);
563 len += print_modalias_bits(buf+len, 'w', id->swbit, 0, SW_MAX);
564 len += sprintf(buf+len, "\n");
565 return len;
566}
567static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
568
532static struct attribute *input_dev_attrs[] = { 569static struct attribute *input_dev_attrs[] = {
533 &class_device_attr_name.attr, 570 &class_device_attr_name.attr,
534 &class_device_attr_phys.attr, 571 &class_device_attr_phys.attr,
535 &class_device_attr_uniq.attr, 572 &class_device_attr_uniq.attr,
573 &class_device_attr_modalias.attr,
536 NULL 574 NULL
537}; 575};
538 576
@@ -611,10 +649,10 @@ static void input_dev_release(struct class_device *class_dev)
611} 649}
612 650
613/* 651/*
614 * Input hotplugging interface - loading event handlers based on 652 * Input uevent interface - loading event handlers based on
615 * device bitfields. 653 * device bitfields.
616 */ 654 */
617static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index, 655static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
618 char *buffer, int buffer_size, int *cur_len, 656 char *buffer, int buffer_size, int *cur_len,
619 const char *name, unsigned long *bitmap, int max) 657 const char *name, unsigned long *bitmap, int max)
620{ 658{
@@ -639,7 +677,7 @@ static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
639 677
640#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ 678#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \
641 do { \ 679 do { \
642 int err = add_hotplug_env_var(envp, num_envp, &i, \ 680 int err = add_uevent_var(envp, num_envp, &i, \
643 buffer, buffer_size, &len, \ 681 buffer, buffer_size, &len, \
644 fmt, val); \ 682 fmt, val); \
645 if (err) \ 683 if (err) \
@@ -648,15 +686,15 @@ static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
648 686
649#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \ 687#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \
650 do { \ 688 do { \
651 int err = input_add_hotplug_bm_var(envp, num_envp, &i, \ 689 int err = input_add_uevent_bm_var(envp, num_envp, &i, \
652 buffer, buffer_size, &len, \ 690 buffer, buffer_size, &len, \
653 name, bm, max); \ 691 name, bm, max); \
654 if (err) \ 692 if (err) \
655 return err; \ 693 return err; \
656 } while (0) 694 } while (0)
657 695
658static int input_dev_hotplug(struct class_device *cdev, char **envp, 696static int input_dev_uevent(struct class_device *cdev, char **envp,
659 int num_envp, char *buffer, int buffer_size) 697 int num_envp, char *buffer, int buffer_size)
660{ 698{
661 struct input_dev *dev = to_input_dev(cdev); 699 struct input_dev *dev = to_input_dev(cdev);
662 int i = 0; 700 int i = 0;
@@ -698,7 +736,7 @@ static int input_dev_hotplug(struct class_device *cdev, char **envp,
698struct class input_class = { 736struct class input_class = {
699 .name = "input", 737 .name = "input",
700 .release = input_dev_release, 738 .release = input_dev_release,
701 .hotplug = input_dev_hotplug, 739 .uevent = input_dev_uevent,
702}; 740};
703 741
704struct input_dev *input_allocate_device(void) 742struct input_dev *input_allocate_device(void)
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index fbb69ef6a77..8e530cc970e 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -800,16 +800,16 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv)
800 800
801#ifdef CONFIG_HOTPLUG 801#ifdef CONFIG_HOTPLUG
802 802
803#define SERIO_ADD_HOTPLUG_VAR(fmt, val...) \ 803#define SERIO_ADD_UEVENT_VAR(fmt, val...) \
804 do { \ 804 do { \
805 int err = add_hotplug_env_var(envp, num_envp, &i, \ 805 int err = add_uevent_var(envp, num_envp, &i, \
806 buffer, buffer_size, &len, \ 806 buffer, buffer_size, &len, \
807 fmt, val); \ 807 fmt, val); \
808 if (err) \ 808 if (err) \
809 return err; \ 809 return err; \
810 } while (0) 810 } while (0)
811 811
812static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) 812static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
813{ 813{
814 struct serio *serio; 814 struct serio *serio;
815 int i = 0; 815 int i = 0;
@@ -820,21 +820,21 @@ static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *bu
820 820
821 serio = to_serio_port(dev); 821 serio = to_serio_port(dev);
822 822
823 SERIO_ADD_HOTPLUG_VAR("SERIO_TYPE=%02x", serio->id.type); 823 SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type);
824 SERIO_ADD_HOTPLUG_VAR("SERIO_PROTO=%02x", serio->id.proto); 824 SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto);
825 SERIO_ADD_HOTPLUG_VAR("SERIO_ID=%02x", serio->id.id); 825 SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id);
826 SERIO_ADD_HOTPLUG_VAR("SERIO_EXTRA=%02x", serio->id.extra); 826 SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
827 SERIO_ADD_HOTPLUG_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", 827 SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
828 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); 828 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
829 envp[i] = NULL; 829 envp[i] = NULL;
830 830
831 return 0; 831 return 0;
832} 832}
833#undef SERIO_ADD_HOTPLUG_VAR 833#undef SERIO_ADD_UEVENT_VAR
834 834
835#else 835#else
836 836
837static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) 837static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
838{ 838{
839 return -ENODEV; 839 return -ENODEV;
840} 840}
@@ -908,7 +908,7 @@ static int __init serio_init(void)
908 serio_bus.dev_attrs = serio_device_attrs; 908 serio_bus.dev_attrs = serio_device_attrs;
909 serio_bus.drv_attrs = serio_driver_attrs; 909 serio_bus.drv_attrs = serio_driver_attrs;
910 serio_bus.match = serio_bus_match; 910 serio_bus.match = serio_bus_match;
911 serio_bus.hotplug = serio_hotplug; 911 serio_bus.uevent = serio_uevent;
912 serio_bus.resume = serio_resume; 912 serio_bus.resume = serio_resume;
913 bus_register(&serio_bus); 913 bus_register(&serio_bus);
914 914
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index c34c96d1890..228e1852a83 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -128,7 +128,7 @@ static int macio_device_resume(struct device * dev)
128 return 0; 128 return 0;
129} 129}
130 130
131static int macio_hotplug (struct device *dev, char **envp, int num_envp, 131static int macio_uevent(struct device *dev, char **envp, int num_envp,
132 char *buffer, int buffer_size) 132 char *buffer, int buffer_size)
133{ 133{
134 struct macio_dev * macio_dev; 134 struct macio_dev * macio_dev;
@@ -203,7 +203,7 @@ extern struct device_attribute macio_dev_attrs[];
203struct bus_type macio_bus_type = { 203struct bus_type macio_bus_type = {
204 .name = "macio", 204 .name = "macio",
205 .match = macio_bus_match, 205 .match = macio_bus_match,
206 .hotplug = macio_hotplug, 206 .uevent = macio_uevent,
207 .suspend = macio_device_suspend, 207 .suspend = macio_device_suspend,
208 .resume = macio_device_resume, 208 .resume = macio_device_resume,
209 .dev_attrs = macio_dev_attrs, 209 .dev_attrs = macio_dev_attrs,
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c
index 3f4a66ca955..ec701667abf 100644
--- a/drivers/mmc/mmc_sysfs.c
+++ b/drivers/mmc/mmc_sysfs.c
@@ -80,7 +80,7 @@ static int mmc_bus_match(struct device *dev, struct device_driver *drv)
80} 80}
81 81
82static int 82static int
83mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf, 83mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
84 int buf_size) 84 int buf_size)
85{ 85{
86 struct mmc_card *card = dev_to_mmc_card(dev); 86 struct mmc_card *card = dev_to_mmc_card(dev);
@@ -140,7 +140,7 @@ static struct bus_type mmc_bus_type = {
140 .name = "mmc", 140 .name = "mmc",
141 .dev_attrs = mmc_dev_attrs, 141 .dev_attrs = mmc_dev_attrs,
142 .match = mmc_bus_match, 142 .match = mmc_bus_match,
143 .hotplug = mmc_bus_hotplug, 143 .uevent = mmc_bus_uevent,
144 .suspend = mmc_bus_suspend, 144 .suspend = mmc_bus_suspend,
145 .resume = mmc_bus_resume, 145 .resume = mmc_bus_resume,
146}; 146};
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index e1743be3190..1c97e7dd130 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -3,8 +3,8 @@
3#include <linux/module.h> 3#include <linux/module.h>
4#include "pci.h" 4#include "pci.h"
5 5
6int pci_hotplug (struct device *dev, char **envp, int num_envp, 6int pci_uevent(struct device *dev, char **envp, int num_envp,
7 char *buffer, int buffer_size) 7 char *buffer, int buffer_size)
8{ 8{
9 struct pci_dev *pdev; 9 struct pci_dev *pdev;
10 int i = 0; 10 int i = 0;
@@ -17,34 +17,34 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
17 if (!pdev) 17 if (!pdev)
18 return -ENODEV; 18 return -ENODEV;
19 19
20 if (add_hotplug_env_var(envp, num_envp, &i, 20 if (add_uevent_var(envp, num_envp, &i,
21 buffer, buffer_size, &length, 21 buffer, buffer_size, &length,
22 "PCI_CLASS=%04X", pdev->class)) 22 "PCI_CLASS=%04X", pdev->class))
23 return -ENOMEM; 23 return -ENOMEM;
24 24
25 if (add_hotplug_env_var(envp, num_envp, &i, 25 if (add_uevent_var(envp, num_envp, &i,
26 buffer, buffer_size, &length, 26 buffer, buffer_size, &length,
27 "PCI_ID=%04X:%04X", pdev->vendor, pdev->device)) 27 "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
28 return -ENOMEM; 28 return -ENOMEM;
29 29
30 if (add_hotplug_env_var(envp, num_envp, &i, 30 if (add_uevent_var(envp, num_envp, &i,
31 buffer, buffer_size, &length, 31 buffer, buffer_size, &length,
32 "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor, 32 "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
33 pdev->subsystem_device)) 33 pdev->subsystem_device))
34 return -ENOMEM; 34 return -ENOMEM;
35 35
36 if (add_hotplug_env_var(envp, num_envp, &i, 36 if (add_uevent_var(envp, num_envp, &i,
37 buffer, buffer_size, &length, 37 buffer, buffer_size, &length,
38 "PCI_SLOT_NAME=%s", pci_name(pdev))) 38 "PCI_SLOT_NAME=%s", pci_name(pdev)))
39 return -ENOMEM; 39 return -ENOMEM;
40 40
41 if (add_hotplug_env_var(envp, num_envp, &i, 41 if (add_uevent_var(envp, num_envp, &i,
42 buffer, buffer_size, &length, 42 buffer, buffer_size, &length,
43 "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x", 43 "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
44 pdev->vendor, pdev->device, 44 pdev->vendor, pdev->device,
45 pdev->subsystem_vendor, pdev->subsystem_device, 45 pdev->subsystem_vendor, pdev->subsystem_device,
46 (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), 46 (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
47 (u8)(pdev->class))) 47 (u8)(pdev->class)))
48 return -ENOMEM; 48 return -ENOMEM;
49 49
50 envp[i] = NULL; 50 envp[i] = NULL;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index a9046d4b8af..7146b69b812 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -502,8 +502,8 @@ void pci_dev_put(struct pci_dev *dev)
502} 502}
503 503
504#ifndef CONFIG_HOTPLUG 504#ifndef CONFIG_HOTPLUG
505int pci_hotplug (struct device *dev, char **envp, int num_envp, 505int pci_uevent(struct device *dev, char **envp, int num_envp,
506 char *buffer, int buffer_size) 506 char *buffer, int buffer_size)
507{ 507{
508 return -ENODEV; 508 return -ENODEV;
509} 509}
@@ -512,7 +512,7 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
512struct bus_type pci_bus_type = { 512struct bus_type pci_bus_type = {
513 .name = "pci", 513 .name = "pci",
514 .match = pci_bus_match, 514 .match = pci_bus_match,
515 .hotplug = pci_hotplug, 515 .uevent = pci_uevent,
516 .suspend = pci_device_suspend, 516 .suspend = pci_device_suspend,
517 .resume = pci_device_resume, 517 .resume = pci_device_resume,
518 .dev_attrs = pci_dev_attrs, 518 .dev_attrs = pci_dev_attrs,
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 6527b36c9a6..294849d2459 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1,7 +1,7 @@
1/* Functions internal to the PCI core code */ 1/* Functions internal to the PCI core code */
2 2
3extern int pci_hotplug (struct device *dev, char **envp, int num_envp, 3extern int pci_uevent(struct device *dev, char **envp, int num_envp,
4 char *buffer, int buffer_size); 4 char *buffer, int buffer_size);
5extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); 5extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
6extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); 6extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
7extern void pci_cleanup_rom(struct pci_dev *dev); 7extern void pci_cleanup_rom(struct pci_dev *dev);
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index a30aa74304a..7cf09084ef6 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -901,14 +901,14 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
901EXPORT_SYMBOL(pcmcia_insert_card); 901EXPORT_SYMBOL(pcmcia_insert_card);
902 902
903 903
904static int pcmcia_socket_hotplug(struct class_device *dev, char **envp, 904static int pcmcia_socket_uevent(struct class_device *dev, char **envp,
905 int num_envp, char *buffer, int buffer_size) 905 int num_envp, char *buffer, int buffer_size)
906{ 906{
907 struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); 907 struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
908 int i = 0, length = 0; 908 int i = 0, length = 0;
909 909
910 if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, 910 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
911 &length, "SOCKET_NO=%u", s->sock)) 911 &length, "SOCKET_NO=%u", s->sock))
912 return -ENOMEM; 912 return -ENOMEM;
913 913
914 envp[i] = NULL; 914 envp[i] = NULL;
@@ -927,7 +927,7 @@ static void pcmcia_release_socket_class(struct class *data)
927 927
928struct class pcmcia_socket_class = { 928struct class pcmcia_socket_class = {
929 .name = "pcmcia_socket", 929 .name = "pcmcia_socket",
930 .hotplug = pcmcia_socket_hotplug, 930 .uevent = pcmcia_socket_uevent,
931 .release = pcmcia_release_socket, 931 .release = pcmcia_release_socket,
932 .class_release = pcmcia_release_socket_class, 932 .class_release = pcmcia_release_socket_class,
933}; 933};
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 7f8219f3fd9..6fb76399547 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -779,8 +779,8 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
779 779
780#ifdef CONFIG_HOTPLUG 780#ifdef CONFIG_HOTPLUG
781 781
782static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp, 782static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
783 char *buffer, int buffer_size) 783 char *buffer, int buffer_size)
784{ 784{
785 struct pcmcia_device *p_dev; 785 struct pcmcia_device *p_dev;
786 int i, length = 0; 786 int i, length = 0;
@@ -800,31 +800,31 @@ static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
800 800
801 i = 0; 801 i = 0;
802 802
803 if (add_hotplug_env_var(envp, num_envp, &i, 803 if (add_uevent_var(envp, num_envp, &i,
804 buffer, buffer_size, &length, 804 buffer, buffer_size, &length,
805 "SOCKET_NO=%u", 805 "SOCKET_NO=%u",
806 p_dev->socket->sock)) 806 p_dev->socket->sock))
807 return -ENOMEM; 807 return -ENOMEM;
808 808
809 if (add_hotplug_env_var(envp, num_envp, &i, 809 if (add_uevent_var(envp, num_envp, &i,
810 buffer, buffer_size, &length, 810 buffer, buffer_size, &length,
811 "DEVICE_NO=%02X", 811 "DEVICE_NO=%02X",
812 p_dev->device_no)) 812 p_dev->device_no))
813 return -ENOMEM; 813 return -ENOMEM;
814 814
815 if (add_hotplug_env_var(envp, num_envp, &i, 815 if (add_uevent_var(envp, num_envp, &i,
816 buffer, buffer_size, &length, 816 buffer, buffer_size, &length,
817 "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X" 817 "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
818 "pa%08Xpb%08Xpc%08Xpd%08X", 818 "pa%08Xpb%08Xpc%08Xpd%08X",
819 p_dev->has_manf_id ? p_dev->manf_id : 0, 819 p_dev->has_manf_id ? p_dev->manf_id : 0,
820 p_dev->has_card_id ? p_dev->card_id : 0, 820 p_dev->has_card_id ? p_dev->card_id : 0,
821 p_dev->has_func_id ? p_dev->func_id : 0, 821 p_dev->has_func_id ? p_dev->func_id : 0,
822 p_dev->func, 822 p_dev->func,
823 p_dev->device_no, 823 p_dev->device_no,
824 hash[0], 824 hash[0],
825 hash[1], 825 hash[1],
826 hash[2], 826 hash[2],
827 hash[3])) 827 hash[3]))
828 return -ENOMEM; 828 return -ENOMEM;
829 829
830 envp[i] = NULL; 830 envp[i] = NULL;
@@ -834,7 +834,7 @@ static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
834 834
835#else 835#else
836 836
837static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp, 837static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
838 char *buffer, int buffer_size) 838 char *buffer, int buffer_size)
839{ 839{
840 return -ENODEV; 840 return -ENODEV;
@@ -1223,7 +1223,7 @@ static struct class_interface pcmcia_bus_interface = {
1223 1223
1224struct bus_type pcmcia_bus_type = { 1224struct bus_type pcmcia_bus_type = {
1225 .name = "pcmcia", 1225 .name = "pcmcia",
1226 .hotplug = pcmcia_bus_hotplug, 1226 .uevent = pcmcia_bus_uevent,
1227 .match = pcmcia_bus_match, 1227 .match = pcmcia_bus_match,
1228 .dev_attrs = pcmcia_dev_attrs, 1228 .dev_attrs = pcmcia_dev_attrs,
1229}; 1229};
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index f49674f0794..b154b3f52cb 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -56,7 +56,6 @@
56#include <linux/mm.h> 56#include <linux/mm.h>
57#include <linux/smp.h> 57#include <linux/smp.h>
58#include <linux/slab.h> 58#include <linux/slab.h>
59#include <linux/kobject_uevent.h>
60#include <linux/completion.h> 59#include <linux/completion.h>
61#include <linux/spinlock.h> 60#include <linux/spinlock.h>
62#include <linux/dmi.h> 61#include <linux/dmi.h>
@@ -106,8 +105,6 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
106 char *argv [3], **envp, *buf, *scratch; 105 char *argv [3], **envp, *buf, *scratch;
107 int i = 0, value; 106 int i = 0, value;
108 107
109 if (!hotplug_path [0])
110 return -ENOENT;
111 if (!current->fs->root) { 108 if (!current->fs->root) {
112 return -EAGAIN; 109 return -EAGAIN;
113 } 110 }
@@ -119,8 +116,9 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
119 return -ENOMEM; 116 return -ENOMEM;
120 } 117 }
121 118
122 /* only one standardized param to hotplug command: type */ 119 /* FIXME: if there are actual users of this, it should be integrated into
123 argv [0] = hotplug_path; 120 * the driver core and use the usual infrastructure like sysfs and uevents */
121 argv [0] = "/sbin/pnpbios";
124 argv [1] = "dock"; 122 argv [1] = "dock";
125 argv [2] = NULL; 123 argv [2] = NULL;
126 124
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index e7bd7f37f08..be9d2d65c22 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -45,7 +45,7 @@ ccwgroup_bus_match (struct device * dev, struct device_driver * drv)
45 return 0; 45 return 0;
46} 46}
47static int 47static int
48ccwgroup_hotplug (struct device *dev, char **envp, int num_envp, char *buffer, 48ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer,
49 int buffer_size) 49 int buffer_size)
50{ 50{
51 /* TODO */ 51 /* TODO */
@@ -55,7 +55,7 @@ ccwgroup_hotplug (struct device *dev, char **envp, int num_envp, char *buffer,
55static struct bus_type ccwgroup_bus_type = { 55static struct bus_type ccwgroup_bus_type = {
56 .name = "ccwgroup", 56 .name = "ccwgroup",
57 .match = ccwgroup_bus_match, 57 .match = ccwgroup_bus_match,
58 .hotplug = ccwgroup_hotplug, 58 .uevent = ccwgroup_uevent,
59}; 59};
60 60
61static inline void 61static inline void
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 811c9d15063..85908cacc3b 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -59,7 +59,7 @@ ccw_bus_match (struct device * dev, struct device_driver * drv)
59 * Heavily modeled on pci and usb hotplug. 59 * Heavily modeled on pci and usb hotplug.
60 */ 60 */
61static int 61static int
62ccw_hotplug (struct device *dev, char **envp, int num_envp, 62ccw_uevent (struct device *dev, char **envp, int num_envp,
63 char *buffer, int buffer_size) 63 char *buffer, int buffer_size)
64{ 64{
65 struct ccw_device *cdev = to_ccwdev(dev); 65 struct ccw_device *cdev = to_ccwdev(dev);
@@ -110,7 +110,7 @@ ccw_hotplug (struct device *dev, char **envp, int num_envp,
110struct bus_type ccw_bus_type = { 110struct bus_type ccw_bus_type = {
111 .name = "ccw", 111 .name = "ccw",
112 .match = &ccw_bus_match, 112 .match = &ccw_bus_match,
113 .hotplug = &ccw_hotplug, 113 .uevent = &ccw_uevent,
114}; 114};
115 115
116static int io_subchannel_probe (struct device *); 116static int io_subchannel_probe (struct device *);
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index 4010f2bb85a..790fcbb74b4 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -34,7 +34,6 @@
34#include <linux/miscdevice.h> 34#include <linux/miscdevice.h>
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/moduleparam.h> 36#include <linux/moduleparam.h>
37#include <linux/kobject_uevent.h>
38#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
39#include <linux/syscalls.h> 38#include <linux/syscalls.h>
40#include "z90crypt.h" 39#include "z90crypt.h"
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b6714da4d6e..27acf78cf8d 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2132,7 +2132,7 @@ restart:
2132 } 2132 }
2133 2133
2134 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 2134 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
2135 kobject_uevent(&ioa_cfg->host->shost_classdev.kobj, KOBJ_CHANGE, NULL); 2135 kobject_uevent(&ioa_cfg->host->shost_classdev.kobj, KOBJ_CHANGE);
2136 LEAVE; 2136 LEAVE;
2137} 2137}
2138 2138
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 56a3520863a..13d1d367f7f 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -192,6 +192,7 @@ void usb_driver_release_interface(struct usb_driver *driver,
192 iface->condition = USB_INTERFACE_UNBOUND; 192 iface->condition = USB_INTERFACE_UNBOUND;
193 mark_quiesced(iface); 193 mark_quiesced(iface);
194} 194}
195
195struct find_interface_arg { 196struct find_interface_arg {
196 int minor; 197 int minor;
197 struct usb_interface *interface; 198 struct usb_interface *interface;
@@ -236,10 +237,7 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
236#ifdef CONFIG_HOTPLUG 237#ifdef CONFIG_HOTPLUG
237 238
238/* 239/*
239 * USB hotplugging invokes what /proc/sys/kernel/hotplug says 240 * This sends an uevent to userspace, typically helping to load driver
240 * (normally /sbin/hotplug) when USB devices get added or removed.
241 *
242 * This invokes a user mode policy agent, typically helping to load driver
243 * or other modules, configure the device, and more. Drivers can provide 241 * or other modules, configure the device, and more. Drivers can provide
244 * a MODULE_DEVICE_TABLE to help with module loading subtasks. 242 * a MODULE_DEVICE_TABLE to help with module loading subtasks.
245 * 243 *
@@ -248,8 +246,8 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
248 * delays in event delivery. Use sysfs (and DEVPATH) to make sure the 246 * delays in event delivery. Use sysfs (and DEVPATH) to make sure the
249 * device (and this configuration!) are still present. 247 * device (and this configuration!) are still present.
250 */ 248 */
251static int usb_hotplug (struct device *dev, char **envp, int num_envp, 249static int usb_uevent(struct device *dev, char **envp, int num_envp,
252 char *buffer, int buffer_size) 250 char *buffer, int buffer_size)
253{ 251{
254 struct usb_interface *intf; 252 struct usb_interface *intf;
255 struct usb_device *usb_dev; 253 struct usb_device *usb_dev;
@@ -261,7 +259,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
261 return -ENODEV; 259 return -ENODEV;
262 260
263 /* driver is often null here; dev_dbg() would oops */ 261 /* driver is often null here; dev_dbg() would oops */
264 pr_debug ("usb %s: hotplug\n", dev->bus_id); 262 pr_debug ("usb %s: uevent\n", dev->bus_id);
265 263
266 /* Must check driver_data here, as on remove driver is always NULL */ 264 /* Must check driver_data here, as on remove driver is always NULL */
267 if ((dev->driver == &usb_generic_driver) || 265 if ((dev->driver == &usb_generic_driver) ||
@@ -288,51 +286,51 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
288 * 286 *
289 * FIXME reduce hardwired intelligence here 287 * FIXME reduce hardwired intelligence here
290 */ 288 */
291 if (add_hotplug_env_var(envp, num_envp, &i, 289 if (add_uevent_var(envp, num_envp, &i,
292 buffer, buffer_size, &length, 290 buffer, buffer_size, &length,
293 "DEVICE=/proc/bus/usb/%03d/%03d", 291 "DEVICE=/proc/bus/usb/%03d/%03d",
294 usb_dev->bus->busnum, usb_dev->devnum)) 292 usb_dev->bus->busnum, usb_dev->devnum))
295 return -ENOMEM; 293 return -ENOMEM;
296#endif 294#endif
297 295
298 /* per-device configurations are common */ 296 /* per-device configurations are common */
299 if (add_hotplug_env_var(envp, num_envp, &i, 297 if (add_uevent_var(envp, num_envp, &i,
300 buffer, buffer_size, &length, 298 buffer, buffer_size, &length,
301 "PRODUCT=%x/%x/%x", 299 "PRODUCT=%x/%x/%x",
302 le16_to_cpu(usb_dev->descriptor.idVendor), 300 le16_to_cpu(usb_dev->descriptor.idVendor),
303 le16_to_cpu(usb_dev->descriptor.idProduct), 301 le16_to_cpu(usb_dev->descriptor.idProduct),
304 le16_to_cpu(usb_dev->descriptor.bcdDevice))) 302 le16_to_cpu(usb_dev->descriptor.bcdDevice)))
305 return -ENOMEM; 303 return -ENOMEM;
306 304
307 /* class-based driver binding models */ 305 /* class-based driver binding models */
308 if (add_hotplug_env_var(envp, num_envp, &i, 306 if (add_uevent_var(envp, num_envp, &i,
309 buffer, buffer_size, &length, 307 buffer, buffer_size, &length,
310 "TYPE=%d/%d/%d", 308 "TYPE=%d/%d/%d",
311 usb_dev->descriptor.bDeviceClass, 309 usb_dev->descriptor.bDeviceClass,
312 usb_dev->descriptor.bDeviceSubClass, 310 usb_dev->descriptor.bDeviceSubClass,
313 usb_dev->descriptor.bDeviceProtocol)) 311 usb_dev->descriptor.bDeviceProtocol))
314 return -ENOMEM; 312 return -ENOMEM;
315 313
316 if (add_hotplug_env_var(envp, num_envp, &i, 314 if (add_uevent_var(envp, num_envp, &i,
317 buffer, buffer_size, &length, 315 buffer, buffer_size, &length,
318 "INTERFACE=%d/%d/%d", 316 "INTERFACE=%d/%d/%d",
319 alt->desc.bInterfaceClass, 317 alt->desc.bInterfaceClass,
320 alt->desc.bInterfaceSubClass, 318 alt->desc.bInterfaceSubClass,
321 alt->desc.bInterfaceProtocol)) 319 alt->desc.bInterfaceProtocol))
322 return -ENOMEM; 320 return -ENOMEM;
323 321
324 if (add_hotplug_env_var(envp, num_envp, &i, 322 if (add_uevent_var(envp, num_envp, &i,
325 buffer, buffer_size, &length, 323 buffer, buffer_size, &length,
326 "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", 324 "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
327 le16_to_cpu(usb_dev->descriptor.idVendor), 325 le16_to_cpu(usb_dev->descriptor.idVendor),
328 le16_to_cpu(usb_dev->descriptor.idProduct), 326 le16_to_cpu(usb_dev->descriptor.idProduct),
329 le16_to_cpu(usb_dev->descriptor.bcdDevice), 327 le16_to_cpu(usb_dev->descriptor.bcdDevice),
330 usb_dev->descriptor.bDeviceClass, 328 usb_dev->descriptor.bDeviceClass,
331 usb_dev->descriptor.bDeviceSubClass, 329 usb_dev->descriptor.bDeviceSubClass,
332 usb_dev->descriptor.bDeviceProtocol, 330 usb_dev->descriptor.bDeviceProtocol,
333 alt->desc.bInterfaceClass, 331 alt->desc.bInterfaceClass,
334 alt->desc.bInterfaceSubClass, 332 alt->desc.bInterfaceSubClass,
335 alt->desc.bInterfaceProtocol)) 333 alt->desc.bInterfaceProtocol))
336 return -ENOMEM; 334 return -ENOMEM;
337 335
338 envp[i] = NULL; 336 envp[i] = NULL;
@@ -342,7 +340,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
342 340
343#else 341#else
344 342
345static int usb_hotplug (struct device *dev, char **envp, 343static int usb_uevent(struct device *dev, char **envp,
346 int num_envp, char *buffer, int buffer_size) 344 int num_envp, char *buffer, int buffer_size)
347{ 345{
348 return -ENODEV; 346 return -ENODEV;
@@ -1093,7 +1091,7 @@ static int usb_generic_resume(struct device *dev)
1093struct bus_type usb_bus_type = { 1091struct bus_type usb_bus_type = {
1094 .name = "usb", 1092 .name = "usb",
1095 .match = usb_device_match, 1093 .match = usb_device_match,
1096 .hotplug = usb_hotplug, 1094 .uevent = usb_uevent,
1097 .suspend = usb_generic_suspend, 1095 .suspend = usb_generic_suspend,
1098 .resume = usb_generic_resume, 1096 .resume = usb_generic_resume,
1099}; 1097};
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index 0eaabeb37ac..641268d7e6f 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -4397,7 +4397,7 @@ static int __init etrax_usb_hc_init(void)
4397 device_initialize(&fake_device); 4397 device_initialize(&fake_device);
4398 kobject_set_name(&fake_device.kobj, "etrax_usb"); 4398 kobject_set_name(&fake_device.kobj, "etrax_usb");
4399 kobject_add(&fake_device.kobj); 4399 kobject_add(&fake_device.kobj);
4400 kobject_hotplug(&fake_device.kobj, KOBJ_ADD); 4400 kobject_uevent(&fake_device.kobj, KOBJ_ADD);
4401 hc->bus->controller = &fake_device; 4401 hc->bus->controller = &fake_device;
4402 usb_register_bus(hc->bus); 4402 usb_register_bus(hc->bus);
4403 4403
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 14016b1cd94..024206c4a0e 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -142,12 +142,12 @@ static struct bin_attribute w1_slave_attr_bin_id = {
142/* Default family */ 142/* Default family */
143static struct w1_family w1_default_family; 143static struct w1_family w1_default_family;
144 144
145static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); 145static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
146 146
147static struct bus_type w1_bus_type = { 147static struct bus_type w1_bus_type = {
148 .name = "w1", 148 .name = "w1",
149 .match = w1_master_match, 149 .match = w1_master_match,
150 .hotplug = w1_hotplug, 150 .uevent = w1_uevent,
151}; 151};
152 152
153struct device_driver w1_master_driver = { 153struct device_driver w1_master_driver = {
@@ -361,7 +361,7 @@ void w1_destroy_master_attributes(struct w1_master *master)
361} 361}
362 362
363#ifdef CONFIG_HOTPLUG 363#ifdef CONFIG_HOTPLUG
364static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) 364static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
365{ 365{
366 struct w1_master *md = NULL; 366 struct w1_master *md = NULL;
367 struct w1_slave *sl = NULL; 367 struct w1_slave *sl = NULL;
@@ -377,7 +377,7 @@ static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffe
377 event_owner = "slave"; 377 event_owner = "slave";
378 name = sl->name; 378 name = sl->name;
379 } else { 379 } else {
380 dev_dbg(dev, "Unknown hotplug event.\n"); 380 dev_dbg(dev, "Unknown event.\n");
381 return -EINVAL; 381 return -EINVAL;
382 } 382 }
383 383
@@ -386,18 +386,18 @@ static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffe
386 if (dev->driver != &w1_slave_driver || !sl) 386 if (dev->driver != &w1_slave_driver || !sl)
387 return 0; 387 return 0;
388 388
389 err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family); 389 err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family);
390 if (err) 390 if (err)
391 return err; 391 return err;
392 392
393 err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id); 393 err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id);
394 if (err) 394 if (err)
395 return err; 395 return err;
396 396
397 return 0; 397 return 0;
398}; 398};
399#else 399#else
400static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) 400static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
401{ 401{
402 return 0; 402 return 0;
403} 403}
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 8dc1822a702..7881ce05dae 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -226,7 +226,7 @@ static struct sysfs_ops part_sysfs_ops = {
226static ssize_t part_uevent_store(struct hd_struct * p, 226static ssize_t part_uevent_store(struct hd_struct * p,
227 const char *page, size_t count) 227 const char *page, size_t count)
228{ 228{
229 kobject_hotplug(&p->kobj, KOBJ_ADD); 229 kobject_uevent(&p->kobj, KOBJ_ADD);
230 return count; 230 return count;
231} 231}
232static ssize_t part_dev_read(struct hd_struct * p, char *page) 232static ssize_t part_dev_read(struct hd_struct * p, char *page)
@@ -336,12 +336,31 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
336 disk->part[part-1] = p; 336 disk->part[part-1] = p;
337} 337}
338 338
339static char *make_block_name(struct gendisk *disk)
340{
341 char *name;
342 static char *block_str = "block:";
343 int size;
344
345 size = strlen(block_str) + strlen(disk->disk_name) + 1;
346 name = kmalloc(size, GFP_KERNEL);
347 if (!name)
348 return NULL;
349 strcpy(name, block_str);
350 strcat(name, disk->disk_name);
351 return name;
352}
353
339static void disk_sysfs_symlinks(struct gendisk *disk) 354static void disk_sysfs_symlinks(struct gendisk *disk)
340{ 355{
341 struct device *target = get_device(disk->driverfs_dev); 356 struct device *target = get_device(disk->driverfs_dev);
342 if (target) { 357 if (target) {
358 char *disk_name = make_block_name(disk);
343 sysfs_create_link(&disk->kobj,&target->kobj,"device"); 359 sysfs_create_link(&disk->kobj,&target->kobj,"device");
344 sysfs_create_link(&target->kobj,&disk->kobj,"block"); 360 if (disk_name) {
361 sysfs_create_link(&target->kobj,&disk->kobj,disk_name);
362 kfree(disk_name);
363 }
345 } 364 }
346} 365}
347 366
@@ -360,7 +379,7 @@ void register_disk(struct gendisk *disk)
360 if ((err = kobject_add(&disk->kobj))) 379 if ((err = kobject_add(&disk->kobj)))
361 return; 380 return;
362 disk_sysfs_symlinks(disk); 381 disk_sysfs_symlinks(disk);
363 kobject_hotplug(&disk->kobj, KOBJ_ADD); 382 kobject_uevent(&disk->kobj, KOBJ_ADD);
364 383
365 /* No minors to use for partitions */ 384 /* No minors to use for partitions */
366 if (disk->minors == 1) { 385 if (disk->minors == 1) {
@@ -461,10 +480,14 @@ void del_gendisk(struct gendisk *disk)
461 devfs_remove_disk(disk); 480 devfs_remove_disk(disk);
462 481
463 if (disk->driverfs_dev) { 482 if (disk->driverfs_dev) {
483 char *disk_name = make_block_name(disk);
464 sysfs_remove_link(&disk->kobj, "device"); 484 sysfs_remove_link(&disk->kobj, "device");
465 sysfs_remove_link(&disk->driverfs_dev->kobj, "block"); 485 if (disk_name) {
486 sysfs_remove_link(&disk->driverfs_dev->kobj, disk_name);
487 kfree(disk_name);
488 }
466 put_device(disk->driverfs_dev); 489 put_device(disk->driverfs_dev);
467 } 490 }
468 kobject_hotplug(&disk->kobj, KOBJ_REMOVE); 491 kobject_uevent(&disk->kobj, KOBJ_REMOVE);
469 kobject_del(&disk->kobj); 492 kobject_del(&disk->kobj);
470} 493}
diff --git a/fs/super.c b/fs/super.c
index 6689dded3c8..5a347a4f673 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -665,16 +665,6 @@ static int test_bdev_super(struct super_block *s, void *data)
665 return (void *)s->s_bdev == data; 665 return (void *)s->s_bdev == data;
666} 666}
667 667
668static void bdev_uevent(struct block_device *bdev, enum kobject_action action)
669{
670 if (bdev->bd_disk) {
671 if (bdev->bd_part)
672 kobject_uevent(&bdev->bd_part->kobj, action, NULL);
673 else
674 kobject_uevent(&bdev->bd_disk->kobj, action, NULL);
675 }
676}
677
678struct super_block *get_sb_bdev(struct file_system_type *fs_type, 668struct super_block *get_sb_bdev(struct file_system_type *fs_type,
679 int flags, const char *dev_name, void *data, 669 int flags, const char *dev_name, void *data,
680 int (*fill_super)(struct super_block *, void *, int)) 670 int (*fill_super)(struct super_block *, void *, int))
@@ -717,10 +707,8 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
717 up_write(&s->s_umount); 707 up_write(&s->s_umount);
718 deactivate_super(s); 708 deactivate_super(s);
719 s = ERR_PTR(error); 709 s = ERR_PTR(error);
720 } else { 710 } else
721 s->s_flags |= MS_ACTIVE; 711 s->s_flags |= MS_ACTIVE;
722 bdev_uevent(bdev, KOBJ_MOUNT);
723 }
724 } 712 }
725 713
726 return s; 714 return s;
@@ -736,7 +724,6 @@ void kill_block_super(struct super_block *sb)
736{ 724{
737 struct block_device *bdev = sb->s_bdev; 725 struct block_device *bdev = sb->s_bdev;
738 726
739 bdev_uevent(bdev, KOBJ_UMOUNT);
740 generic_shutdown_super(sb); 727 generic_shutdown_super(sb);
741 sync_blockdev(bdev); 728 sync_blockdev(bdev);
742 close_bdev_excl(bdev); 729 close_bdev_excl(bdev);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 59734ba1ee6..d3678038217 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -112,7 +112,11 @@ static int create_dir(struct kobject * k, struct dentry * p,
112 } 112 }
113 } 113 }
114 if (error && (error != -EEXIST)) { 114 if (error && (error != -EEXIST)) {
115 sysfs_put((*d)->d_fsdata); 115 struct sysfs_dirent *sd = (*d)->d_fsdata;
116 if (sd) {
117 list_del_init(&sd->s_sibling);
118 sysfs_put(sd);
119 }
116 d_drop(*d); 120 d_drop(*d);
117 } 121 }
118 dput(*d); 122 dput(*d);
diff --git a/include/linux/device.h b/include/linux/device.h
index 17cbc6db67b..0cdee78e5ce 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -47,8 +47,8 @@ struct bus_type {
47 struct driver_attribute * drv_attrs; 47 struct driver_attribute * drv_attrs;
48 48
49 int (*match)(struct device * dev, struct device_driver * drv); 49 int (*match)(struct device * dev, struct device_driver * drv);
50 int (*hotplug) (struct device *dev, char **envp, 50 int (*uevent)(struct device *dev, char **envp,
51 int num_envp, char *buffer, int buffer_size); 51 int num_envp, char *buffer, int buffer_size);
52 int (*suspend)(struct device * dev, pm_message_t state); 52 int (*suspend)(struct device * dev, pm_message_t state);
53 int (*resume)(struct device * dev); 53 int (*resume)(struct device * dev);
54}; 54};
@@ -151,7 +151,7 @@ struct class {
151 struct class_attribute * class_attrs; 151 struct class_attribute * class_attrs;
152 struct class_device_attribute * class_dev_attrs; 152 struct class_device_attribute * class_dev_attrs;
153 153
154 int (*hotplug)(struct class_device *dev, char **envp, 154 int (*uevent)(struct class_device *dev, char **envp,
155 int num_envp, char *buffer, int buffer_size); 155 int num_envp, char *buffer, int buffer_size);
156 156
157 void (*release)(struct class_device *dev); 157 void (*release)(struct class_device *dev);
@@ -209,9 +209,9 @@ extern int class_device_create_file(struct class_device *,
209 * set, this will be called instead of the class specific release function. 209 * set, this will be called instead of the class specific release function.
210 * Only use this if you want to override the default release function, like 210 * Only use this if you want to override the default release function, like
211 * when you are nesting class_device structures. 211 * when you are nesting class_device structures.
212 * @hotplug: pointer to a hotplug function for this struct class_device. If 212 * @uevent: pointer to a uevent function for this struct class_device. If
213 * set, this will be called instead of the class specific hotplug function. 213 * set, this will be called instead of the class specific uevent function.
214 * Only use this if you want to override the default hotplug function, like 214 * Only use this if you want to override the default uevent function, like
215 * when you are nesting class_device structures. 215 * when you are nesting class_device structures.
216 */ 216 */
217struct class_device { 217struct class_device {
@@ -227,7 +227,7 @@ struct class_device {
227 struct class_device *parent; /* parent of this child device, if there is one */ 227 struct class_device *parent; /* parent of this child device, if there is one */
228 228
229 void (*release)(struct class_device *dev); 229 void (*release)(struct class_device *dev);
230 int (*hotplug)(struct class_device *dev, char **envp, 230 int (*uevent)(struct class_device *dev, char **envp,
231 int num_envp, char *buffer, int buffer_size); 231 int num_envp, char *buffer, int buffer_size);
232 char class_id[BUS_ID_SIZE]; /* unique to this class */ 232 char class_id[BUS_ID_SIZE]; /* unique to this class */
233}; 233};
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
index 2063c0839d4..2d716080be4 100644
--- a/include/linux/firmware.h
+++ b/include/linux/firmware.h
@@ -14,7 +14,7 @@ struct device;
14int request_firmware(const struct firmware **fw, const char *name, 14int request_firmware(const struct firmware **fw, const char *name,
15 struct device *device); 15 struct device *device);
16int request_firmware_nowait( 16int request_firmware_nowait(
17 struct module *module, int hotplug, 17 struct module *module, int uevent,
18 const char *name, struct device *device, void *context, 18 const char *name, struct device *device, void *context,
19 void (*cont)(const struct firmware *fw, void *context)); 19 void (*cont)(const struct firmware *fw, void *context));
20 20
diff --git a/include/linux/input.h b/include/linux/input.h
index 3c5823368dd..6d4cc3c110d 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -13,6 +13,7 @@
13#include <linux/time.h> 13#include <linux/time.h>
14#include <linux/list.h> 14#include <linux/list.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/mod_devicetable.h>
16#else 17#else
17#include <sys/time.h> 18#include <sys/time.h>
18#include <sys/ioctl.h> 19#include <sys/ioctl.h>
@@ -511,6 +512,8 @@ struct input_absinfo {
511#define KEY_FN_S 0x1e3 512#define KEY_FN_S 0x1e3
512#define KEY_FN_B 0x1e4 513#define KEY_FN_B 0x1e4
513 514
515/* We avoid low common keys in module aliases so they don't get huge. */
516#define KEY_MIN_INTERESTING KEY_MUTE
514#define KEY_MAX 0x1ff 517#define KEY_MAX 0x1ff
515 518
516/* 519/*
@@ -793,6 +796,44 @@ struct ff_effect {
793 796
794#define FF_MAX 0x7f 797#define FF_MAX 0x7f
795 798
799struct input_device_id {
800
801 kernel_ulong_t flags;
802
803 struct input_id id;
804
805 kernel_ulong_t evbit[EV_MAX/BITS_PER_LONG+1];
806 kernel_ulong_t keybit[KEY_MAX/BITS_PER_LONG+1];
807 kernel_ulong_t relbit[REL_MAX/BITS_PER_LONG+1];
808 kernel_ulong_t absbit[ABS_MAX/BITS_PER_LONG+1];
809 kernel_ulong_t mscbit[MSC_MAX/BITS_PER_LONG+1];
810 kernel_ulong_t ledbit[LED_MAX/BITS_PER_LONG+1];
811 kernel_ulong_t sndbit[SND_MAX/BITS_PER_LONG+1];
812 kernel_ulong_t ffbit[FF_MAX/BITS_PER_LONG+1];
813 kernel_ulong_t swbit[SW_MAX/BITS_PER_LONG+1];
814
815 kernel_ulong_t driver_info;
816};
817
818/*
819 * Structure for hotplug & device<->driver matching.
820 */
821
822#define INPUT_DEVICE_ID_MATCH_BUS 1
823#define INPUT_DEVICE_ID_MATCH_VENDOR 2
824#define INPUT_DEVICE_ID_MATCH_PRODUCT 4
825#define INPUT_DEVICE_ID_MATCH_VERSION 8
826
827#define INPUT_DEVICE_ID_MATCH_EVBIT 0x010
828#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020
829#define INPUT_DEVICE_ID_MATCH_RELBIT 0x040
830#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080
831#define INPUT_DEVICE_ID_MATCH_MSCIT 0x100
832#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200
833#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400
834#define INPUT_DEVICE_ID_MATCH_FFBIT 0x800
835#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000
836
796#ifdef __KERNEL__ 837#ifdef __KERNEL__
797 838
798/* 839/*
@@ -901,49 +942,11 @@ struct input_dev {
901}; 942};
902#define to_input_dev(d) container_of(d, struct input_dev, cdev) 943#define to_input_dev(d) container_of(d, struct input_dev, cdev)
903 944
904/*
905 * Structure for hotplug & device<->driver matching.
906 */
907
908#define INPUT_DEVICE_ID_MATCH_BUS 1
909#define INPUT_DEVICE_ID_MATCH_VENDOR 2
910#define INPUT_DEVICE_ID_MATCH_PRODUCT 4
911#define INPUT_DEVICE_ID_MATCH_VERSION 8
912
913#define INPUT_DEVICE_ID_MATCH_EVBIT 0x010
914#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020
915#define INPUT_DEVICE_ID_MATCH_RELBIT 0x040
916#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080
917#define INPUT_DEVICE_ID_MATCH_MSCIT 0x100
918#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200
919#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400
920#define INPUT_DEVICE_ID_MATCH_FFBIT 0x800
921#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000
922
923#define INPUT_DEVICE_ID_MATCH_DEVICE\ 945#define INPUT_DEVICE_ID_MATCH_DEVICE\
924 (INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT) 946 (INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT)
925#define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\ 947#define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\
926 (INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION) 948 (INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION)
927 949
928struct input_device_id {
929
930 unsigned long flags;
931
932 struct input_id id;
933
934 unsigned long evbit[NBITS(EV_MAX)];
935 unsigned long keybit[NBITS(KEY_MAX)];
936 unsigned long relbit[NBITS(REL_MAX)];
937 unsigned long absbit[NBITS(ABS_MAX)];
938 unsigned long mscbit[NBITS(MSC_MAX)];
939 unsigned long ledbit[NBITS(LED_MAX)];
940 unsigned long sndbit[NBITS(SND_MAX)];
941 unsigned long ffbit[NBITS(FF_MAX)];
942 unsigned long swbit[NBITS(SW_MAX)];
943
944 unsigned long driver_info;
945};
946
947struct input_handle; 950struct input_handle;
948 951
949struct input_handler { 952struct input_handler {
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 7f7403aa4a4..2a8d8da7096 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -23,14 +23,27 @@
23#include <linux/spinlock.h> 23#include <linux/spinlock.h>
24#include <linux/rwsem.h> 24#include <linux/rwsem.h>
25#include <linux/kref.h> 25#include <linux/kref.h>
26#include <linux/kobject_uevent.h>
27#include <linux/kernel.h> 26#include <linux/kernel.h>
28#include <asm/atomic.h> 27#include <asm/atomic.h>
29 28
30#define KOBJ_NAME_LEN 20 29#define KOBJ_NAME_LEN 20
30#define UEVENT_HELPER_PATH_LEN 256
31 31
32/* counter to tag the hotplug event, read only except for the kobject core */ 32/* path to the userspace helper executed on an event */
33extern u64 hotplug_seqnum; 33extern char uevent_helper[];
34
35/* counter to tag the uevent, read only except for the kobject core */
36extern u64 uevent_seqnum;
37
38/* the actions here must match the proper string in lib/kobject_uevent.c */
39typedef int __bitwise kobject_action_t;
40enum kobject_action {
41 KOBJ_ADD = (__force kobject_action_t) 0x01, /* exclusive to core */
42 KOBJ_REMOVE = (__force kobject_action_t) 0x02, /* exclusive to core */
43 KOBJ_CHANGE = (__force kobject_action_t) 0x03, /* device state change */
44 KOBJ_OFFLINE = (__force kobject_action_t) 0x04, /* device offline */
45 KOBJ_ONLINE = (__force kobject_action_t) 0x05, /* device online */
46};
34 47
35struct kobject { 48struct kobject {
36 const char * k_name; 49 const char * k_name;
@@ -87,15 +100,14 @@ struct kobj_type {
87 * of object; multiple ksets can belong to one subsystem. All 100 * of object; multiple ksets can belong to one subsystem. All
88 * ksets of a subsystem share the subsystem's lock. 101 * ksets of a subsystem share the subsystem's lock.
89 * 102 *
90 * Each kset can support hotplugging; if it does, it will be given 103 * Each kset can support specific event variables; it can
91 * the opportunity to filter out specific kobjects from being 104 * supress the event generation or add subsystem specific
92 * reported, as well as to add its own "data" elements to the 105 * variables carried with the event.
93 * environment being passed to the hotplug helper.
94 */ 106 */
95struct kset_hotplug_ops { 107struct kset_uevent_ops {
96 int (*filter)(struct kset *kset, struct kobject *kobj); 108 int (*filter)(struct kset *kset, struct kobject *kobj);
97 const char *(*name)(struct kset *kset, struct kobject *kobj); 109 const char *(*name)(struct kset *kset, struct kobject *kobj);
98 int (*hotplug)(struct kset *kset, struct kobject *kobj, char **envp, 110 int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp,
99 int num_envp, char *buffer, int buffer_size); 111 int num_envp, char *buffer, int buffer_size);
100}; 112};
101 113
@@ -105,7 +117,7 @@ struct kset {
105 struct list_head list; 117 struct list_head list;
106 spinlock_t list_lock; 118 spinlock_t list_lock;
107 struct kobject kobj; 119 struct kobject kobj;
108 struct kset_hotplug_ops * hotplug_ops; 120 struct kset_uevent_ops * uevent_ops;
109}; 121};
110 122
111 123
@@ -153,20 +165,20 @@ struct subsystem {
153 struct rw_semaphore rwsem; 165 struct rw_semaphore rwsem;
154}; 166};
155 167
156#define decl_subsys(_name,_type,_hotplug_ops) \ 168#define decl_subsys(_name,_type,_uevent_ops) \
157struct subsystem _name##_subsys = { \ 169struct subsystem _name##_subsys = { \
158 .kset = { \ 170 .kset = { \
159 .kobj = { .name = __stringify(_name) }, \ 171 .kobj = { .name = __stringify(_name) }, \
160 .ktype = _type, \ 172 .ktype = _type, \
161 .hotplug_ops =_hotplug_ops, \ 173 .uevent_ops =_uevent_ops, \
162 } \ 174 } \
163} 175}
164#define decl_subsys_name(_varname,_name,_type,_hotplug_ops) \ 176#define decl_subsys_name(_varname,_name,_type,_uevent_ops) \
165struct subsystem _varname##_subsys = { \ 177struct subsystem _varname##_subsys = { \
166 .kset = { \ 178 .kset = { \
167 .kobj = { .name = __stringify(_name) }, \ 179 .kobj = { .name = __stringify(_name) }, \
168 .ktype = _type, \ 180 .ktype = _type, \
169 .hotplug_ops =_hotplug_ops, \ 181 .uevent_ops =_uevent_ops, \
170 } \ 182 } \
171} 183}
172 184
@@ -241,15 +253,17 @@ struct subsys_attribute {
241extern int subsys_create_file(struct subsystem * , struct subsys_attribute *); 253extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
242extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *); 254extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
243 255
244#ifdef CONFIG_HOTPLUG 256#if defined(CONFIG_HOTPLUG) & defined(CONFIG_NET)
245void kobject_hotplug(struct kobject *kobj, enum kobject_action action); 257void kobject_uevent(struct kobject *kobj, enum kobject_action action);
246int add_hotplug_env_var(char **envp, int num_envp, int *cur_index, 258
259int add_uevent_var(char **envp, int num_envp, int *cur_index,
247 char *buffer, int buffer_size, int *cur_len, 260 char *buffer, int buffer_size, int *cur_len,
248 const char *format, ...) 261 const char *format, ...)
249 __attribute__((format (printf, 7, 8))); 262 __attribute__((format (printf, 7, 8)));
250#else 263#else
251static inline void kobject_hotplug(struct kobject *kobj, enum kobject_action action) { } 264static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { }
252static inline int add_hotplug_env_var(char **envp, int num_envp, int *cur_index, 265
266static inline int add_uevent_var(char **envp, int num_envp, int *cur_index,
253 char *buffer, int buffer_size, int *cur_len, 267 char *buffer, int buffer_size, int *cur_len,
254 const char *format, ...) 268 const char *format, ...)
255{ return 0; } 269{ return 0; }
diff --git a/include/linux/kobject_uevent.h b/include/linux/kobject_uevent.h
deleted file mode 100644
index aa664fe7e56..00000000000
--- a/include/linux/kobject_uevent.h
+++ /dev/null
@@ -1,57 +0,0 @@
1/*
2 * kobject_uevent.h - list of kobject user events that can be generated
3 *
4 * Copyright (C) 2004 IBM Corp.
5 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
6 *
7 * This file is released under the GPLv2.
8 *
9 */
10
11#ifndef _KOBJECT_EVENT_H_
12#define _KOBJECT_EVENT_H_
13
14#define HOTPLUG_PATH_LEN 256
15
16/* path to the hotplug userspace helper executed on an event */
17extern char hotplug_path[];
18
19/*
20 * If you add an action here, you must also add the proper string to the
21 * lib/kobject_uevent.c file.
22 */
23typedef int __bitwise kobject_action_t;
24enum kobject_action {
25 KOBJ_ADD = (__force kobject_action_t) 0x01, /* add event, for hotplug */
26 KOBJ_REMOVE = (__force kobject_action_t) 0x02, /* remove event, for hotplug */
27 KOBJ_CHANGE = (__force kobject_action_t) 0x03, /* a sysfs attribute file has changed */
28 KOBJ_MOUNT = (__force kobject_action_t) 0x04, /* mount event for block devices */
29 KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices */
30 KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* offline event for hotplug devices */
31 KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* online event for hotplug devices */
32};
33
34
35#ifdef CONFIG_KOBJECT_UEVENT
36int kobject_uevent(struct kobject *kobj,
37 enum kobject_action action,
38 struct attribute *attr);
39int kobject_uevent_atomic(struct kobject *kobj,
40 enum kobject_action action,
41 struct attribute *attr);
42#else
43static inline int kobject_uevent(struct kobject *kobj,
44 enum kobject_action action,
45 struct attribute *attr)
46{
47 return 0;
48}
49static inline int kobject_uevent_atomic(struct kobject *kobj,
50 enum kobject_action action,
51 struct attribute *attr)
52{
53 return 0;
54}
55#endif
56
57#endif
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 17e336f40b4..782090c6893 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -41,6 +41,7 @@ extern struct platform_device *platform_device_alloc(const char *name, unsigned
41extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num); 41extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
42extern int platform_device_add_data(struct platform_device *pdev, void *data, size_t size); 42extern int platform_device_add_data(struct platform_device *pdev, void *data, size_t size);
43extern int platform_device_add(struct platform_device *pdev); 43extern int platform_device_add(struct platform_device *pdev);
44extern void platform_device_del(struct platform_device *pdev);
44extern void platform_device_put(struct platform_device *pdev); 45extern void platform_device_put(struct platform_device *pdev);
45 46
46struct platform_driver { 47struct platform_driver {
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 93fa765e47d..a9b80fc7f0f 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -124,7 +124,7 @@ enum
124 KERN_OVERFLOWUID=46, /* int: overflow UID */ 124 KERN_OVERFLOWUID=46, /* int: overflow UID */
125 KERN_OVERFLOWGID=47, /* int: overflow GID */ 125 KERN_OVERFLOWGID=47, /* int: overflow GID */
126 KERN_SHMPATH=48, /* string: path to shm fs */ 126 KERN_SHMPATH=48, /* string: path to shm fs */
127 KERN_HOTPLUG=49, /* string: path to hotplug policy agent */ 127 KERN_HOTPLUG=49, /* string: path to uevent helper (deprecated) */
128 KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */ 128 KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */
129 KERN_S390_USER_DEBUG_LOGGING=51, /* int: dumps of user faults */ 129 KERN_S390_USER_DEBUG_LOGGING=51, /* int: dumps of user faults */
130 KERN_CORE_USES_PID=52, /* int: use core or core.%pid */ 130 KERN_CORE_USES_PID=52, /* int: use core or core.%pid */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index e59d1bd52d4..827cc6de5f5 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -225,7 +225,7 @@ struct usb_interface_cache {
225 * Device drivers should not attempt to activate configurations. The choice 225 * Device drivers should not attempt to activate configurations. The choice
226 * of which configuration to install is a policy decision based on such 226 * of which configuration to install is a policy decision based on such
227 * considerations as available power, functionality provided, and the user's 227 * considerations as available power, functionality provided, and the user's
228 * desires (expressed through hotplug scripts). However, drivers can call 228 * desires (expressed through userspace tools). However, drivers can call
229 * usb_reset_configuration() to reinitialize the current configuration and 229 * usb_reset_configuration() to reinitialize the current configuration and
230 * all its interfaces. 230 * all its interfaces.
231 */ 231 */
diff --git a/init/Kconfig b/init/Kconfig
index aa29b797ca2..ce737e02c5a 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -197,33 +197,6 @@ config AUDITSYSCALL
197 can be used independently or with another kernel subsystem, 197 can be used independently or with another kernel subsystem,
198 such as SELinux. 198 such as SELinux.
199 199
200config HOTPLUG
201 bool "Support for hot-pluggable devices" if !ARCH_S390
202 default ARCH_S390
203 help
204 This option is provided for the case where no in-kernel-tree
205 modules require HOTPLUG functionality, but a module built
206 outside the kernel tree does. Such modules require Y here.
207
208config KOBJECT_UEVENT
209 bool "Kernel Userspace Events" if EMBEDDED
210 depends on NET
211 default y
212 help
213 This option enables the kernel userspace event layer, which is a
214 simple mechanism for kernel-to-user communication over a netlink
215 socket.
216 The goal of the kernel userspace events layer is to provide a simple
217 and efficient events system, that notifies userspace about kobject
218 state changes. This will enable applications to just listen for
219 events instead of polling system devices and files.
220 Hotplug events (kobject addition and removal) are also available on
221 the netlink socket in addition to the execution of /sbin/hotplug if
222 CONFIG_HOTPLUG is enabled.
223
224 Say Y, unless you are building a system requiring minimal memory
225 consumption.
226
227config IKCONFIG 200config IKCONFIG
228 bool "Kernel .config support" 201 bool "Kernel .config support"
229 ---help--- 202 ---help---
@@ -308,6 +281,15 @@ config KALLSYMS_EXTRA_PASS
308 you wait for kallsyms to be fixed. 281 you wait for kallsyms to be fixed.
309 282
310 283
284config HOTPLUG
285 bool "Support for hot-pluggable devices" if EMBEDDED
286 default y
287 help
288 This option is provided for the case where no hotplug or uevent
289 capabilities is wanted by the kernel. You should only consider
290 disabling this option for embedded systems that do not use modules, a
291 dynamic /dev tree, or dynamic device discovery. Just say Y.
292
311config PRINTK 293config PRINTK
312 default y 294 default y
313 bool "Enable support for printk" if EMBEDDED 295 bool "Enable support for printk" if EMBEDDED
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 015fb69ad94..99af8b05eea 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -15,6 +15,9 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17 17
18u64 uevent_seqnum;
19char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug";
20
18#define KERNEL_ATTR_RO(_name) \ 21#define KERNEL_ATTR_RO(_name) \
19static struct subsys_attribute _name##_attr = __ATTR_RO(_name) 22static struct subsys_attribute _name##_attr = __ATTR_RO(_name)
20 23
@@ -23,11 +26,29 @@ static struct subsys_attribute _name##_attr = \
23 __ATTR(_name, 0644, _name##_show, _name##_store) 26 __ATTR(_name, 0644, _name##_show, _name##_store)
24 27
25#ifdef CONFIG_HOTPLUG 28#ifdef CONFIG_HOTPLUG
26static ssize_t hotplug_seqnum_show(struct subsystem *subsys, char *page) 29/* current uevent sequence number */
30static ssize_t uevent_seqnum_show(struct subsystem *subsys, char *page)
31{
32 return sprintf(page, "%llu\n", (unsigned long long)uevent_seqnum);
33}
34KERNEL_ATTR_RO(uevent_seqnum);
35
36/* uevent helper program, used during early boo */
37static ssize_t uevent_helper_show(struct subsystem *subsys, char *page)
38{
39 return sprintf(page, "%s\n", uevent_helper);
40}
41static ssize_t uevent_helper_store(struct subsystem *subsys, const char *page, size_t count)
27{ 42{
28 return sprintf(page, "%llu\n", (unsigned long long)hotplug_seqnum); 43 if (count+1 > UEVENT_HELPER_PATH_LEN)
44 return -ENOENT;
45 memcpy(uevent_helper, page, count);
46 uevent_helper[count] = '\0';
47 if (count && uevent_helper[count-1] == '\n')
48 uevent_helper[count-1] = '\0';
49 return count;
29} 50}
30KERNEL_ATTR_RO(hotplug_seqnum); 51KERNEL_ATTR_RW(uevent_helper);
31#endif 52#endif
32 53
33#ifdef CONFIG_KEXEC 54#ifdef CONFIG_KEXEC
@@ -45,7 +66,8 @@ EXPORT_SYMBOL_GPL(kernel_subsys);
45 66
46static struct attribute * kernel_attrs[] = { 67static struct attribute * kernel_attrs[] = {
47#ifdef CONFIG_HOTPLUG 68#ifdef CONFIG_HOTPLUG
48 &hotplug_seqnum_attr.attr, 69 &uevent_seqnum_attr.attr,
70 &uevent_helper_attr.attr,
49#endif 71#endif
50#ifdef CONFIG_KEXEC 72#ifdef CONFIG_KEXEC
51 &crash_notes_attr.attr, 73 &crash_notes_attr.attr,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index b53115b882e..345f4a1d533 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -31,6 +31,7 @@
31#include <linux/smp_lock.h> 31#include <linux/smp_lock.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/kobject.h>
34#include <linux/net.h> 35#include <linux/net.h>
35#include <linux/sysrq.h> 36#include <linux/sysrq.h>
36#include <linux/highuid.h> 37#include <linux/highuid.h>
@@ -83,9 +84,6 @@ static int ngroups_max = NGROUPS_MAX;
83#ifdef CONFIG_KMOD 84#ifdef CONFIG_KMOD
84extern char modprobe_path[]; 85extern char modprobe_path[];
85#endif 86#endif
86#ifdef CONFIG_HOTPLUG
87extern char hotplug_path[];
88#endif
89#ifdef CONFIG_CHR_DEV_SG 87#ifdef CONFIG_CHR_DEV_SG
90extern int sg_big_buff; 88extern int sg_big_buff;
91#endif 89#endif
@@ -397,8 +395,8 @@ static ctl_table kern_table[] = {
397 { 395 {
398 .ctl_name = KERN_HOTPLUG, 396 .ctl_name = KERN_HOTPLUG,
399 .procname = "hotplug", 397 .procname = "hotplug",
400 .data = &hotplug_path, 398 .data = &uevent_helper,
401 .maxlen = HOTPLUG_PATH_LEN, 399 .maxlen = UEVENT_HELPER_PATH_LEN,
402 .mode = 0644, 400 .mode = 0644,
403 .proc_handler = &proc_dostring, 401 .proc_handler = &proc_dostring,
404 .strategy = &sysctl_string, 402 .strategy = &sysctl_string,
diff --git a/lib/klist.c b/lib/klist.c
index bb2f3551d50..9c94f0b163a 100644
--- a/lib/klist.c
+++ b/lib/klist.c
@@ -199,6 +199,8 @@ void klist_iter_init_node(struct klist * k, struct klist_iter * i, struct klist_
199 i->i_klist = k; 199 i->i_klist = k;
200 i->i_head = &k->k_list; 200 i->i_head = &k->k_list;
201 i->i_cur = n; 201 i->i_cur = n;
202 if (n)
203 kref_get(&n->n_ref);
202} 204}
203 205
204EXPORT_SYMBOL_GPL(klist_iter_init_node); 206EXPORT_SYMBOL_GPL(klist_iter_init_node);
diff --git a/lib/kobject.c b/lib/kobject.c
index a181abed89f..7a0e6809490 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -207,7 +207,7 @@ int kobject_register(struct kobject * kobj)
207 kobject_name(kobj),error); 207 kobject_name(kobj),error);
208 dump_stack(); 208 dump_stack();
209 } else 209 } else
210 kobject_hotplug(kobj, KOBJ_ADD); 210 kobject_uevent(kobj, KOBJ_ADD);
211 } else 211 } else
212 error = -EINVAL; 212 error = -EINVAL;
213 return error; 213 return error;
@@ -312,7 +312,7 @@ void kobject_del(struct kobject * kobj)
312void kobject_unregister(struct kobject * kobj) 312void kobject_unregister(struct kobject * kobj)
313{ 313{
314 pr_debug("kobject %s: unregistering\n",kobject_name(kobj)); 314 pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
315 kobject_hotplug(kobj, KOBJ_REMOVE); 315 kobject_uevent(kobj, KOBJ_REMOVE);
316 kobject_del(kobj); 316 kobject_del(kobj);
317 kobject_put(kobj); 317 kobject_put(kobj);
318} 318}
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 3ab375411e3..f56e27ae9d5 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -19,14 +19,16 @@
19#include <linux/skbuff.h> 19#include <linux/skbuff.h>
20#include <linux/netlink.h> 20#include <linux/netlink.h>
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/kobject_uevent.h>
23#include <linux/kobject.h> 22#include <linux/kobject.h>
24#include <net/sock.h> 23#include <net/sock.h>
25 24
26#define BUFFER_SIZE 1024 /* buffer for the hotplug env */ 25#define BUFFER_SIZE 1024 /* buffer for the variables */
27#define NUM_ENVP 32 /* number of env pointers */ 26#define NUM_ENVP 32 /* number of env pointers */
28 27
29#if defined(CONFIG_KOBJECT_UEVENT) || defined(CONFIG_HOTPLUG) 28#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
29static DEFINE_SPINLOCK(sequence_lock);
30static struct sock *uevent_sock;
31
30static char *action_to_string(enum kobject_action action) 32static char *action_to_string(enum kobject_action action)
31{ 33{
32 switch (action) { 34 switch (action) {
@@ -36,10 +38,6 @@ static char *action_to_string(enum kobject_action action)
36 return "remove"; 38 return "remove";
37 case KOBJ_CHANGE: 39 case KOBJ_CHANGE:
38 return "change"; 40 return "change";
39 case KOBJ_MOUNT:
40 return "mount";
41 case KOBJ_UMOUNT:
42 return "umount";
43 case KOBJ_OFFLINE: 41 case KOBJ_OFFLINE:
44 return "offline"; 42 return "offline";
45 case KOBJ_ONLINE: 43 case KOBJ_ONLINE:
@@ -48,306 +46,183 @@ static char *action_to_string(enum kobject_action action)
48 return NULL; 46 return NULL;
49 } 47 }
50} 48}
51#endif
52
53#ifdef CONFIG_KOBJECT_UEVENT
54static struct sock *uevent_sock;
55 49
56/** 50/**
57 * send_uevent - notify userspace by sending event through netlink socket 51 * kobject_uevent - notify userspace by ending an uevent
58 * 52 *
59 * @signal: signal name 53 * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE)
60 * @obj: object path (kobject)
61 * @envp: possible hotplug environment to pass with the message
62 * @gfp_mask:
63 */
64static int send_uevent(const char *signal, const char *obj,
65 char **envp, gfp_t gfp_mask)
66{
67 struct sk_buff *skb;
68 char *pos;
69 int len;
70
71 if (!uevent_sock)
72 return -EIO;
73
74 len = strlen(signal) + 1;
75 len += strlen(obj) + 1;
76
77 /* allocate buffer with the maximum possible message size */
78 skb = alloc_skb(len + BUFFER_SIZE, gfp_mask);
79 if (!skb)
80 return -ENOMEM;
81
82 pos = skb_put(skb, len);
83 sprintf(pos, "%s@%s", signal, obj);
84
85 /* copy the environment key by key to our continuous buffer */
86 if (envp) {
87 int i;
88
89 for (i = 2; envp[i]; i++) {
90 len = strlen(envp[i]) + 1;
91 pos = skb_put(skb, len);
92 strcpy(pos, envp[i]);
93 }
94 }
95
96 NETLINK_CB(skb).dst_group = 1;
97 return netlink_broadcast(uevent_sock, skb, 0, 1, gfp_mask);
98}
99
100static int do_kobject_uevent(struct kobject *kobj, enum kobject_action action,
101 struct attribute *attr, gfp_t gfp_mask)
102{
103 char *path;
104 char *attrpath;
105 char *signal;
106 int len;
107 int rc = -ENOMEM;
108
109 path = kobject_get_path(kobj, gfp_mask);
110 if (!path)
111 return -ENOMEM;
112
113 signal = action_to_string(action);
114 if (!signal)
115 return -EINVAL;
116
117 if (attr) {
118 len = strlen(path);
119 len += strlen(attr->name) + 2;
120 attrpath = kmalloc(len, gfp_mask);
121 if (!attrpath)
122 goto exit;
123 sprintf(attrpath, "%s/%s", path, attr->name);
124 rc = send_uevent(signal, attrpath, NULL, gfp_mask);
125 kfree(attrpath);
126 } else
127 rc = send_uevent(signal, path, NULL, gfp_mask);
128
129exit:
130 kfree(path);
131 return rc;
132}
133
134/**
135 * kobject_uevent - notify userspace by sending event through netlink socket
136 *
137 * @signal: signal name
138 * @kobj: struct kobject that the event is happening to
139 * @attr: optional struct attribute the event belongs to
140 */
141int kobject_uevent(struct kobject *kobj, enum kobject_action action,
142 struct attribute *attr)
143{
144 return do_kobject_uevent(kobj, action, attr, GFP_KERNEL);
145}
146EXPORT_SYMBOL_GPL(kobject_uevent);
147
148int kobject_uevent_atomic(struct kobject *kobj, enum kobject_action action,
149 struct attribute *attr)
150{
151 return do_kobject_uevent(kobj, action, attr, GFP_ATOMIC);
152}
153EXPORT_SYMBOL_GPL(kobject_uevent_atomic);
154
155static int __init kobject_uevent_init(void)
156{
157 uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL,
158 THIS_MODULE);
159
160 if (!uevent_sock) {
161 printk(KERN_ERR
162 "kobject_uevent: unable to create netlink socket!\n");
163 return -ENODEV;
164 }
165
166 return 0;
167}
168
169postcore_initcall(kobject_uevent_init);
170
171#else
172static inline int send_uevent(const char *signal, const char *obj,
173 char **envp, int gfp_mask)
174{
175 return 0;
176}
177
178#endif /* CONFIG_KOBJECT_UEVENT */
179
180
181#ifdef CONFIG_HOTPLUG
182char hotplug_path[HOTPLUG_PATH_LEN] = "/sbin/hotplug";
183u64 hotplug_seqnum;
184static DEFINE_SPINLOCK(sequence_lock);
185
186/**
187 * kobject_hotplug - notify userspace by executing /sbin/hotplug
188 *
189 * @action: action that is happening (usually "ADD" or "REMOVE")
190 * @kobj: struct kobject that the action is happening to 54 * @kobj: struct kobject that the action is happening to
191 */ 55 */
192void kobject_hotplug(struct kobject *kobj, enum kobject_action action) 56void kobject_uevent(struct kobject *kobj, enum kobject_action action)
193{ 57{
194 char *argv [3]; 58 char **envp;
195 char **envp = NULL; 59 char *buffer;
196 char *buffer = NULL;
197 char *seq_buff;
198 char *scratch; 60 char *scratch;
61 const char *action_string;
62 const char *devpath = NULL;
63 const char *subsystem;
64 struct kobject *top_kobj;
65 struct kset *kset;
66 struct kset_uevent_ops *uevent_ops;
67 u64 seq;
68 char *seq_buff;
199 int i = 0; 69 int i = 0;
200 int retval; 70 int retval;
201 char *kobj_path = NULL;
202 const char *name = NULL;
203 char *action_string;
204 u64 seq;
205 struct kobject *top_kobj = kobj;
206 struct kset *kset;
207 static struct kset_hotplug_ops null_hotplug_ops;
208 struct kset_hotplug_ops *hotplug_ops = &null_hotplug_ops;
209 71
210 /* If this kobj does not belong to a kset, 72 pr_debug("%s\n", __FUNCTION__);
211 try to find a parent that does. */ 73
74 action_string = action_to_string(action);
75 if (!action_string)
76 return;
77
78 /* search the kset we belong to */
79 top_kobj = kobj;
212 if (!top_kobj->kset && top_kobj->parent) { 80 if (!top_kobj->kset && top_kobj->parent) {
213 do { 81 do {
214 top_kobj = top_kobj->parent; 82 top_kobj = top_kobj->parent;
215 } while (!top_kobj->kset && top_kobj->parent); 83 } while (!top_kobj->kset && top_kobj->parent);
216 } 84 }
217 85 if (!top_kobj->kset)
218 if (top_kobj->kset)
219 kset = top_kobj->kset;
220 else
221 return; 86 return;
222 87
223 if (kset->hotplug_ops) 88 kset = top_kobj->kset;
224 hotplug_ops = kset->hotplug_ops; 89 uevent_ops = kset->uevent_ops;
225 90
226 /* If the kset has a filter operation, call it. 91 /* skip the event, if the filter returns zero. */
227 Skip the event, if the filter returns zero. */ 92 if (uevent_ops && uevent_ops->filter)
228 if (hotplug_ops->filter) { 93 if (!uevent_ops->filter(kset, kobj))
229 if (!hotplug_ops->filter(kset, kobj))
230 return; 94 return;
231 }
232 95
233 pr_debug ("%s\n", __FUNCTION__); 96 /* environment index */
234 97 envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
235 action_string = action_to_string(action);
236 if (!action_string)
237 return;
238
239 envp = kmalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
240 if (!envp) 98 if (!envp)
241 return; 99 return;
242 memset (envp, 0x00, NUM_ENVP * sizeof (char *));
243 100
101 /* environment values */
244 buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL); 102 buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
245 if (!buffer) 103 if (!buffer)
246 goto exit; 104 goto exit;
247 105
248 if (hotplug_ops->name) 106 /* complete object path */
249 name = hotplug_ops->name(kset, kobj); 107 devpath = kobject_get_path(kobj, GFP_KERNEL);
250 if (name == NULL) 108 if (!devpath)
251 name = kobject_name(&kset->kobj); 109 goto exit;
252 110
253 argv [0] = hotplug_path; 111 /* originating subsystem */
254 argv [1] = (char *)name; /* won't be changed but 'const' has to go */ 112 if (uevent_ops && uevent_ops->name)
255 argv [2] = NULL; 113 subsystem = uevent_ops->name(kset, kobj);
114 else
115 subsystem = kobject_name(&kset->kobj);
256 116
257 /* minimal command environment */ 117 /* event environemnt for helper process only */
258 envp [i++] = "HOME=/"; 118 envp[i++] = "HOME=/";
259 envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; 119 envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
260 120
121 /* default keys */
261 scratch = buffer; 122 scratch = buffer;
262
263 envp [i++] = scratch; 123 envp [i++] = scratch;
264 scratch += sprintf(scratch, "ACTION=%s", action_string) + 1; 124 scratch += sprintf(scratch, "ACTION=%s", action_string) + 1;
265
266 kobj_path = kobject_get_path(kobj, GFP_KERNEL);
267 if (!kobj_path)
268 goto exit;
269
270 envp [i++] = scratch; 125 envp [i++] = scratch;
271 scratch += sprintf (scratch, "DEVPATH=%s", kobj_path) + 1; 126 scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1;
272
273 envp [i++] = scratch; 127 envp [i++] = scratch;
274 scratch += sprintf(scratch, "SUBSYSTEM=%s", name) + 1; 128 scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1;
275 129
276 /* reserve space for the sequence, 130 /* just reserve the space, overwrite it after kset call has returned */
277 * put the real one in after the hotplug call */
278 envp[i++] = seq_buff = scratch; 131 envp[i++] = seq_buff = scratch;
279 scratch += strlen("SEQNUM=18446744073709551616") + 1; 132 scratch += strlen("SEQNUM=18446744073709551616") + 1;
280 133
281 if (hotplug_ops->hotplug) { 134 /* let the kset specific function add its stuff */
282 /* have the kset specific function add its stuff */ 135 if (uevent_ops && uevent_ops->uevent) {
283 retval = hotplug_ops->hotplug (kset, kobj, 136 retval = uevent_ops->uevent(kset, kobj,
284 &envp[i], NUM_ENVP - i, scratch, 137 &envp[i], NUM_ENVP - i, scratch,
285 BUFFER_SIZE - (scratch - buffer)); 138 BUFFER_SIZE - (scratch - buffer));
286 if (retval) { 139 if (retval) {
287 pr_debug ("%s - hotplug() returned %d\n", 140 pr_debug ("%s - uevent() returned %d\n",
288 __FUNCTION__, retval); 141 __FUNCTION__, retval);
289 goto exit; 142 goto exit;
290 } 143 }
291 } 144 }
292 145
146 /* we will send an event, request a new sequence number */
293 spin_lock(&sequence_lock); 147 spin_lock(&sequence_lock);
294 seq = ++hotplug_seqnum; 148 seq = ++uevent_seqnum;
295 spin_unlock(&sequence_lock); 149 spin_unlock(&sequence_lock);
296 sprintf(seq_buff, "SEQNUM=%llu", (unsigned long long)seq); 150 sprintf(seq_buff, "SEQNUM=%llu", (unsigned long long)seq);
297 151
298 pr_debug ("%s: %s %s seq=%llu %s %s %s %s %s\n", 152 /* send netlink message */
299 __FUNCTION__, argv[0], argv[1], (unsigned long long)seq, 153 if (uevent_sock) {
300 envp[0], envp[1], envp[2], envp[3], envp[4]); 154 struct sk_buff *skb;
301 155 size_t len;
302 send_uevent(action_string, kobj_path, envp, GFP_KERNEL); 156
157 /* allocate message with the maximum possible size */
158 len = strlen(action_string) + strlen(devpath) + 2;
159 skb = alloc_skb(len + BUFFER_SIZE, GFP_KERNEL);
160 if (skb) {
161 /* add header */
162 scratch = skb_put(skb, len);
163 sprintf(scratch, "%s@%s", action_string, devpath);
164
165 /* copy keys to our continuous event payload buffer */
166 for (i = 2; envp[i]; i++) {
167 len = strlen(envp[i]) + 1;
168 scratch = skb_put(skb, len);
169 strcpy(scratch, envp[i]);
170 }
171
172 NETLINK_CB(skb).dst_group = 1;
173 netlink_broadcast(uevent_sock, skb, 0, 1, GFP_KERNEL);
174 }
175 }
303 176
304 if (!hotplug_path[0]) 177 /* call uevent_helper, usually only enabled during early boot */
305 goto exit; 178 if (uevent_helper[0]) {
179 char *argv [3];
306 180
307 retval = call_usermodehelper (argv[0], argv, envp, 0); 181 argv [0] = uevent_helper;
308 if (retval) 182 argv [1] = (char *)subsystem;
309 pr_debug ("%s - call_usermodehelper returned %d\n", 183 argv [2] = NULL;
310 __FUNCTION__, retval); 184 call_usermodehelper (argv[0], argv, envp, 0);
185 }
311 186
312exit: 187exit:
313 kfree(kobj_path); 188 kfree(devpath);
314 kfree(buffer); 189 kfree(buffer);
315 kfree(envp); 190 kfree(envp);
316 return; 191 return;
317} 192}
318EXPORT_SYMBOL(kobject_hotplug); 193EXPORT_SYMBOL_GPL(kobject_uevent);
319 194
320/** 195/**
321 * add_hotplug_env_var - helper for creating hotplug environment variables 196 * add_uevent_var - helper for creating event variables
322 * @envp: Pointer to table of environment variables, as passed into 197 * @envp: Pointer to table of environment variables, as passed into
323 * hotplug() method. 198 * uevent() method.
324 * @num_envp: Number of environment variable slots available, as 199 * @num_envp: Number of environment variable slots available, as
325 * passed into hotplug() method. 200 * passed into uevent() method.
326 * @cur_index: Pointer to current index into @envp. It should be 201 * @cur_index: Pointer to current index into @envp. It should be
327 * initialized to 0 before the first call to add_hotplug_env_var(), 202 * initialized to 0 before the first call to add_uevent_var(),
328 * and will be incremented on success. 203 * and will be incremented on success.
329 * @buffer: Pointer to buffer for environment variables, as passed 204 * @buffer: Pointer to buffer for environment variables, as passed
330 * into hotplug() method. 205 * into uevent() method.
331 * @buffer_size: Length of @buffer, as passed into hotplug() method. 206 * @buffer_size: Length of @buffer, as passed into uevent() method.
332 * @cur_len: Pointer to current length of space used in @buffer. 207 * @cur_len: Pointer to current length of space used in @buffer.
333 * Should be initialized to 0 before the first call to 208 * Should be initialized to 0 before the first call to
334 * add_hotplug_env_var(), and will be incremented on success. 209 * add_uevent_var(), and will be incremented on success.
335 * @format: Format for creating environment variable (of the form 210 * @format: Format for creating environment variable (of the form
336 * "XXX=%x") for snprintf(). 211 * "XXX=%x") for snprintf().
337 * 212 *
338 * Returns 0 if environment variable was added successfully or -ENOMEM 213 * Returns 0 if environment variable was added successfully or -ENOMEM
339 * if no space was available. 214 * if no space was available.
340 */ 215 */
341int add_hotplug_env_var(char **envp, int num_envp, int *cur_index, 216int add_uevent_var(char **envp, int num_envp, int *cur_index,
342 char *buffer, int buffer_size, int *cur_len, 217 char *buffer, int buffer_size, int *cur_len,
343 const char *format, ...) 218 const char *format, ...)
344{ 219{
345 va_list args; 220 va_list args;
346 221
347 /* 222 /*
348 * We check against num_envp - 1 to make sure there is at 223 * We check against num_envp - 1 to make sure there is at
349 * least one slot left after we return, since the hotplug 224 * least one slot left after we return, since kobject_uevent()
350 * method needs to set the last slot to NULL. 225 * needs to set the last slot to NULL.
351 */ 226 */
352 if (*cur_index >= num_envp - 1) 227 if (*cur_index >= num_envp - 1)
353 return -ENOMEM; 228 return -ENOMEM;
@@ -366,6 +241,22 @@ int add_hotplug_env_var(char **envp, int num_envp, int *cur_index,
366 (*cur_index)++; 241 (*cur_index)++;
367 return 0; 242 return 0;
368} 243}
369EXPORT_SYMBOL(add_hotplug_env_var); 244EXPORT_SYMBOL_GPL(add_uevent_var);
245
246static int __init kobject_uevent_init(void)
247{
248 uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL,
249 THIS_MODULE);
250
251 if (!uevent_sock) {
252 printk(KERN_ERR
253 "kobject_uevent: unable to create netlink socket!\n");
254 return -ENODEV;
255 }
256
257 return 0;
258}
259
260postcore_initcall(kobject_uevent_init);
370 261
371#endif /* CONFIG_HOTPLUG */ 262#endif /* CONFIG_HOTPLUG */
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index bd7568ac87f..0ed38740388 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -78,7 +78,7 @@ static struct class_device_attribute *bt_attrs[] = {
78}; 78};
79 79
80#ifdef CONFIG_HOTPLUG 80#ifdef CONFIG_HOTPLUG
81static int bt_hotplug(struct class_device *cdev, char **envp, int num_envp, char *buf, int size) 81static int bt_uevent(struct class_device *cdev, char **envp, int num_envp, char *buf, int size)
82{ 82{
83 struct hci_dev *hdev = class_get_devdata(cdev); 83 struct hci_dev *hdev = class_get_devdata(cdev);
84 int n, i = 0; 84 int n, i = 0;
@@ -107,7 +107,7 @@ struct class bt_class = {
107 .name = "bluetooth", 107 .name = "bluetooth",
108 .release = bt_release, 108 .release = bt_release,
109#ifdef CONFIG_HOTPLUG 109#ifdef CONFIG_HOTPLUG
110 .hotplug = bt_hotplug, 110 .uevent = bt_uevent,
111#endif 111#endif
112}; 112};
113 113
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index f6a19d53eae..2ebdc23bbe2 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -248,7 +248,7 @@ int br_sysfs_addif(struct net_bridge_port *p)
248 if (err) 248 if (err)
249 goto out2; 249 goto out2;
250 250
251 kobject_hotplug(&p->kobj, KOBJ_ADD); 251 kobject_uevent(&p->kobj, KOBJ_ADD);
252 return 0; 252 return 0;
253 out2: 253 out2:
254 kobject_del(&p->kobj); 254 kobject_del(&p->kobj);
@@ -260,7 +260,7 @@ void br_sysfs_removeif(struct net_bridge_port *p)
260{ 260{
261 pr_debug("br_sysfs_removeif\n"); 261 pr_debug("br_sysfs_removeif\n");
262 sysfs_remove_link(&p->br->ifobj, p->dev->name); 262 sysfs_remove_link(&p->br->ifobj, p->dev->name);
263 kobject_hotplug(&p->kobj, KOBJ_REMOVE); 263 kobject_uevent(&p->kobj, KOBJ_REMOVE);
264 kobject_del(&p->kobj); 264 kobject_del(&p->kobj);
265} 265}
266 266
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index e2137f3e489..e1da81d261d 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -84,16 +84,11 @@ static ssize_t netdev_store(struct class_device *dev,
84 return ret; 84 return ret;
85} 85}
86 86
87/* generate a read-only network device class attribute */ 87NETDEVICE_SHOW(addr_len, fmt_dec);
88#define NETDEVICE_ATTR(field, format_string) \ 88NETDEVICE_SHOW(iflink, fmt_dec);
89NETDEVICE_SHOW(field, format_string) \ 89NETDEVICE_SHOW(ifindex, fmt_dec);
90static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) \ 90NETDEVICE_SHOW(features, fmt_long_hex);
91 91NETDEVICE_SHOW(type, fmt_dec);
92NETDEVICE_ATTR(addr_len, fmt_dec);
93NETDEVICE_ATTR(iflink, fmt_dec);
94NETDEVICE_ATTR(ifindex, fmt_dec);
95NETDEVICE_ATTR(features, fmt_long_hex);
96NETDEVICE_ATTR(type, fmt_dec);
97 92
98/* use same locking rules as GIFHWADDR ioctl's */ 93/* use same locking rules as GIFHWADDR ioctl's */
99static ssize_t format_addr(char *buf, const unsigned char *addr, int len) 94static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
@@ -136,10 +131,6 @@ static ssize_t show_carrier(struct class_device *dev, char *buf)
136 return -EINVAL; 131 return -EINVAL;
137} 132}
138 133
139static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
140static CLASS_DEVICE_ATTR(broadcast, S_IRUGO, show_broadcast, NULL);
141static CLASS_DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL);
142
143/* read-write attributes */ 134/* read-write attributes */
144NETDEVICE_SHOW(mtu, fmt_dec); 135NETDEVICE_SHOW(mtu, fmt_dec);
145 136
@@ -153,8 +144,6 @@ static ssize_t store_mtu(struct class_device *dev, const char *buf, size_t len)
153 return netdev_store(dev, buf, len, change_mtu); 144 return netdev_store(dev, buf, len, change_mtu);
154} 145}
155 146
156static CLASS_DEVICE_ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu);
157
158NETDEVICE_SHOW(flags, fmt_hex); 147NETDEVICE_SHOW(flags, fmt_hex);
159 148
160static int change_flags(struct net_device *net, unsigned long new_flags) 149static int change_flags(struct net_device *net, unsigned long new_flags)
@@ -167,8 +156,6 @@ static ssize_t store_flags(struct class_device *dev, const char *buf, size_t len
167 return netdev_store(dev, buf, len, change_flags); 156 return netdev_store(dev, buf, len, change_flags);
168} 157}
169 158
170static CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags);
171
172NETDEVICE_SHOW(tx_queue_len, fmt_ulong); 159NETDEVICE_SHOW(tx_queue_len, fmt_ulong);
173 160
174static int change_tx_queue_len(struct net_device *net, unsigned long new_len) 161static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
@@ -182,9 +169,6 @@ static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, siz
182 return netdev_store(dev, buf, len, change_tx_queue_len); 169 return netdev_store(dev, buf, len, change_tx_queue_len);
183} 170}
184 171
185static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
186 store_tx_queue_len);
187
188NETDEVICE_SHOW(weight, fmt_dec); 172NETDEVICE_SHOW(weight, fmt_dec);
189 173
190static int change_weight(struct net_device *net, unsigned long new_weight) 174static int change_weight(struct net_device *net, unsigned long new_weight)
@@ -198,24 +182,21 @@ static ssize_t store_weight(struct class_device *dev, const char *buf, size_t le
198 return netdev_store(dev, buf, len, change_weight); 182 return netdev_store(dev, buf, len, change_weight);
199} 183}
200 184
201static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight, 185static struct class_device_attribute net_class_attributes[] = {
202 store_weight); 186 __ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
203 187 __ATTR(iflink, S_IRUGO, show_iflink, NULL),
204 188 __ATTR(ifindex, S_IRUGO, show_ifindex, NULL),
205static struct class_device_attribute *net_class_attributes[] = { 189 __ATTR(features, S_IRUGO, show_features, NULL),
206 &class_device_attr_ifindex, 190 __ATTR(type, S_IRUGO, show_type, NULL),
207 &class_device_attr_iflink, 191 __ATTR(address, S_IRUGO, show_address, NULL),
208 &class_device_attr_addr_len, 192 __ATTR(broadcast, S_IRUGO, show_broadcast, NULL),
209 &class_device_attr_tx_queue_len, 193 __ATTR(carrier, S_IRUGO, show_carrier, NULL),
210 &class_device_attr_features, 194 __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu),
211 &class_device_attr_mtu, 195 __ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags),
212 &class_device_attr_flags, 196 __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
213 &class_device_attr_weight, 197 store_tx_queue_len),
214 &class_device_attr_type, 198 __ATTR(weight, S_IRUGO | S_IWUSR, show_weight, store_weight),
215 &class_device_attr_address, 199 {}
216 &class_device_attr_broadcast,
217 &class_device_attr_carrier,
218 NULL
219}; 200};
220 201
221/* Show a given an attribute in the statistics group */ 202/* Show a given an attribute in the statistics group */
@@ -369,14 +350,14 @@ static struct attribute_group wireless_group = {
369#endif 350#endif
370 351
371#ifdef CONFIG_HOTPLUG 352#ifdef CONFIG_HOTPLUG
372static int netdev_hotplug(struct class_device *cd, char **envp, 353static int netdev_uevent(struct class_device *cd, char **envp,
373 int num_envp, char *buf, int size) 354 int num_envp, char *buf, int size)
374{ 355{
375 struct net_device *dev = to_net_dev(cd); 356 struct net_device *dev = to_net_dev(cd);
376 int i = 0; 357 int i = 0;
377 int n; 358 int n;
378 359
379 /* pass interface in env to hotplug. */ 360 /* pass interface to uevent. */
380 envp[i++] = buf; 361 envp[i++] = buf;
381 n = snprintf(buf, size, "INTERFACE=%s", dev->name) + 1; 362 n = snprintf(buf, size, "INTERFACE=%s", dev->name) + 1;
382 buf += n; 363 buf += n;
@@ -407,8 +388,9 @@ static void netdev_release(struct class_device *cd)
407static struct class net_class = { 388static struct class net_class = {
408 .name = "net", 389 .name = "net",
409 .release = netdev_release, 390 .release = netdev_release,
391 .class_dev_attrs = net_class_attributes,
410#ifdef CONFIG_HOTPLUG 392#ifdef CONFIG_HOTPLUG
411 .hotplug = netdev_hotplug, 393 .uevent = netdev_uevent,
412#endif 394#endif
413}; 395};
414 396
@@ -431,8 +413,6 @@ void netdev_unregister_sysfs(struct net_device * net)
431int netdev_register_sysfs(struct net_device *net) 413int netdev_register_sysfs(struct net_device *net)
432{ 414{
433 struct class_device *class_dev = &(net->class_dev); 415 struct class_device *class_dev = &(net->class_dev);
434 int i;
435 struct class_device_attribute *attr;
436 int ret; 416 int ret;
437 417
438 class_dev->class = &net_class; 418 class_dev->class = &net_class;
@@ -442,12 +422,6 @@ int netdev_register_sysfs(struct net_device *net)
442 if ((ret = class_device_register(class_dev))) 422 if ((ret = class_device_register(class_dev)))
443 goto out; 423 goto out;
444 424
445 for (i = 0; (attr = net_class_attributes[i]) != NULL; i++) {
446 if ((ret = class_device_create_file(class_dev, attr)))
447 goto out_unreg;
448 }
449
450
451 if (net->get_stats && 425 if (net->get_stats &&
452 (ret = sysfs_create_group(&class_dev->kobj, &netstat_group))) 426 (ret = sysfs_create_group(&class_dev->kobj, &netstat_group)))
453 goto out_unreg; 427 goto out_unreg;
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index e3d144a3f10..e0eedffe565 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -16,8 +16,10 @@
16 * use either stdint.h or inttypes.h for the rest. */ 16 * use either stdint.h or inttypes.h for the rest. */
17#if KERNEL_ELFCLASS == ELFCLASS32 17#if KERNEL_ELFCLASS == ELFCLASS32
18typedef Elf32_Addr kernel_ulong_t; 18typedef Elf32_Addr kernel_ulong_t;
19#define BITS_PER_LONG 32
19#else 20#else
20typedef Elf64_Addr kernel_ulong_t; 21typedef Elf64_Addr kernel_ulong_t;
22#define BITS_PER_LONG 64
21#endif 23#endif
22#ifdef __sun__ 24#ifdef __sun__
23#include <inttypes.h> 25#include <inttypes.h>
@@ -35,6 +37,7 @@ typedef unsigned char __u8;
35 * even potentially has different endianness and word sizes, since 37 * even potentially has different endianness and word sizes, since
36 * we handle those differences explicitly below */ 38 * we handle those differences explicitly below */
37#include "../../include/linux/mod_devicetable.h" 39#include "../../include/linux/mod_devicetable.h"
40#include "../../include/linux/input.h"
38 41
39#define ADD(str, sep, cond, field) \ 42#define ADD(str, sep, cond, field) \
40do { \ 43do { \
@@ -366,6 +369,61 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *i2c, char *a
366 return 1; 369 return 1;
367} 370}
368 371
372#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
373
374static void do_input(char *alias,
375 kernel_ulong_t *arr, unsigned int min, unsigned int max)
376{
377 unsigned int i;
378 for (i = min; i < max; i++) {
379 if (arr[i/BITS_PER_LONG] & (1 << (i%BITS_PER_LONG)))
380 sprintf(alias+strlen(alias), "%X,*", i);
381 }
382}
383
384/* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */
385static int do_input_entry(const char *filename, struct input_device_id *id,
386 char *alias)
387{
388 sprintf(alias, "input:");
389
390 ADD(alias, "b", id->flags&INPUT_DEVICE_ID_MATCH_BUS, id->id.bustype);
391 ADD(alias, "v", id->flags&INPUT_DEVICE_ID_MATCH_VENDOR, id->id.vendor);
392 ADD(alias, "p", id->flags&INPUT_DEVICE_ID_MATCH_PRODUCT,
393 id->id.product);
394 ADD(alias, "e", id->flags&INPUT_DEVICE_ID_MATCH_VERSION,
395 id->id.version);
396
397 sprintf(alias + strlen(alias), "-e*");
398 if (id->flags&INPUT_DEVICE_ID_MATCH_EVBIT)
399 do_input(alias, id->evbit, 0, EV_MAX);
400 sprintf(alias + strlen(alias), "k*");
401 if (id->flags&INPUT_DEVICE_ID_MATCH_KEYBIT)
402 do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
403 sprintf(alias + strlen(alias), "r*");
404 if (id->flags&INPUT_DEVICE_ID_MATCH_RELBIT)
405 do_input(alias, id->relbit, 0, REL_MAX);
406 sprintf(alias + strlen(alias), "a*");
407 if (id->flags&INPUT_DEVICE_ID_MATCH_ABSBIT)
408 do_input(alias, id->absbit, 0, ABS_MAX);
409 sprintf(alias + strlen(alias), "m*");
410 if (id->flags&INPUT_DEVICE_ID_MATCH_MSCIT)
411 do_input(alias, id->mscbit, 0, MSC_MAX);
412 sprintf(alias + strlen(alias), "l*");
413 if (id->flags&INPUT_DEVICE_ID_MATCH_LEDBIT)
414 do_input(alias, id->ledbit, 0, LED_MAX);
415 sprintf(alias + strlen(alias), "s*");
416 if (id->flags&INPUT_DEVICE_ID_MATCH_SNDBIT)
417 do_input(alias, id->sndbit, 0, SND_MAX);
418 sprintf(alias + strlen(alias), "f*");
419 if (id->flags&INPUT_DEVICE_ID_MATCH_FFBIT)
420 do_input(alias, id->ffbit, 0, SND_MAX);
421 sprintf(alias + strlen(alias), "w*");
422 if (id->flags&INPUT_DEVICE_ID_MATCH_SWBIT)
423 do_input(alias, id->swbit, 0, SW_MAX);
424 return 1;
425}
426
369/* Ignore any prefix, eg. v850 prepends _ */ 427/* Ignore any prefix, eg. v850 prepends _ */
370static inline int sym_is(const char *symbol, const char *name) 428static inline int sym_is(const char *symbol, const char *name)
371{ 429{
@@ -453,7 +511,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
453 else if (sym_is(symname, "__mod_i2c_device_table")) 511 else if (sym_is(symname, "__mod_i2c_device_table"))
454 do_table(symval, sym->st_size, sizeof(struct i2c_device_id), 512 do_table(symval, sym->st_size, sizeof(struct i2c_device_id),
455 do_i2c_entry, mod); 513 do_i2c_entry, mod);
456 514 else if (sym_is(symname, "__mod_input_device_table"))
515 do_table(symval, sym->st_size, sizeof(struct input_device_id),
516 do_input_entry, mod);
457} 517}
458 518
459/* Now add out buffered information to the generated C source */ 519/* Now add out buffered information to the generated C source */