--- ./lib/kobject.c.orig 2004-06-17 09:18:27.000000000 +0200 +++ ./lib/kobject.c 2004-06-17 12:59:55.000000000 +0200 @@ -472,6 +472,53 @@ kobject_cleanup(kobj); } +static int kobject_hotplug_filter_all(struct kset *kset, struct kobject *kobj) +{ + return 0; +} + +/** + * kobject_disable_events - filter out all hotplug events + * @kobj: object + * + */ + +void kobject_disable_events(struct kobject * kobj ) +{ + struct kset_hotplug_ops *delayed_ops; + + if (kobj && kobj->kset) { + down_write(&kobj->kset->subsys->rwsem); + + delayed_ops = kobj->kset->hotplug_ops; + kobj->kset->hotplug_ops_stored = delayed_ops; + + delayed_ops->filter = kobject_hotplug_filter_all; + kobj->kset->hotplug_ops = delayed_ops; + + up_write(&kobj->kset->subsys->rwsem); + } +} + +/** + * kobject_enable_events - reset hotplug filter to original value + * @kobj: object + * + */ + +void kobject_enable_events(struct kobject * kobj ) +{ + struct kset_hotplug_ops *delayed_ops; + + if (kobj && kobj->kset && kobj->kset->hotplug_ops_stored) { + down_write(&kobj->kset->subsys->rwsem); + + kobj->kset->hotplug_ops = kobj->kset->hotplug_ops_stored; + kobj->kset->hotplug_ops_stored = NULL; + + up_write(&kobj->kset->subsys->rwsem); + } +} /** * kset_init - initialize a kset for use @@ -635,6 +682,8 @@ EXPORT_SYMBOL(kobject_del); EXPORT_SYMBOL(kobject_rename); EXPORT_SYMBOL(kobject_hotplug); +EXPORT_SYMBOL(kobject_enable_events); +EXPORT_SYMBOL(kobject_disable_events); EXPORT_SYMBOL(kset_register); EXPORT_SYMBOL(kset_unregister); --- ./drivers/base/core.c.orig 2004-06-17 09:03:58.000000000 +0200 +++ ./drivers/base/core.c 2004-06-17 13:06:29.581368704 +0200 @@ -271,6 +271,25 @@ return device_add(dev); } +void device_suspend_hotplug(struct device *dev) +{ + get_device(dev); + + kobject_disable_events(&dev->kobj); + + put_device(dev); +} + +void device_resume_hotplug(struct device *dev) +{ + get_device(dev); + + kobject_enable_events(&dev->kobj); + + kobject_hotplug("add", &dev->kobj); + + put_device(dev); +} /** * get_device - increment reference count for device. @@ -405,3 +424,5 @@ EXPORT_SYMBOL(device_create_file); EXPORT_SYMBOL(device_remove_file); +EXPORT_SYMBOL(device_suspend_hotplug); +EXPORT_SYMBOL(device_resume_hotplug); --- ./drivers/scsi/scsi_sysfs.c.orig 2004-06-17 13:00:45.000000000 +0200 +++ ./drivers/scsi/scsi_sysfs.c 2004-06-17 13:03:13.071318353 +0200 @@ -379,6 +379,7 @@ if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0) return error; + device_suspend_hotplug(&sdev->sdev_gendev); error = device_add(&sdev->sdev_gendev); if (error) { printk(KERN_INFO "error 1\n"); @@ -439,6 +440,8 @@ } } + device_resume_hotplug(&sdev->sdev_gendev); + out: return error; --- ./include/linux/kobject.h.orig 2004-06-17 11:22:29.000000000 +0200 +++ ./include/linux/kobject.h 2004-06-17 12:55:06.000000000 +0200 @@ -47,6 +47,8 @@ extern int kobject_add(struct kobject *); extern void kobject_del(struct kobject *); +extern void kobject_enable_events(struct kobject *kobj); +extern void kobject_disable_events(struct kobject *kobj); extern int kobject_rename(struct kobject *, char *new_name); @@ -96,6 +98,7 @@ struct list_head list; struct kobject kobj; struct kset_hotplug_ops * hotplug_ops; + struct kset_hotplug_ops * hotplug_ops_stored; }; --- ./include/linux/device.h.orig 2004-06-17 12:14:21.000000000 +0200 +++ ./include/linux/device.h 2004-06-17 12:14:56.000000000 +0200 @@ -332,6 +332,8 @@ extern void device_bind_driver(struct device * dev); extern void device_release_driver(struct device * dev); extern void driver_attach(struct device_driver * drv); +extern void device_suspend_hotplug(struct device *dev); +extern void device_resume_hotplug(struct device *dev); /* driverfs interface for exporting device attributes */