Use bus_rescan_devices() and a pcmcia_bus_match() function to match pcmcia devices and drivers based on cardmgr's wishes. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 34 +++++++++++++++++++++++++--------- include/pcmcia/ds.h | 4 ++-- 2 files changed, 27 insertions(+), 11 deletions(-) Index: 2.6.10-rc3/drivers/pcmcia/ds.c =================================================================== --- 2.6.10-rc3.orig/drivers/pcmcia/ds.c 2004-12-06 14:17:15.583024376 +0100 +++ 2.6.10-rc3/drivers/pcmcia/ds.c 2004-12-06 14:19:28.481820688 +0100 @@ -461,7 +461,7 @@ */ static DECLARE_MUTEX(device_add_lock); -static int pcmcia_device_add(struct pcmcia_bus_socket *s, unsigned int function, struct pcmcia_driver *p_drv) +static int pcmcia_device_add(struct pcmcia_bus_socket *s, unsigned int function) { struct pcmcia_device *p_dev, *tmp_dev; unsigned long flags; @@ -497,9 +497,6 @@ p_dev->dev.release = pcmcia_release_dev; sprintf (p_dev->dev.bus_id, "pcmcia%d.%d", p_dev->socket->sock, p_dev->func); - /* temporary workaround */ - p_dev->dev.driver = &p_drv->drv; - /* compat */ p_dev->client.client_magic = CLIENT_MAGIC; p_dev->client.Socket = s->parent; @@ -542,6 +539,18 @@ return (ret); } + +static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { + struct pcmcia_device * p_dev = to_pcmcia_dev(dev); + struct pcmcia_driver * p_drv = to_pcmcia_drv(drv); + + /* matching by cardmgr */ + if (p_dev->cardmgr == p_drv) + return 1; + + return 0; +} + /*====================================================================== These manage a ring buffer of events pending for one user process @@ -732,7 +741,7 @@ goto err_put_driver; } - ret = pcmcia_device_add(s, bind_info->function, p_drv); + ret = pcmcia_device_add(s, bind_info->function); if ((ret) && (ret != -EBUSY)) goto err_put_module; @@ -749,11 +758,17 @@ bind_info->instance = p_dev->instance; ret = -EBUSY; goto err_put_device; - } + } else + p_dev->cardmgr = p_drv; - ret = pcmcia_device_probe(&p_dev->dev); - if (!ret) - p_dev->cardmgr++; + bus_rescan_devices(&pcmcia_bus_type); + + /* check whether the driver indeed matched. I don't care if this + * is racy or not, because it can only happen on cardmgr access + * paths... + */ + if (!(p_dev->dev.driver == &p_drv->drv)) + p_dev->cardmgr = NULL; err_put_device: pcmcia_put_dev(p_dev); @@ -1482,6 +1497,7 @@ struct bus_type pcmcia_bus_type = { .name = "pcmcia", + .match = pcmcia_bus_match, }; EXPORT_SYMBOL(pcmcia_bus_type); Index: 2.6.10-rc3/include/pcmcia/ds.h =================================================================== --- 2.6.10-rc3.orig/include/pcmcia/ds.h 2004-12-06 14:16:00.892379080 +0100 +++ 2.6.10-rc3/include/pcmcia/ds.h 2004-12-06 14:18:04.196633984 +0100 @@ -164,8 +164,8 @@ event_callback_args_t event_callback_args; } client; - /* registration by cardmgr done? */ - unsigned int cardmgr; + /* device driver wanted by cardmgr */ + struct pcmcia_driver * cardmgr; struct device dev; };