]> git.hungrycats.org Git - linux/commitdiff
[PATCH] pcmcia: move struct client_t inside struct pcmcia_device
authorDominik Brodowski <linux@dominikbrodowski.de>
Tue, 11 Jan 2005 11:24:11 +0000 (03:24 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Tue, 11 Jan 2005 11:24:11 +0000 (03:24 -0800)
Move the struct client_t inside struct pcmcia_device.  This means it gets
proper reference counting as well.  The clients list inside struct
pcmcia_socket can be removed now.

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/bulkmem.c
drivers/pcmcia/cs.c
drivers/pcmcia/cs_internal.h
drivers/pcmcia/ds.c
include/pcmcia/ds.h
include/pcmcia/ss.h

index 1be40034acd432ade5df1c22fc0b56cae7ab33f4..8997b5c04a9e5194588224a5d750374caf5b4442 100644 (file)
@@ -27,6 +27,7 @@
 #include <pcmcia/cs.h>
 #include <pcmcia/bulkmem.h>
 #include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
 #include "cs_internal.h"
 
 #ifdef DEBUG
index b93ec422c78aade7b23e99f2558567a94a31d8fa..e875cb399ffbfca34b8ca04b6bd036ff2355b16d 100644 (file)
@@ -41,6 +41,7 @@
 #include <pcmcia/bulkmem.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
 #include "cs_internal.h"
 
 #ifdef CONFIG_PCI
@@ -199,8 +200,6 @@ static void pcmcia_release_socket(struct class_device *class_dev)
 {
        struct pcmcia_socket *socket = class_get_devdata(class_dev);
 
-       BUG_ON(socket->clients);
-
        complete(&socket->socket_released);
 }
 
@@ -369,7 +368,6 @@ static void shutdown_socket(struct pcmcia_socket *s)
        kfree(s->config);
        s->config = NULL;
     }
-    BUG_ON(s->clients);
     free_regions(&s->a_region);
     free_regions(&s->c_region);
 
index 67f85f56fe9d7d57aaca72b6cc209c30cf2b7d78..6d441e178f63ff56e4319375caca81933f211cf0 100644 (file)
 #include <linux/config.h>
 
 #define CLIENT_MAGIC   0x51E6
-typedef struct client_t {
-    u_short            client_magic;
-    struct pcmcia_socket *Socket;
-    u_char             Function;
-    dev_info_t         dev_info;
-    u_int              Attributes;
-    u_int              state;
-    event_t            EventMask, PendingEvents;
-    int (*event_handler)(event_t event, int priority,
-                        event_callback_args_t *);
-    event_callback_args_t event_callback_args;
-    struct client_t    *next;
-} client_t;
+typedef struct client_t client_t;
 
 /* Flags in client state */
 #define CLIENT_CONFIG_LOCKED   0x0001
index 059f02471b627d2611e5e51bf2fd46997f2a9d30..f6609d8f463921a842547509a2142405c1fbe1f5 100644 (file)
@@ -356,6 +356,7 @@ static void pcmcia_put_dev(struct pcmcia_device *p_dev)
 static void pcmcia_release_dev(struct device *dev)
 {
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+       ds_dbg(1, "releasing dev %p\n", p_dev);
        pcmcia_put_bus_socket(p_dev->socket->pcmcia);
        kfree(p_dev);
 }
@@ -430,11 +431,11 @@ static int send_event_callback(struct device *dev, void * _data)
        if (p_dev->socket != data->skt)
                return 0;
 
-       if (p_dev->client->state & (CLIENT_UNBOUND|CLIENT_STALE))
+       if (p_dev->client.state & (CLIENT_UNBOUND|CLIENT_STALE))
                return 0;
 
-       if (p_dev->client->EventMask & data->event)
-               return EVENT(p_dev->client, data->event, data->priority);
+       if (p_dev->client.EventMask & data->event)
+               return EVENT(&p_dev->client, data->event, data->priority);
 
        return 0;
 }
@@ -559,10 +560,10 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
 {
        struct pcmcia_driver *p_drv;
        struct pcmcia_device *p_dev, *tmp_dev;
-       client_t *client;
        unsigned long flags;
        int ret = 0;
 
+       s = pcmcia_get_bus_socket(s);
        if (!s)
                return -EINVAL;
 
@@ -570,25 +571,10 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
               (char *)bind_info->dev_info);
 
        p_drv = get_pcmcia_driver(&bind_info->dev_info);
-       if (!p_drv)
-               return -EINVAL;
-
-       if (!try_module_get(p_drv->owner))
-               return -EINVAL;
-
-       client = (client_t *) kmalloc(sizeof(client_t), GFP_KERNEL);
-       if (!client) {
-               ret = -ENOMEM;
+       if ((!p_drv) || (!try_module_get(p_drv->owner))) {
+               ret = -EINVAL;
                goto err_put;
        }
-       memset(client, 0, sizeof(client_t));
-
-       client->client_magic = CLIENT_MAGIC;
-       client->Socket = s->parent;
-       client->Function = bind_info->function;
-       client->state = CLIENT_UNBOUND;
-       client->next = s->parent->clients;
-       strlcpy(client->dev_info, p_drv->drv.name, DEV_NAME_LEN);
 
        /* Currently, the userspace pcmcia cardmgr detects pcmcia devices.
         * Here this information is translated into a kernel
@@ -598,21 +584,13 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
        p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
        if (!p_dev) {
                ret = -ENOMEM;
-               goto err_free_client;
+               goto err_put_module;
        }
        memset(p_dev, 0, sizeof(struct pcmcia_device));
 
-       s = pcmcia_get_bus_socket(s);
-       if (!s) {
-               ret = -ENODEV;
-               kfree(p_dev);
-               goto err_free_client;
-       }
-
        p_dev->socket = s->parent;
        p_dev->device_no = (s->device_count++);
        p_dev->func   = bind_info->function;
-       p_dev->client = client;
 
        p_dev->dev.bus = &pcmcia_bus_type;
        p_dev->dev.parent = s->parent->dev.dev;
@@ -620,11 +598,17 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
        sprintf (p_dev->dev.bus_id, "pcmcia%d.%d", p_dev->socket->sock, p_dev->device_no);
        p_dev->dev.driver = &p_drv->drv;
 
+       /* compat */
+       p_dev->client.client_magic = CLIENT_MAGIC;
+       p_dev->client.Socket = s->parent;
+       p_dev->client.Function = bind_info->function;
+       p_dev->client.state = CLIENT_UNBOUND;
+       strlcpy(p_dev->client.dev_info, p_drv->drv.name, DEV_NAME_LEN);
+
        ret = device_register(&p_dev->dev);
        if (ret) {
                kfree(p_dev);
-               pcmcia_put_bus_socket(s);
-               goto err_free_client;
+               goto err_put_module;
        }
 
        /* Add to the list in pcmcia_bus_socket, but only if no device
@@ -642,15 +626,11 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
        list_add_tail(&p_dev->socket_device_list, &s->devices_list);
        spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
-       /* finally here the parent client is registered */
-       s->parent->clients = client;
-
        if (p_drv->attach) {
                p_dev->instance = p_drv->attach();
-               if (!p_dev->instance) {
+               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);
-                       /* FIXME: client isn't freed here */
                        ret = -ENODEV;
                        goto err_unregister;
                }
@@ -660,11 +640,14 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
 
  err_unregister:
        device_unregister(&p_dev->dev);
- err_free_client:
-       kfree(client);
- err_put:
        module_put(p_drv->owner);
        return (ret);
+
+ err_put_module:
+       module_put(p_drv->owner);
+ err_put:
+       pcmcia_put_bus_socket(s);
+       return (ret);
 } /* bind_request */
 
 int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
@@ -690,11 +673,11 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
                        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))) {
+                       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;
+                                       client = &p_dev->client;
                                spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
                                goto found;
                        }
@@ -753,7 +736,6 @@ 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:
@@ -877,7 +859,7 @@ static int unbind_request(struct pcmcia_bus_socket *s)
                }
                p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
                list_del(&p_dev->socket_device_list);
-               p_dev->client->state |= CLIENT_STALE;
+               p_dev->client.state |= CLIENT_STALE;
                spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
                /* detach the "instance" */
@@ -896,10 +878,9 @@ static int unbind_request(struct pcmcia_bus_socket *s)
 
 int pcmcia_deregister_client(client_handle_t handle)
 {
-       client_t **client;
        struct pcmcia_socket *s;
-       u_long flags;
        int i;
+       struct pcmcia_device *p_dev = handle_to_pdev(handle);
 
        if (CHECK_HANDLE(handle))
                return CS_BAD_HANDLE;
@@ -914,18 +895,9 @@ int pcmcia_deregister_client(client_handle_t handle)
                        goto warn_out;
 
        if (handle->state & CLIENT_STALE) {
-               spin_lock_irqsave(&s->lock, flags);
-               client = &s->clients;
-               while ((*client) && ((*client) != handle))
-                       client = &(*client)->next;
-               if (*client == NULL) {
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       return CS_BAD_HANDLE;
-               }
-               *client = handle->next;
                handle->client_magic = 0;
-               kfree(handle);
-               spin_unlock_irqrestore(&s->lock, flags);
+               handle->state &= ~CLIENT_STALE;
+               pcmcia_put_dev(p_dev);
        } else {
                handle->state = CLIENT_UNBOUND;
                handle->event_handler = NULL;
index ba49e8bc7abdad117392adb0bf22ea3a0d87ccdc..c8223b32742e9d9533c83bdde6432b6ae24e4df5 100644 (file)
@@ -128,7 +128,6 @@ typedef struct dev_link_t {
 
 
 struct pcmcia_socket;
-struct client_t;
 
 extern struct bus_type pcmcia_bus_type;
 
@@ -159,7 +158,18 @@ struct pcmcia_device {
        /* deprecated, a cleaned up version will be moved into this
           struct soon */
        dev_link_t              *instance;
-       struct client_t         *client;
+       struct client_t {
+               u_short                 client_magic;
+               struct pcmcia_socket    *Socket;
+               u_char                  Function;
+               dev_info_t              dev_info;
+               u_int                   Attributes;
+               u_int                   state;
+               event_t                 EventMask, PendingEvents;
+               int (*event_handler)    (event_t event, int priority,
+                                        event_callback_args_t *);
+               event_callback_args_t   event_callback_args;
+       }                       client;
 
        struct device           dev;
 };
@@ -167,6 +177,7 @@ struct pcmcia_device {
 #define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
 #define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv)
 
+#define handle_to_pdev(handle) container_of(handle, struct pcmcia_device, client);
 
 /* error reporting */
 void cs_error(client_handle_t handle, int func, int ret);
index cc679ac74891cfd9003c4aeb9430bf3e3b801796..fc8080f2b691b130a3d7d9a3624daae65dfade42 100644 (file)
@@ -153,7 +153,6 @@ struct pcmcia_socket {
        u_int                           state;
        u_short                         functions;
        u_short                         lock_count;
-       client_handle_t                 clients;
        pccard_mem_map                  cis_mem;
        void __iomem                    *cis_virt;
        struct config_t                 *config;