From 35061138b5286db84e16512da733d4202ef24e3c Mon Sep 17 00:00:00 2001 From: Patrick Mochel Date: Tue, 11 Mar 2003 04:00:30 -0600 Subject: [PATCH] driver model: add bus_rescan_devices() From Ben Collins Used as manual trigger for device/driver binding, so drivers can claim devices that are present but failed to be bound. In case of ieee1394, this can happen if two computers are attached to a device - the second one won't be able to claim it until the first detaches. Changed device_attach() to return 1 when a driver was bound to a device. Makes it so bus_rescan_devices() can return the number of devices attached. Tested this with ieee1394 over a bus reset and it worked as expected. --- drivers/base/bus.c | 41 ++++++++++++++++++++++++++++++++++++++--- include/linux/device.h | 2 ++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index d895085ea9da5..1e4a63e9d9f3f 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -282,23 +282,25 @@ static int bus_match(struct device * dev, struct device_driver * drv) * Walk the list of drivers that the bus has and call bus_match() * for each pair. If a compatible pair is found, break out and return. */ -static void device_attach(struct device * dev) +static int device_attach(struct device * dev) { struct bus_type * bus = dev->bus; struct list_head * entry; if (dev->driver) { device_bind_driver(dev); - return; + return 1; } if (bus->match) { list_for_each(entry,&bus->drivers.list) { struct device_driver * drv = to_drv(entry); if (!bus_match(dev,drv)) - break; + return 1; } } + + return 0; } @@ -476,6 +478,38 @@ void bus_remove_driver(struct device_driver * drv) } } + +/* Helper for bus_rescan_devices's iter */ +static int bus_rescan_devices_helper(struct device *dev, void *data) +{ + int *count = data; + + if (!dev->driver && device_attach(dev)) + (*count)++; + + return 0; +} + + +/** + * bus_rescan_devices - rescan devices on the bus for possible drivers + * @bus: the bus to scan. + * + * This function will look for devices on the bus with no driver + * attached and rescan it against existing drivers to see if it + * matches any. Calls device_attach(). Returns the number of devices + * that were sucessfully bound to a driver. + */ +int bus_rescan_devices(struct bus_type * bus) +{ + int count = 0; + + bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper); + + return count; +} + + struct bus_type * get_bus(struct bus_type * bus) { return bus ? container_of(subsys_get(&bus->subsys),struct bus_type,subsys) : NULL; @@ -560,6 +594,7 @@ EXPORT_SYMBOL(bus_add_device); EXPORT_SYMBOL(bus_remove_device); EXPORT_SYMBOL(bus_register); EXPORT_SYMBOL(bus_unregister); +EXPORT_SYMBOL(bus_rescan_devices); EXPORT_SYMBOL(get_bus); EXPORT_SYMBOL(put_bus); EXPORT_SYMBOL(find_bus); diff --git a/include/linux/device.h b/include/linux/device.h index f059058eb3ac9..e27039ec22220 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -79,6 +79,8 @@ struct bus_type { extern int bus_register(struct bus_type * bus); extern void bus_unregister(struct bus_type * bus); +extern int bus_rescan_devices(struct bus_type * bus); + extern struct bus_type * get_bus(struct bus_type * bus); extern void put_bus(struct bus_type * bus); -- 2.53.0