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 --- drivers/pcmcia/ds.c | 59 +++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 49 insertions(+), 10 deletions(-) Index: 2.6.10-rc3/drivers/pcmcia/ds.c =================================================================== --- 2.6.10-rc3.orig/drivers/pcmcia/ds.c 2004-12-06 08:16:11.403733584 +0100 +++ 2.6.10-rc3/drivers/pcmcia/ds.c 2004-12-06 08:17:17.074750072 +0100 @@ -282,13 +282,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); } @@ -361,6 +365,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 0; +} + + /*====================================================================== These manage a ring buffer of events pending for one user process @@ -602,15 +642,11 @@ 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 = pcmcia_device_probe(&p_dev->dev); + if (ret) + goto err_unregister; + + module_put(p_drv->owner); put_driver(&p_drv->drv); @@ -849,8 +885,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); }