ChangeSet 1.2065.3.15, 2005/03/12 08:24:42-08:00, [EMAIL PROTECTED]

        [PATCH] pcmcia: pcmcia_device_probe
        
        Move the probing of a device-driver pair (a.k.a. "attach") into
        pcmcia_device_probe() conforming to the driver model.
        
        Signed-off-by: Dominik Brodowski <[EMAIL PROTECTED]>
        Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
        Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>



 ds.c |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 55 insertions(+), 17 deletions(-)


diff -Nru a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
--- a/drivers/pcmcia/ds.c       2005-03-12 21:27:41 -08:00
+++ b/drivers/pcmcia/ds.c       2005-03-12 21:27:41 -08:00
@@ -285,13 +285,17 @@
  *
  * Registers a PCMCIA driver with the PCMCIA bus core.
  */
+static int pcmcia_device_probe(struct device *dev);
+
 int pcmcia_register_driver(struct pcmcia_driver *driver)
 {
        if (!driver)
                return -EINVAL;
 
+       /* initialize common fields */
        driver->drv.bus = &pcmcia_bus_type;
        driver->drv.owner = driver->owner;
+       driver->drv.probe = pcmcia_device_probe;
 
        return driver_register(&driver->drv);
 }
@@ -364,6 +368,42 @@
 }
 
 
+static int pcmcia_device_probe(struct device * dev)
+{
+       struct pcmcia_device *p_dev;
+       struct pcmcia_driver *p_drv;
+       int ret = 0;
+
+       dev = get_device(dev);
+       if (!dev)
+               return -ENODEV;
+
+       p_dev = to_pcmcia_dev(dev);
+       p_drv = to_pcmcia_drv(dev->driver);
+
+       if (!try_module_get(p_drv->owner)) {
+               ret = -EINVAL;
+               goto put_dev;
+       }
+
+       if (p_drv->attach) {
+               p_dev->instance = p_drv->attach();
+               if ((!p_dev->instance) || (p_dev->client.state & 
CLIENT_UNBOUND)) {
+                       printk(KERN_NOTICE "ds: unable to create instance "
+                              "of '%s'!\n", p_drv->drv.name);
+                       ret = -EINVAL;
+               }
+       }
+
+       if (ret)
+               module_put(p_drv->owner);
+ put_dev:
+       if ((ret) || !(p_drv->attach))
+               put_device(dev);
+       return (ret);
+}
+
+
 /*======================================================================
 
     These manage a ring buffer of events pending for one user process
@@ -583,12 +623,6 @@
        p_dev->client.Function = bind_info->function;
        p_dev->client.state = CLIENT_UNBOUND;
 
-       ret = device_register(&p_dev->dev);
-       if (ret) {
-               kfree(p_dev);
-               goto err_put_module;
-       }
-
        /* Add to the list in pcmcia_bus_socket, but only if no device
         * with the same func _and_ driver exists */
        spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
@@ -598,22 +632,21 @@
                        spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
                        bind_info->instance = tmp_dev->instance;
                        ret = -EBUSY;
-                       goto err_unregister;
+                       goto err_free;
                }
        }
        list_add_tail(&p_dev->socket_device_list, &s->devices_list);
        spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
-       if (p_drv->attach) {
-               p_dev->instance = p_drv->attach();
-               if ((!p_dev->instance) || (p_dev->client.state & 
CLIENT_UNBOUND)) {
-                       printk(KERN_NOTICE "ds: unable to create instance "
-                              "of '%s'!\n", (char *)bind_info->dev_info);
-                       ret = -ENODEV;
-                       goto err_unregister;
-               }
-       }
+       ret = device_register(&p_dev->dev);
+       if (ret)
+               goto err_free;
 
+       ret = pcmcia_device_probe(&p_dev->dev);
+       if (ret)
+               goto err_unregister;
+
+       module_put(p_drv->owner);
        put_driver(&p_drv->drv);
 
        return 0;
@@ -624,6 +657,8 @@
        put_driver(&p_drv->drv);
        return (ret);
 
+ err_free:
+       kfree(p_dev);
  err_put_module:
        module_put(p_drv->owner);
  err_put_driver:
@@ -853,8 +888,11 @@
                /* detach the "instance" */
                p_drv = to_pcmcia_drv(p_dev->dev.driver);
                if (p_drv) {
-                       if ((p_drv->detach) && (p_dev->instance))
+                       if ((p_drv->detach) && (p_dev->instance)) {
                                p_drv->detach(p_dev->instance);
+                               /* from pcmcia_probe_device */
+                               put_device(&p_dev->dev);
+                       }
                        module_put(p_drv->owner);
                }
 
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to