]> err.no Git - linux-2.6/blobdiff - drivers/base/bus.c
[PATCH] Adapt scripts/ver_linux to new util-linux version strings
[linux-2.6] / drivers / base / bus.c
index fa41ee90a53a03b9de7ef95e539759eabcd6fa62..17e96698410e43c47464fb6d509cf082b0a0a724 100644 (file)
@@ -156,10 +156,38 @@ static ssize_t driver_unbind(struct device_driver *drv,
                device_release_driver(dev);
                err = count;
        }
-       return err;
+       if (err)
+               return err;
+       return count;
 }
 static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
 
+/*
+ * Manually attach a device to a driver.
+ * Note: the driver must want to bind to the device,
+ * it is not possible to override the driver's id table.
+ */
+static ssize_t driver_bind(struct device_driver *drv,
+                          const char *buf, size_t count)
+{
+       struct bus_type *bus = get_bus(drv->bus);
+       struct device *dev;
+       int err = -ENODEV;
+
+       dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
+       if ((dev) &&
+           (dev->driver == NULL)) {
+               down(&dev->sem);
+               err = driver_probe_device(drv, dev);
+               up(&dev->sem);
+               put_device(dev);
+       }
+       if (err)
+               return err;
+       return count;
+}
+static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
+
 
 static struct device * next_device(struct klist_iter * i)
 {
@@ -332,7 +360,7 @@ int bus_add_device(struct device * dev)
        if (bus) {
                pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
                device_attach(dev);
-               klist_add_tail(&bus->klist_devices, &dev->knode_bus);
+               klist_add_tail(&dev->knode_bus, &bus->klist_devices);
                error = device_add_attrs(bus, dev);
                if (!error) {
                        sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
@@ -420,11 +448,12 @@ int bus_add_driver(struct device_driver * drv)
                }
 
                driver_attach(drv);
-               klist_add_tail(&bus->klist_drivers, &drv->knode_bus);
+               klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
                module_add_driver(drv->owner, drv);
 
                driver_add_attrs(bus, drv);
                driver_create_file(drv, &driver_attr_unbind);
+               driver_create_file(drv, &driver_attr_bind);
        }
        return error;
 }
@@ -442,6 +471,7 @@ int bus_add_driver(struct device_driver * drv)
 void bus_remove_driver(struct device_driver * drv)
 {
        if (drv->bus) {
+               driver_remove_file(drv, &driver_attr_bind);
                driver_remove_file(drv, &driver_attr_unbind);
                driver_remove_attrs(drv->bus, drv);
                klist_remove(&drv->knode_bus);
@@ -457,31 +487,22 @@ 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) > 0))
-               (*count)++;
-
+       if (!dev->driver)
+               device_attach(dev);
        return 0;
 }
 
-
 /**
- *     bus_rescan_devices - rescan devices on the bus for possible drivers
- *     @bus:   the bus to scan.
+ * 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.
+ * 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 by calling device_attach() for the unbound devices.
  */
-int bus_rescan_devices(struct bus_type * bus)
+void bus_rescan_devices(struct bus_type * bus)
 {
-       int count = 0;
-
-       bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
-
-       return count;
+       bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper);
 }