- patches.apparmor/remove_suid_new_case_in_2.6.22.diff: Merge fix.
[linux-flexiantxendom0-3.2.10.git] / drivers / base / dd.c
index 6a48824..92428e5 100644 (file)
@@ -94,19 +94,11 @@ int device_bind_driver(struct device *dev)
        return ret;
 }
 
-struct stupid_thread_structure {
-       struct device_driver *drv;
-       struct device *dev;
-};
-
 static atomic_t probe_count = ATOMIC_INIT(0);
 static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue);
 
-static int really_probe(void *void_data)
+static int really_probe(struct device *dev, struct device_driver *drv)
 {
-       struct stupid_thread_structure *data = void_data;
-       struct device_driver *drv = data->drv;
-       struct device *dev = data->dev;
        int ret = 0;
 
        atomic_inc(&probe_count);
@@ -154,7 +146,6 @@ probe_failed:
         */
        ret = 0;
 done:
-       kfree(data);
        atomic_dec(&probe_count);
        wake_up(&probe_waitqueue);
        return ret;
@@ -186,16 +177,14 @@ int driver_probe_done(void)
  * format of the ID structures, nor what is to be considered a match and
  * what is not.
  *
- * This function returns 1 if a match is found, an error if one occurs
- * (that is not -ENODEV or -ENXIO), and 0 otherwise.
+ * This function returns 1 if a match is found, -ENODEV if the device is
+ * not registered, and 0 otherwise.
  *
  * This function must be called with @dev->sem held.  When called for a
  * USB interface, @dev->parent->sem must be held as well.
  */
 int driver_probe_device(struct device_driver * drv, struct device * dev)
 {
-       struct stupid_thread_structure *data;
-       struct task_struct *probe_task;
        int ret = 0;
 
        if (!device_is_registered(dev))
@@ -206,19 +195,7 @@ int driver_probe_device(struct device_driver * drv, struct device * dev)
        pr_debug("%s: Matched Device %s with Driver %s\n",
                 drv->bus->name, dev->bus_id, drv->name);
 
-       data = kmalloc(sizeof(*data), GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-       data->drv = drv;
-       data->dev = dev;
-
-       if (drv->multithread_probe) {
-               probe_task = kthread_run(really_probe, data,
-                                        "probe-%s", dev->bus_id);
-               if (IS_ERR(probe_task))
-                       ret = really_probe(data);
-       } else
-               ret = really_probe(data);
+       ret = really_probe(dev, drv);
 
 done:
        return ret;
@@ -230,6 +207,19 @@ static int __device_attach(struct device_driver * drv, void * data)
        return driver_probe_device(drv, dev);
 }
 
+static int device_probe_drivers(void *data)
+{
+       struct device *dev = data;
+       int ret = 0;
+
+       if (dev->bus) {
+               down(&dev->sem);
+               ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
+               up(&dev->sem);
+       }
+       return ret;
+}
+
 /**
  *     device_attach - try to attach device to a driver.
  *     @dev:   device.
@@ -239,7 +229,8 @@ static int __device_attach(struct device_driver * drv, void * data)
  *     pair is found, break out and return.
  *
  *     Returns 1 if the device was bound to a driver;
- *     0 if no matching device was found; error code otherwise.
+ *     0 if no matching device was found;
+ *     -ENODEV if the device is not registered.
  *
  *     When called for a USB interface, @dev->parent->sem must be held.
  */
@@ -252,8 +243,13 @@ int device_attach(struct device * dev)
                ret = device_bind_driver(dev);
                if (ret == 0)
                        ret = 1;
-       } else
+               else {
+                       dev->driver = NULL;
+                       ret = 0;
+               }
+       } else {
                ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
+       }
        up(&dev->sem);
        return ret;
 }
@@ -379,33 +375,6 @@ void driver_detach(struct device_driver * drv)
        }
 }
 
-#ifdef CONFIG_PCI_MULTITHREAD_PROBE
-static int __init wait_for_probes(void)
-{
-       DEFINE_WAIT(wait);
-
-       printk(KERN_INFO "%s: waiting for %d threads\n", __FUNCTION__,
-                       atomic_read(&probe_count));
-       if (!atomic_read(&probe_count))
-               return 0;
-       while (atomic_read(&probe_count)) {
-               prepare_to_wait(&probe_waitqueue, &wait, TASK_UNINTERRUPTIBLE);
-               if (atomic_read(&probe_count))
-                       schedule();
-       }
-       finish_wait(&probe_waitqueue, &wait);
-       return 0;
-}
-
-core_initcall_sync(wait_for_probes);
-postcore_initcall_sync(wait_for_probes);
-arch_initcall_sync(wait_for_probes);
-subsys_initcall_sync(wait_for_probes);
-fs_initcall_sync(wait_for_probes);
-device_initcall_sync(wait_for_probes);
-late_initcall_sync(wait_for_probes);
-#endif
-
 EXPORT_SYMBOL_GPL(device_bind_driver);
 EXPORT_SYMBOL_GPL(device_release_driver);
 EXPORT_SYMBOL_GPL(device_attach);