diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2009-07-30 15:27:18 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-15 12:50:46 -0400 |
commit | 2023c610dc54a4f4130b0494309a9bd668ca3df8 (patch) | |
tree | 2ffc4b19491df0f6131905d22bbb05c517a8c24c | |
parent | 18240904960a39e582ced8ba8ececb10b8c22dd3 (diff) |
Driver core: add new device to bus's list before probing
This patch (as1271) affects when new devices get linked into their
bus's list of devices. Currently this happens after probing, and it
doesn't happen at all if probing fails. Clearly this is wrong,
because at that point quite a few symbolic links have already been
created in sysfs. We are committed to adding the device, so it should
be linked into the bus's list regardless.
In addition, this needs to happen before the uevent announcing the new
device gets issued. Otherwise user programs might try to access the
device before it has been added to the bus.
To fix both these problems, the patch moves the call to
klist_add_tail() forward from bus_attach_device() to bus_add_device().
Since bus_attach_device() now does nothing but probe for drivers, it
has been renamed to bus_probe_device(). And lastly, the kerneldoc is
updated.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/base/base.h | 2 | ||||
-rw-r--r-- | drivers/base/bus.c | 23 | ||||
-rw-r--r-- | drivers/base/core.c | 2 |
3 files changed, 12 insertions, 15 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h index b528145a078f..1e52c125f437 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -104,7 +104,7 @@ extern int system_bus_init(void); | |||
104 | extern int cpu_dev_init(void); | 104 | extern int cpu_dev_init(void); |
105 | 105 | ||
106 | extern int bus_add_device(struct device *dev); | 106 | extern int bus_add_device(struct device *dev); |
107 | extern void bus_attach_device(struct device *dev); | 107 | extern void bus_probe_device(struct device *dev); |
108 | extern void bus_remove_device(struct device *dev); | 108 | extern void bus_remove_device(struct device *dev); |
109 | 109 | ||
110 | extern int bus_add_driver(struct device_driver *drv); | 110 | extern int bus_add_driver(struct device_driver *drv); |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 4b04a15146d7..973bf2ad4e0d 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -459,8 +459,9 @@ static inline void remove_deprecated_bus_links(struct device *dev) { } | |||
459 | * bus_add_device - add device to bus | 459 | * bus_add_device - add device to bus |
460 | * @dev: device being added | 460 | * @dev: device being added |
461 | * | 461 | * |
462 | * - Add device's bus attributes. | ||
463 | * - Create links to device's bus. | ||
462 | * - Add the device to its bus's list of devices. | 464 | * - Add the device to its bus's list of devices. |
463 | * - Create link to device's bus. | ||
464 | */ | 465 | */ |
465 | int bus_add_device(struct device *dev) | 466 | int bus_add_device(struct device *dev) |
466 | { | 467 | { |
@@ -483,6 +484,7 @@ int bus_add_device(struct device *dev) | |||
483 | error = make_deprecated_bus_links(dev); | 484 | error = make_deprecated_bus_links(dev); |
484 | if (error) | 485 | if (error) |
485 | goto out_deprecated; | 486 | goto out_deprecated; |
487 | klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices); | ||
486 | } | 488 | } |
487 | return 0; | 489 | return 0; |
488 | 490 | ||
@@ -498,24 +500,19 @@ out_put: | |||
498 | } | 500 | } |
499 | 501 | ||
500 | /** | 502 | /** |
501 | * bus_attach_device - add device to bus | 503 | * bus_probe_device - probe drivers for a new device |
502 | * @dev: device tried to attach to a driver | 504 | * @dev: device to probe |
503 | * | 505 | * |
504 | * - Add device to bus's list of devices. | 506 | * - Automatically probe for a driver if the bus allows it. |
505 | * - Try to attach to driver. | ||
506 | */ | 507 | */ |
507 | void bus_attach_device(struct device *dev) | 508 | void bus_probe_device(struct device *dev) |
508 | { | 509 | { |
509 | struct bus_type *bus = dev->bus; | 510 | struct bus_type *bus = dev->bus; |
510 | int ret = 0; | 511 | int ret; |
511 | 512 | ||
512 | if (bus) { | 513 | if (bus && bus->p->drivers_autoprobe) { |
513 | if (bus->p->drivers_autoprobe) | 514 | ret = device_attach(dev); |
514 | ret = device_attach(dev); | ||
515 | WARN_ON(ret < 0); | 515 | WARN_ON(ret < 0); |
516 | if (ret >= 0) | ||
517 | klist_add_tail(&dev->p->knode_bus, | ||
518 | &bus->p->klist_devices); | ||
519 | } | 516 | } |
520 | } | 517 | } |
521 | 518 | ||
diff --git a/drivers/base/core.c b/drivers/base/core.c index 7ecb1938e590..c34774d0b9d3 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -945,7 +945,7 @@ int device_add(struct device *dev) | |||
945 | BUS_NOTIFY_ADD_DEVICE, dev); | 945 | BUS_NOTIFY_ADD_DEVICE, dev); |
946 | 946 | ||
947 | kobject_uevent(&dev->kobj, KOBJ_ADD); | 947 | kobject_uevent(&dev->kobj, KOBJ_ADD); |
948 | bus_attach_device(dev); | 948 | bus_probe_device(dev); |
949 | if (parent) | 949 | if (parent) |
950 | klist_add_tail(&dev->p->knode_parent, | 950 | klist_add_tail(&dev->p->knode_parent, |
951 | &parent->p->klist_children); | 951 | &parent->p->klist_children); |