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