ChangeSet 1.793.1.17, 2002/10/18 10:00:13-07:00, [EMAIL PROTECTED]

merge between the usb and driver model trees.


diff -Nru a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c       Fri Oct 18 14:43:06 2002
+++ b/drivers/base/core.c       Fri Oct 18 14:43:06 2002
@@ -19,109 +19,12 @@
 int (*platform_notify)(struct device * dev) = NULL;
 int (*platform_notify_remove)(struct device * dev) = NULL;
 
+DECLARE_MUTEX(device_sem);
+
 spinlock_t device_lock = SPIN_LOCK_UNLOCKED;
 
 #define to_dev(node) container_of(node,struct device,driver_list)
 
-static int probe(struct device * dev, struct device_driver * drv)
-{
-       dev->driver = drv;
-       return drv->probe ? drv->probe(dev) : -ENODEV;
-}
-
-static void attach(struct device * dev)
-{
-       spin_lock(&device_lock);
-       list_add_tail(&dev->driver_list,&dev->driver->devices);
-       spin_unlock(&device_lock);
-       devclass_add_device(dev);
-}
-
-/**
- * found_match - do actual binding of device to driver
- * @dev:       device 
- * @drv:       driver
- *
- * We're here because the bus's match callback returned success for this 
- * pair. We call the driver's probe callback to verify they're really a
- * match made in heaven.
- *
- * In the future, we may want to notify userspace of the binding. (But, 
- * we might not want to do it here).
- * 
- * We may also want to create a symlink in the driver's directory to the 
- * device's physical directory.
- */
-static int found_match(struct device * dev, struct device_driver * drv)
-{
-       int error;
-
-       if (!(error = probe(dev,get_driver(drv)))) {
-               pr_debug("bound device '%s' to driver '%s'\n",
-                        dev->bus_id,drv->name);
-               attach(dev);
-       } else {
-               put_driver(drv);
-               dev->driver = NULL;
-       }
-       /* return boolean:  did driver bind? */
-       return error == 0;
-}
-
-/**
- * device_attach - try to associated device with a driver
- * @drv:       current driver to try
- * @data:      device in disguise
- *
- * This function is used as a callback to bus_for_each_drv.
- * It calls the bus's match callback to check if the driver supports
- * the device. If so, it calls the found_match() function above to 
- * take care of all the details.
- */
-static int do_device_attach(struct device_driver * drv, void * data)
-{
-       struct device * dev = (struct device *)data;
-       int error = 0;
-
-       if (drv->bus->match && drv->bus->match(dev,drv))
-               error = found_match(dev,drv);
-       /* stop bus_for_each_drv() once a driver binds to the device */
-       return error;
-}
-
-static int device_attach(struct device * dev)
-{
-       int error = 0;
-       if (!dev->driver) {
-               if (dev->bus)
-                       error = bus_for_each_drv(dev->bus,dev,do_device_attach);
-       } else
-               attach(dev);
-       return error;
-}
-
-static void device_detach(struct device * dev)
-{
-       struct device_driver * drv = dev->driver;
-
-       if (drv) {
-               devclass_remove_device(dev);
-               if (drv && drv->remove)
-                       drv->remove(dev);
-               dev->driver = NULL;
-       }
-}
-
-static int do_driver_attach(struct device * dev, void * data)
-{
-       struct device_driver * drv = (struct device_driver *)data;
-
-       if (!dev->driver) {
-               if (dev->bus->match && dev->bus->match(dev,drv))
-                       found_match(dev,drv);
-       }
-       /* continue bus_for_each_dev(), to attach to other devices */
-       return 0;
 }
 
 int driver_attach(struct device_driver * drv)
@@ -162,30 +65,21 @@
  * Maintains a global list of all devices, in depth-first ordering.
  * The head for that list is device_root.g_list.
  */
-int device_register(struct device *dev)
+int device_add(struct device *dev)
 {
        int error;
 
        if (!dev || !strlen(dev->bus_id))
                return -EINVAL;
 
-       INIT_LIST_HEAD(&dev->node);
-       INIT_LIST_HEAD(&dev->children);
-       INIT_LIST_HEAD(&dev->g_list);
-       INIT_LIST_HEAD(&dev->driver_list);
-       INIT_LIST_HEAD(&dev->bus_list);
-       INIT_LIST_HEAD(&dev->intf_list);
-       spin_lock_init(&dev->lock);
-       atomic_set(&dev->refcount,2);
-       dev->present = 1;
-       spin_lock(&device_lock);
+       down(&device_sem);
+       dev->state = DEVICE_REGISTERED;
        if (dev->parent) {
-               get_device_locked(dev->parent);
                list_add_tail(&dev->g_list,&dev->parent->g_list);
                list_add_tail(&dev->node,&dev->parent->children);
        } else
                list_add_tail(&dev->g_list,&global_device_list);
-       spin_unlock(&device_lock);
+       up(&device_sem);
 
        pr_debug("DEV: registering device: ID = '%s', name = %s\n",
                 dev->bus_id, dev->name);
@@ -195,9 +89,6 @@
 
        bus_add_device(dev);
 
-       /* bind to driver */
-       device_attach(dev);
-
        /* notify platform of device entry */
        if (platform_notify)
                platform_notify(dev);
@@ -205,35 +96,68 @@
        /* notify userspace of device entry */
        dev_hotplug(dev, "add");
 
+       devclass_add_device(dev);
  register_done:
        if (error) {
-               spin_lock(&device_lock);
+               up(&device_sem);
                list_del_init(&dev->g_list);
                list_del_init(&dev->node);
-               spin_unlock(&device_lock);
-               if (dev->parent)
-                       put_device(dev->parent);
+               up(&device_sem);
        }
-       put_device(dev);
        return error;
 }
 
-struct device * get_device_locked(struct device * dev)
+void device_initialize(struct device *dev)
 {
-       struct device * ret = dev;
-       if (dev && dev->present && atomic_read(&dev->refcount) > 0)
-               atomic_inc(&dev->refcount);
-       else
-               ret = NULL;
-       return ret;
+       INIT_LIST_HEAD(&dev->node);
+       INIT_LIST_HEAD(&dev->children);
+       INIT_LIST_HEAD(&dev->g_list);
+       INIT_LIST_HEAD(&dev->driver_list);
+       INIT_LIST_HEAD(&dev->bus_list);
+       INIT_LIST_HEAD(&dev->intf_list);
+       spin_lock_init(&dev->lock);
+       atomic_set(&dev->refcount,1);
+       dev->state = DEVICE_INITIALIZED;
+       if (dev->parent)
+               get_device(dev->parent);
+}
+
+/**
+ * device_register - register a device
+ * @dev:       pointer to the device structure
+ *
+ * First, make sure that the device has a parent, create
+ * a directory for it, then add it to the parent's list of
+ * children.
+ *
+ * Maintains a global list of all devices, in depth-first ordering.
+ * The head for that list is device_root.g_list.
+ */
+int device_register(struct device *dev)
+{
+       int error;
+
+       if (!dev || !strlen(dev->bus_id))
+               return -EINVAL;
+
+       device_initialize(dev);
+       if (dev->parent)
+               get_device(dev->parent);
+       error = device_add(dev);
+       if (error && dev->parent)
+               put_device(dev->parent);
+       return error;
 }
 
 struct device * get_device(struct device * dev)
 {
-       struct device * ret;
-       spin_lock(&device_lock);
-       ret = get_device_locked(dev);
-       spin_unlock(&device_lock);
+       struct device * ret = dev;
+       down(&device_sem);
+       if (device_present(dev) && atomic_read(&dev->refcount) > 0)
+               atomic_inc(&dev->refcount);
+       else
+               ret = NULL;
+       up(&device_sem);
        return ret;
 }
 
@@ -243,43 +167,23 @@
  */
 void put_device(struct device * dev)
 {
-       struct device * parent;
-       if (!atomic_dec_and_lock(&dev->refcount,&device_lock))
+       down(&device_sem);
+       if (!atomic_dec_and_test(&dev->refcount)) {
+               up(&device_sem);
                return;
-       parent = dev->parent;
-       dev->parent = NULL;
-       spin_unlock(&device_lock);
-
-       BUG_ON(dev->present);
+       }
+       list_del_init(&dev->node);
+       list_del_init(&dev->g_list);
+       up(&device_sem);
 
-       if (dev->release)
-               dev->release(dev);
+       BUG_ON((dev->state != DEVICE_GONE));
 
-       if (parent)
-               put_device(parent);
+       device_del(dev);
 }
 
-/**
- * device_unregister - unlink device
- * @dev:       device going away
- *
- * The device has been removed from the system, so we disavow knowledge
- * of it. It might not be the final reference to the device, so we mark
- * it as !present, so no more references to it can be acquired.
- * In the end, we decrement the final reference count for it.
- */
-void device_unregister(struct device * dev)
+void device_del(struct device * dev)
 {
-       spin_lock(&device_lock);
-       dev->present = 0;
-       list_del_init(&dev->node);
-       list_del_init(&dev->g_list);
-       list_del_init(&dev->bus_list);
-       list_del_init(&dev->driver_list);
-       spin_unlock(&device_lock);
-
-       pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n",
-                dev->bus_id,dev->name);
+       struct device * parent = dev->parent;
 
        /* Notify the platform of the removal, in case they
         * need to do anything...
@@ -290,26 +194,37 @@
        /* notify userspace that this device is about to disappear */
        dev_hotplug (dev, "remove");
 
-       device_detach(dev);
        bus_remove_device(dev);
 
        /* remove the driverfs directory */
        device_remove_dir(dev);
 
-       put_device(dev);
+       if (dev->release)
+               dev->release(dev);
+
+       if (parent)
+               put_device(parent);
 }
 
-static int __init device_init(void)
+/**
+ * device_unregister - unlink device
+ * @dev:       device going away
+ *
+ * The device has been removed from the system, so we disavow knowledge
+ * of it. It might not be the final reference to the device, so we mark
+ * it as !present, so no more references to it can be acquired.
+ * In the end, we decrement the final reference count for it.
+ */
+void device_unregister(struct device * dev)
 {
-       int error;
+       down(&device_sem);
+       dev->state = DEVICE_GONE;
+       up(&device_sem);
 
-       error = init_driverfs_fs();
-       if (error)
-               panic("DEV: could not initialize driverfs");
-       return 0;
+       pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n",
+                dev->bus_id,dev->name);
+       put_device(dev);
 }
-
-core_initcall(device_init);
 
 EXPORT_SYMBOL(device_register);
 EXPORT_SYMBOL(device_unregister);


-------------------------------------------------------
This sf.net email is sponsored by:
Access Your PC Securely with GoToMyPC. Try Free Now
https://www.gotomypc.com/s/OSND/DD
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to