diff options
author | Kay Sievers <kay.sievers@suse.de> | 2005-10-01 08:49:43 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-10-28 12:52:51 -0400 |
commit | a7fd67062efc5b0fc9a61368c607fa92d1d57f9e (patch) | |
tree | 8b91f198640608bd99f4e4764394e5134220abcf /drivers/base | |
parent | d8539d81aeee4dbdc0624a798321e822fb2df7ae (diff) |
[PATCH] add sysfs attr to re-emit device hotplug event
A "coldplug + udevstart" can be simple like this:
for i in /sys/block/*/*/uevent; do echo 1 > $i; done
for i in /sys/class/*/*/uevent; do echo 1 > $i; done
for i in /sys/bus/*/devices/*/uevent; do echo 1 > $i; done
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/class.c | 16 | ||||
-rw-r--r-- | drivers/base/core.c | 16 |
2 files changed, 30 insertions, 2 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c index 73d44cf53db0..3cf6eb36f3d8 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -442,6 +442,13 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf) | |||
442 | return print_dev_t(buf, class_dev->devt); | 442 | return print_dev_t(buf, class_dev->devt); |
443 | } | 443 | } |
444 | 444 | ||
445 | static ssize_t store_uevent(struct class_device *class_dev, | ||
446 | const char *buf, size_t count) | ||
447 | { | ||
448 | kobject_hotplug(&class_dev->kobj, KOBJ_ADD); | ||
449 | return count; | ||
450 | } | ||
451 | |||
445 | void class_device_initialize(struct class_device *class_dev) | 452 | void class_device_initialize(struct class_device *class_dev) |
446 | { | 453 | { |
447 | kobj_set_kset_s(class_dev, class_obj_subsys); | 454 | kobj_set_kset_s(class_dev, class_obj_subsys); |
@@ -497,6 +504,12 @@ int class_device_add(struct class_device *class_dev) | |||
497 | goto register_done; | 504 | goto register_done; |
498 | 505 | ||
499 | /* add the needed attributes to this device */ | 506 | /* add the needed attributes to this device */ |
507 | class_dev->uevent_attr.attr.name = "uevent"; | ||
508 | class_dev->uevent_attr.attr.mode = S_IWUSR; | ||
509 | class_dev->uevent_attr.attr.owner = parent->owner; | ||
510 | class_dev->uevent_attr.store = store_uevent; | ||
511 | class_device_create_file(class_dev, &class_dev->uevent_attr); | ||
512 | |||
500 | if (MAJOR(class_dev->devt)) { | 513 | if (MAJOR(class_dev->devt)) { |
501 | struct class_device_attribute *attr; | 514 | struct class_device_attribute *attr; |
502 | attr = kzalloc(sizeof(*attr), GFP_KERNEL); | 515 | attr = kzalloc(sizeof(*attr), GFP_KERNEL); |
@@ -505,12 +518,10 @@ int class_device_add(struct class_device *class_dev) | |||
505 | kobject_del(&class_dev->kobj); | 518 | kobject_del(&class_dev->kobj); |
506 | goto register_done; | 519 | goto register_done; |
507 | } | 520 | } |
508 | |||
509 | attr->attr.name = "dev"; | 521 | attr->attr.name = "dev"; |
510 | attr->attr.mode = S_IRUGO; | 522 | attr->attr.mode = S_IRUGO; |
511 | attr->attr.owner = parent->owner; | 523 | attr->attr.owner = parent->owner; |
512 | attr->show = show_dev; | 524 | attr->show = show_dev; |
513 | attr->store = NULL; | ||
514 | class_device_create_file(class_dev, attr); | 525 | class_device_create_file(class_dev, attr); |
515 | class_dev->devt_attr = attr; | 526 | class_dev->devt_attr = attr; |
516 | } | 527 | } |
@@ -621,6 +632,7 @@ void class_device_del(struct class_device *class_dev) | |||
621 | sysfs_remove_link(&class_dev->kobj, "device"); | 632 | sysfs_remove_link(&class_dev->kobj, "device"); |
622 | sysfs_remove_link(&class_dev->dev->kobj, class_name); | 633 | sysfs_remove_link(&class_dev->dev->kobj, class_name); |
623 | } | 634 | } |
635 | class_device_remove_file(class_dev, &class_dev->uevent_attr); | ||
624 | if (class_dev->devt_attr) | 636 | if (class_dev->devt_attr) |
625 | class_device_remove_file(class_dev, class_dev->devt_attr); | 637 | class_device_remove_file(class_dev, class_dev->devt_attr); |
626 | class_device_remove_attrs(class_dev); | 638 | class_device_remove_attrs(class_dev); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 31109193e2c4..ac4b5fdd95f5 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -154,6 +154,13 @@ static struct kset_hotplug_ops device_hotplug_ops = { | |||
154 | .hotplug = dev_hotplug, | 154 | .hotplug = dev_hotplug, |
155 | }; | 155 | }; |
156 | 156 | ||
157 | static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | ||
158 | const char *buf, size_t count) | ||
159 | { | ||
160 | kobject_hotplug(&dev->kobj, KOBJ_ADD); | ||
161 | return count; | ||
162 | } | ||
163 | |||
157 | /** | 164 | /** |
158 | * device_subsys - structure to be registered with kobject core. | 165 | * device_subsys - structure to be registered with kobject core. |
159 | */ | 166 | */ |
@@ -259,6 +266,14 @@ int device_add(struct device *dev) | |||
259 | 266 | ||
260 | if ((error = kobject_add(&dev->kobj))) | 267 | if ((error = kobject_add(&dev->kobj))) |
261 | goto Error; | 268 | goto Error; |
269 | |||
270 | dev->uevent_attr.attr.name = "uevent"; | ||
271 | dev->uevent_attr.attr.mode = S_IWUSR; | ||
272 | if (dev->driver) | ||
273 | dev->uevent_attr.attr.owner = dev->driver->owner; | ||
274 | dev->uevent_attr.store = store_uevent; | ||
275 | device_create_file(dev, &dev->uevent_attr); | ||
276 | |||
262 | kobject_hotplug(&dev->kobj, KOBJ_ADD); | 277 | kobject_hotplug(&dev->kobj, KOBJ_ADD); |
263 | if ((error = device_pm_add(dev))) | 278 | if ((error = device_pm_add(dev))) |
264 | goto PMError; | 279 | goto PMError; |
@@ -350,6 +365,7 @@ void device_del(struct device * dev) | |||
350 | 365 | ||
351 | if (parent) | 366 | if (parent) |
352 | klist_del(&dev->knode_parent); | 367 | klist_del(&dev->knode_parent); |
368 | device_remove_file(dev, &dev->uevent_attr); | ||
353 | 369 | ||
354 | /* Notify the platform of the removal, in case they | 370 | /* Notify the platform of the removal, in case they |
355 | * need to do anything... | 371 | * need to do anything... |