aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.de>2005-01-11 03:23:13 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-11 03:23:13 -0800
commit6a35548e58c20e8b3254e00b709ebbb7cef76b68 (patch)
tree6ab2c7f3207948921718c130ee780281f50ba45a /drivers
parent57f5c824093a2bc07ea88ca77e965bb2f97681b4 (diff)
downloadhistory-6a35548e58c20e8b3254e00b709ebbb7cef76b68.tar.gz
[PATCH] pcmcia: use pcmcia_device in register_client
Search the devices_list for an UNBOUND client in register_client, instead of the single linked list clients. Signed-off-by: Dominik Brodowski <linux@brodo.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pcmcia/ds.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 7610959235752b..94310b95f623e1 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -675,21 +675,43 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
{
client_t *client = NULL;
struct pcmcia_socket *s;
+ struct pcmcia_bus_socket *skt = NULL;
+ struct pcmcia_device *p_dev = NULL;
/* Look for unbound client with matching dev_info */
down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
- client = s->clients;
- while (client != NULL) {
- if ((strcmp(client->dev_info, (char *)req->dev_info) == 0)
- && (client->state & CLIENT_UNBOUND)) break;
- client = client->next;
+ unsigned long flags;
+
+ if (s->state & SOCKET_CARDBUS)
+ continue;
+
+ skt = s->pcmcia;
+ if (!skt)
+ continue;
+ skt = pcmcia_get_bus_socket(skt);
+ if (!skt)
+ continue;
+ spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+ list_for_each_entry(p_dev, &skt->devices_list, socket_device_list) {
+ if ((p_dev->client->state & CLIENT_UNBOUND) &&
+ (!strcmp(p_dev->client->dev_info, (char *)req->dev_info))) {
+ p_dev = pcmcia_get_dev(p_dev);
+ if (p_dev)
+ client = p_dev->client;
+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ goto found;
+ }
}
- if (client != NULL) break;
+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ pcmcia_put_bus_socket(skt);
}
+ found:
up_read(&pcmcia_socket_list_rwsem);
- if (client == NULL)
- return CS_OUT_OF_RESOURCE;
+ if (!p_dev || !client)
+ return -ENODEV;
+
+ pcmcia_put_bus_socket(skt); /* safe, as we already hold a reference from bind_device */
/*
* Prevent this racing with a card insertion.
@@ -735,10 +757,12 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
}
up(&s->skt_sem);
+ pcmcia_put_dev(p_dev); /* FIXME: put in deregister_client. */
return CS_SUCCESS;
out_no_resource:
up(&s->skt_sem);
+ pcmcia_put_dev(p_dev);
return CS_OUT_OF_RESOURCE;
} /* register_client */
EXPORT_SYMBOL(pcmcia_register_client);