driver core: Probe devices asynchronously instead of the driver
[sfrench/cifs-2.6.git] / drivers / base / bus.c
index 8bfd27ec73d60d1d18a43f9bfcff29b4eb9a50a6..0a58e969f8b7c27c1c956004f7d036b6e7b8def5 100644 (file)
@@ -31,6 +31,9 @@ static struct kset *system_kset;
 
 #define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr)
 
+#define DRIVER_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \
+       struct driver_attribute driver_attr_##_name =           \
+               __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)
 
 static int __must_check bus_rescan_devices_helper(struct device *dev,
                                                void *data);
@@ -184,18 +187,14 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf,
 
        dev = bus_find_device_by_name(bus, NULL, buf);
        if (dev && dev->driver == drv) {
-               if (dev->parent && dev->bus->need_parent_lock)
-                       device_lock(dev->parent);
-               device_release_driver(dev);
-               if (dev->parent && dev->bus->need_parent_lock)
-                       device_unlock(dev->parent);
+               device_driver_detach(dev);
                err = count;
        }
        put_device(dev);
        bus_put(bus);
        return err;
 }
-static DRIVER_ATTR_WO(unbind);
+static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, S_IWUSR, NULL, unbind_store);
 
 /*
  * Manually attach a device to a driver.
@@ -211,13 +210,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf,
 
        dev = bus_find_device_by_name(bus, NULL, buf);
        if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
-               if (dev->parent && bus->need_parent_lock)
-                       device_lock(dev->parent);
-               device_lock(dev);
-               err = driver_probe_device(drv, dev);
-               device_unlock(dev);
-               if (dev->parent && bus->need_parent_lock)
-                       device_unlock(dev->parent);
+               err = device_driver_attach(drv, dev);
 
                if (err > 0) {
                        /* success */
@@ -231,14 +224,14 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf,
        bus_put(bus);
        return err;
 }
-static DRIVER_ATTR_WO(bind);
+static DRIVER_ATTR_IGNORE_LOCKDEP(bind, S_IWUSR, NULL, bind_store);
 
-static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)
+static ssize_t drivers_autoprobe_show(struct bus_type *bus, char *buf)
 {
        return sprintf(buf, "%d\n", bus->p->drivers_autoprobe);
 }
 
-static ssize_t store_drivers_autoprobe(struct bus_type *bus,
+static ssize_t drivers_autoprobe_store(struct bus_type *bus,
                                       const char *buf, size_t count)
 {
        if (buf[0] == '0')
@@ -248,7 +241,7 @@ static ssize_t store_drivers_autoprobe(struct bus_type *bus,
        return count;
 }
 
-static ssize_t store_drivers_probe(struct bus_type *bus,
+static ssize_t drivers_probe_store(struct bus_type *bus,
                                   const char *buf, size_t count)
 {
        struct device *dev;
@@ -583,9 +576,8 @@ static void remove_bind_files(struct device_driver *drv)
        driver_remove_file(drv, &driver_attr_unbind);
 }
 
-static BUS_ATTR(drivers_probe, S_IWUSR, NULL, store_drivers_probe);
-static BUS_ATTR(drivers_autoprobe, S_IWUSR | S_IRUGO,
-               show_drivers_autoprobe, store_drivers_autoprobe);
+static BUS_ATTR_WO(drivers_probe);
+static BUS_ATTR_RW(drivers_autoprobe);
 
 static int add_probe_files(struct bus_type *bus)
 {
@@ -611,21 +603,12 @@ static void remove_probe_files(struct bus_type *bus)
 static ssize_t uevent_store(struct device_driver *drv, const char *buf,
                            size_t count)
 {
-       kobject_synth_uevent(&drv->p->kobj, buf, count);
-       return count;
-}
-static DRIVER_ATTR_WO(uevent);
-
-static void driver_attach_async(void *_drv, async_cookie_t cookie)
-{
-       struct device_driver *drv = _drv;
-       int ret;
-
-       ret = driver_attach(drv);
+       int rc;
 
-       pr_debug("bus: '%s': driver %s async attach completed: %d\n",
-                drv->bus->name, drv->name, ret);
+       rc = kobject_synth_uevent(&drv->p->kobj, buf, count);
+       return rc ? rc : count;
 }
+static DRIVER_ATTR_WO(uevent);
 
 /**
  * bus_add_driver - Add a driver to the bus.
@@ -659,15 +642,9 @@ int bus_add_driver(struct device_driver *drv)
 
        klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
        if (drv->bus->p->drivers_autoprobe) {
-               if (driver_allows_async_probing(drv)) {
-                       pr_debug("bus: '%s': probing driver %s asynchronously\n",
-                               drv->bus->name, drv->name);
-                       async_schedule(driver_attach_async, drv);
-               } else {
-                       error = driver_attach(drv);
-                       if (error)
-                               goto out_unregister;
-               }
+               error = driver_attach(drv);
+               if (error)
+                       goto out_unregister;
        }
        module_add_driver(drv->owner, drv);
 
@@ -769,13 +746,8 @@ EXPORT_SYMBOL_GPL(bus_rescan_devices);
  */
 int device_reprobe(struct device *dev)
 {
-       if (dev->driver) {
-               if (dev->parent && dev->bus->need_parent_lock)
-                       device_lock(dev->parent);
-               device_release_driver(dev);
-               if (dev->parent && dev->bus->need_parent_lock)
-                       device_unlock(dev->parent);
-       }
+       if (dev->driver)
+               device_driver_detach(dev);
        return bus_rescan_devices_helper(dev, NULL);
 }
 EXPORT_SYMBOL_GPL(device_reprobe);
@@ -828,10 +800,19 @@ static void klist_devices_put(struct klist_node *n)
 static ssize_t bus_uevent_store(struct bus_type *bus,
                                const char *buf, size_t count)
 {
-       kobject_synth_uevent(&bus->p->subsys.kobj, buf, count);
-       return count;
+       int rc;
+
+       rc = kobject_synth_uevent(&bus->p->subsys.kobj, buf, count);
+       return rc ? rc : count;
 }
-static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
+/*
+ * "open code" the old BUS_ATTR() macro here.  We want to use BUS_ATTR_WO()
+ * here, but can not use it as earlier in the file we have
+ * DEVICE_ATTR_WO(uevent), which would cause a clash with the with the store
+ * function name.
+ */
+static struct bus_attribute bus_attr_uevent = __ATTR(uevent, S_IWUSR, NULL,
+                                                    bus_uevent_store);
 
 /**
  * bus_register - register a driver-core subsystem