]> git.hungrycats.org Git - linux/commitdiff
[PATCH] pcmcia: use pcmcia_device in register_client
authorDominik Brodowski <linux@dominikbrodowski.de>
Tue, 11 Jan 2005 11:23:13 +0000 (03:23 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Tue, 11 Jan 2005 11:23:13 +0000 (03:23 -0800)
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>
drivers/pcmcia/ds.c

index 7610959235752b63f7a7a7c6c814139c359f276f..94310b95f623e1444c6be6f9036ae62c08707078 100644 (file)
@@ -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);