Commit 2287c322 authored by mochel@digitalimplant.org's avatar mochel@digitalimplant.org Committed by Greg Kroah-Hartman

[PATCH] Use bus_for_each_{dev,drv} for driver binding.

- Now possible, since the lists are locked using the klist lock and not the
  global rwsem.
Signed-off-by: default avatarPatrick Mochel <mochel@digitalimplant.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent cb85b6f1
...@@ -82,6 +82,28 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) ...@@ -82,6 +82,28 @@ int driver_probe_device(struct device_driver * drv, struct device * dev)
return 0; return 0;
} }
static int __device_attach(struct device_driver * drv, void * data)
{
struct device * dev = data;
int error;
error = driver_probe_device(drv, dev);
if (error == -ENODEV && error == -ENXIO) {
/* Driver matched, but didn't support device
* or device not found.
* Not an error; keep going.
*/
error = 0;
} else {
/* driver matched but the probe failed */
printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
drv->name, dev->bus_id, error);
}
return 0;
}
/** /**
* device_attach - try to attach device to a driver. * device_attach - try to attach device to a driver.
* @dev: device. * @dev: device.
...@@ -92,30 +114,31 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) ...@@ -92,30 +114,31 @@ int driver_probe_device(struct device_driver * drv, struct device * dev)
*/ */
int device_attach(struct device * dev) int device_attach(struct device * dev)
{ {
struct bus_type * bus = dev->bus;
struct list_head * entry;
int error;
if (dev->driver) { if (dev->driver) {
device_bind_driver(dev); device_bind_driver(dev);
return 1; return 1;
} }
if (bus->match) { return bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
list_for_each(entry, &bus->drivers.list) { }
struct device_driver * drv = to_drv(entry);
error = driver_probe_device(drv, dev); static int __driver_attach(struct device * dev, void * data)
if (!error) {
/* success, driver matched */ struct device_driver * drv = data;
return 1; int error = 0;
if (error != -ENODEV && error != -ENXIO)
if (!dev->driver) {
error = driver_probe_device(drv, dev);
if (error) {
if (error != -ENODEV) {
/* driver matched but the probe failed */ /* driver matched but the probe failed */
printk(KERN_WARNING printk(KERN_WARNING
"%s: probe of %s failed with error %d\n", "%s: probe of %s failed with error %d\n",
drv->name, dev->bus_id, error); drv->name, dev->bus_id, error);
} else
error = 0;
} }
} }
return 0; return 0;
} }
...@@ -133,24 +156,7 @@ int device_attach(struct device * dev) ...@@ -133,24 +156,7 @@ int device_attach(struct device * dev)
*/ */
void driver_attach(struct device_driver * drv) void driver_attach(struct device_driver * drv)
{ {
struct bus_type * bus = drv->bus; bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
struct list_head * entry;
int error;
if (!bus->match)
return;
list_for_each(entry, &bus->devices.list) {
struct device * dev = container_of(entry, struct device, bus_list);
if (!dev->driver) {
error = driver_probe_device(drv, dev);
if (error && (error != -ENODEV))
/* driver matched but the probe failed */
printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
drv->name, dev->bus_id, error);
}
}
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment