]> git.hungrycats.org Git - linux/commitdiff
driver model: add bus_rescan_devices()
authorPatrick Mochel <mochel@osdl.org>
Tue, 11 Mar 2003 10:00:30 +0000 (04:00 -0600)
committerPatrick Mochel <mochel@osdl.org>
Tue, 11 Mar 2003 10:00:30 +0000 (04:00 -0600)
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
include/linux/device.h

index d895085ea9da523e78f6699c020d797b87b86442..1e4a63e9d9f3f8d635b97999ad9a149c928a5219 100644 (file)
@@ -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);
index f059058eb3ac9af490fe838126d993f69182af80..e27039ec22220a25ff7940ef2075496a8cb8b99c 100644 (file)
@@ -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);