Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/pcmcia/bulkmem.c     |   45 +---
 25-akpm/drivers/pcmcia/cardbus.c     |   45 +---
 25-akpm/drivers/pcmcia/cistpl.c      |   45 +---
 25-akpm/drivers/pcmcia/cs.c          |  256 ++++------------------------
 25-akpm/drivers/pcmcia/cs_internal.h |   18 -
 25-akpm/drivers/pcmcia/ds.c          |  318 ++++++++++++++++++++++++++++-------
 25-akpm/drivers/pcmcia/rsrc_mgr.c    |   45 +---
 25-akpm/include/pcmcia/bulkmem.h     |   28 ---
 25-akpm/include/pcmcia/ciscode.h     |   25 --
 25-akpm/include/pcmcia/cisreg.h      |   25 --
 25-akpm/include/pcmcia/cistpl.h      |   25 --
 25-akpm/include/pcmcia/cs.h          |   28 ---
 25-akpm/include/pcmcia/cs_types.h    |   25 --
 25-akpm/include/pcmcia/ds.h          |    2 
 25-akpm/include/pcmcia/mem_op.h      |   25 --
 25-akpm/include/pcmcia/ss.h          |   25 --
 16 files changed, 407 insertions(+), 573 deletions(-)

diff -puN drivers/pcmcia/bulkmem.c~pcmcia-b18a-client_t-and-pcmcia_device-integration drivers/pcmcia/bulkmem.c
--- 25/drivers/pcmcia/bulkmem.c~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.413511760 -0800
+++ 25-akpm/drivers/pcmcia/bulkmem.c	2004-11-30 01:23:21.439507808 -0800
@@ -1,35 +1,16 @@
-/*======================================================================
-
-    PCMCIA Bulk Memory Services
-
-    bulkmem.c 1.38 2000/09/25 19:29:51
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    The initial developer of the original code is David A. Hinds
-    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * bulkmem.c -- 16-bit PCMCIA Bulk Memory Services
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ * (C) 1999		David A. Hinds
+ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
diff -puN drivers/pcmcia/cardbus.c~pcmcia-b18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cardbus.c
--- 25/drivers/pcmcia/cardbus.c~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.415511456 -0800
+++ 25-akpm/drivers/pcmcia/cardbus.c	2004-11-30 01:23:21.439507808 -0800
@@ -1,35 +1,16 @@
-/*======================================================================
-  
-    Cardbus device configuration
-    
-    cardbus.c 1.87 2002/10/24 06:11:41
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    The initial developer of the original code is David A. Hinds
-    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * cardbus.c -- 16-bit PCMCIA core support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ * (C) 1999		David A. Hinds
+ */
 
 /*
  * Cardbus handling has been re-written to be more of a PCI bridge thing,
diff -puN drivers/pcmcia/cistpl.c~pcmcia-b18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cistpl.c
--- 25/drivers/pcmcia/cistpl.c~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.417511152 -0800
+++ 25-akpm/drivers/pcmcia/cistpl.c	2004-11-30 01:23:21.441507504 -0800
@@ -1,35 +1,16 @@
-/*======================================================================
-
-    PCMCIA Card Information Structure parser
-
-    cistpl.c 1.99 2002/10/24 06:11:48
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    The initial developer of the original code is David A. Hinds
-    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in
-    which case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * cistpl.c -- 16-bit PCMCIA Card Information Structure parser
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ * (C) 1999		David A. Hinds
+ */
 
 #include <linux/config.h>
 #include <linux/module.h>
diff -puN drivers/pcmcia/cs.c~pcmcia-b18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cs.c
--- 25/drivers/pcmcia/cs.c~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.418511000 -0800
+++ 25-akpm/drivers/pcmcia/cs.c	2004-11-30 01:23:21.444507048 -0800
@@ -1,35 +1,16 @@
-/*======================================================================
-
-    Kernel Card Services -- core services
-
-    cs.c 1.271 2000/10/02 20:27:49
-    
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    The initial developer of the original code is David A. Hinds
-    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * cs.c -- Kernel Card Services - core services
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ * (C) 1999		David A. Hinds
+ */
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -92,7 +73,7 @@ static const char *options = "options: "
 
 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("Linux Kernel Card Services\noptions:" OPTIONS);
-MODULE_LICENSE("Dual MPL/GPL");	  
+MODULE_LICENSE("GPL");
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
 
@@ -132,6 +113,8 @@ socket_state_t dead_socket = {
 /* List of all sockets, protected by a rwsem */
 LIST_HEAD(pcmcia_socket_list);
 DECLARE_RWSEM(pcmcia_socket_list_rwsem);
+EXPORT_SYMBOL(pcmcia_socket_list);
+EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
 
 
 /*====================================================================
@@ -189,6 +172,29 @@ int pcmcia_socket_dev_resume(struct devi
 EXPORT_SYMBOL(pcmcia_socket_dev_resume);
 
 
+struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt)
+{
+	struct class_device *cl_dev = class_device_get(&skt->dev);
+	if (!cl_dev)
+		return NULL;
+	skt = class_get_devdata(cl_dev);
+	if (!try_module_get(skt->owner)) {
+		class_device_put(&skt->dev);
+		return NULL;
+	}
+	return (skt);
+}
+EXPORT_SYMBOL(pcmcia_get_socket);
+
+
+void pcmcia_put_socket(struct pcmcia_socket *skt)
+{
+	module_put(skt->owner);
+	class_device_put(&skt->dev);
+}
+EXPORT_SYMBOL(pcmcia_put_socket);
+
+
 static void pcmcia_release_socket(struct class_device *class_dev)
 {
 	struct pcmcia_socket *socket = class_get_devdata(class_dev);
@@ -393,8 +399,9 @@ static void shutdown_socket(struct pcmci
 
 /*======================================================================
 
-    The central event handler.  Send_event() sends an event to all
-    valid clients.  Parse_events() interprets the event bits from
+    The central event handler.  Send_event() sends an event to the
+    16-bit subsystem, which then calls the relevant device drivers.
+    Parse_events() interprets the event bits from
     a card status change report.  Do_shutdown() handles the high
     priority stuff associated with a card removal.
     
@@ -427,15 +434,9 @@ static int send_event(struct pcmcia_sock
 
 static void socket_remove_drivers(struct pcmcia_socket *skt)
 {
-	client_t *client;
-
 	cs_dbg(skt, 4, "remove_drivers\n");
 
 	send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
-
-	for (client = skt->clients; client; client = client->next)
-		if (!(client->Attributes & INFO_MASTER_CLIENT))
-			client->state |= CLIENT_STALE;
 }
 
 static void socket_shutdown(struct pcmcia_socket *skt)
@@ -890,49 +891,6 @@ int pccard_access_configuration_register
 } /* access_configuration_register */
 EXPORT_SYMBOL(pccard_access_configuration_register);
 
-/*====================================================================*/
-
-int pcmcia_deregister_client(client_handle_t handle)
-{
-    client_t **client;
-    struct pcmcia_socket *s;
-    u_long flags;
-    int i;
-    
-    if (CHECK_HANDLE(handle))
-	return CS_BAD_HANDLE;
-
-    s = SOCKET(handle);
-    cs_dbg(s, 1, "deregister_client(%p)\n", handle);
-
-    if (handle->state &
-	(CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
-	return CS_IN_USE;
-    for (i = 0; i < MAX_WIN; i++)
-	if (handle->state & CLIENT_WIN_REQ(i))
-	    return CS_IN_USE;
-
-    if ((handle->state & CLIENT_STALE) ||
-	(handle->Attributes & INFO_MASTER_CLIENT)) {
-	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);
-    } else {
-	handle->state = CLIENT_UNBOUND;
-	handle->event_handler = NULL;
-    }
-
-    return CS_SUCCESS;
-} /* deregister_client */
 
 /*====================================================================*/
 
@@ -1016,53 +974,6 @@ int pcmcia_get_card_services_info(servin
     return CS_SUCCESS;
 } /* get_card_services_info */
 
-#ifdef CONFIG_PCMCIA_OBSOLETE
-
-/*======================================================================
-
-    Note that get_first_client() *does* recognize the Socket field
-    in the request structure.
-    
-======================================================================*/
-
-int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req)
-{
-    socket_t s;
-    struct pcmcia_socket *socket;
-    if (req->Attributes & CLIENT_THIS_SOCKET)
-	s = req->Socket;
-    else
-	s = 0;
-    socket = pcmcia_get_socket_by_nr(s);
-    if (!socket)
-	return CS_BAD_SOCKET;
-    if (socket->clients == NULL)
-	return CS_NO_MORE_ITEMS;
-    *handle = socket->clients;
-    return CS_SUCCESS;
-} /* get_first_client */
-EXPORT_SYMBOL(pcmcia_get_first_client);
-
-/*====================================================================*/
-
-int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req)
-{
-    struct pcmcia_socket *s;
-    if ((handle == NULL) || CHECK_HANDLE(*handle))
-	return CS_BAD_HANDLE;
-    if ((*handle)->next == NULL) {
-	if (req->Attributes & CLIENT_THIS_SOCKET)
-	    return CS_NO_MORE_ITEMS;
-	s = (*handle)->Socket;
-	if (s->clients == NULL)
-	    return CS_NO_MORE_ITEMS;
-	*handle = s->clients;
-    } else
-	*handle = (*handle)->next;
-    return CS_SUCCESS;
-} /* get_next_client */
-EXPORT_SYMBOL(pcmcia_get_next_client);
-#endif /* CONFIG_PCMCIA_OBSOLETE */
 
 /*====================================================================*/
 
@@ -1284,87 +1195,6 @@ EXPORT_SYMBOL(pcmcia_modify_window);
 
 #endif /* CONFIG_PCMCIA_OBSOLETE */
 
-
-/*======================================================================
-
-    Register_client() uses the dev_info_t handle to match the
-    caller with a socket.  The driver must have already been bound
-    to a socket with bind_device() -- in fact, bind_device()
-    allocates the client structure that will be used.
-    
-======================================================================*/
-
-int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
-{
-    client_t *client = NULL;
-    struct pcmcia_socket *s;
-    
-    /* 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;
-	}
-	if (client != NULL) break;
-    }
-    up_read(&pcmcia_socket_list_rwsem);
-    if (client == NULL)
-	return CS_OUT_OF_RESOURCE;
-
-    /*
-     * Prevent this racing with a card insertion.
-     */
-    down(&s->skt_sem);
-    *handle = client;
-    client->state &= ~CLIENT_UNBOUND;
-    client->Socket = s;
-    client->Attributes = req->Attributes;
-    client->EventMask = req->EventMask;
-    client->event_handler = req->event_handler;
-    client->event_callback_args = req->event_callback_args;
-    client->event_callback_args.client_handle = client;
-
-    if (s->state & SOCKET_CARDBUS)
-	client->state |= CLIENT_CARDBUS;
-    
-    if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) &&
-	(client->Function != BIND_FN_ALL)) {
-	cistpl_longlink_mfc_t mfc;
-	if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc)
-	    == CS_SUCCESS)
-	    s->functions = mfc.nfn;
-	else
-	    s->functions = 1;
-	s->config = kmalloc(sizeof(config_t) * s->functions,
-			    GFP_KERNEL);
-	if (!s->config)
-		goto out_no_resource;
-	memset(s->config, 0, sizeof(config_t) * s->functions);
-    }
-    
-    cs_dbg(s, 1, "register_client(): client 0x%p, dev %s\n",
-	   client, client->dev_info);
-    if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
-	EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
-
-    if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) {
-	if (client->EventMask & CS_EVENT_CARD_INSERTION)
-	    EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
-	else
-	    client->PendingEvents |= CS_EVENT_CARD_INSERTION;
-    }
-
-    up(&s->skt_sem);
-    return CS_SUCCESS;
-
- out_no_resource:
-    up(&s->skt_sem);
-    return CS_OUT_OF_RESOURCE;
-} /* register_client */
-
 /* register pcmcia_callback */
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
 {
@@ -2085,14 +1915,12 @@ EXPORT_SYMBOL(pcmcia_set_event_mask);
     
 ======================================================================*/
 /* in alpha order */
-EXPORT_SYMBOL(pcmcia_deregister_client);
 EXPORT_SYMBOL(pcmcia_eject_card);
 EXPORT_SYMBOL(pcmcia_get_card_services_info);
 EXPORT_SYMBOL(pcmcia_get_mem_page);
 EXPORT_SYMBOL(pcmcia_insert_card);
 EXPORT_SYMBOL(pcmcia_map_mem_page);
 EXPORT_SYMBOL(pcmcia_modify_configuration);
-EXPORT_SYMBOL(pcmcia_register_client);
 EXPORT_SYMBOL(pcmcia_release_configuration);
 EXPORT_SYMBOL(pcmcia_release_io);
 EXPORT_SYMBOL(pcmcia_release_irq);
diff -puN drivers/pcmcia/cs_internal.h~pcmcia-b18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cs_internal.h
--- 25/drivers/pcmcia/cs_internal.h~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.420510696 -0800
+++ 25-akpm/drivers/pcmcia/cs_internal.h	2004-11-30 01:23:21.445506896 -0800
@@ -1,19 +1,15 @@
 /*
- * cs_internal.h 1.57 2002/10/24 06:11:43
+ * cs_internal.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
- *  are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ * (C) 1999		David A. Hinds
  */
 
 #ifndef _LINUX_CS_INTERNAL_H
diff -puN drivers/pcmcia/ds.c~pcmcia-b18a-client_t-and-pcmcia_device-integration drivers/pcmcia/ds.c
--- 25/drivers/pcmcia/ds.c~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.422510392 -0800
+++ 25-akpm/drivers/pcmcia/ds.c	2004-11-30 01:23:21.448506440 -0800
@@ -33,6 +33,7 @@
 #include <linux/pci.h>
 #include <linux/list.h>
 #include <linux/delay.h>
+#include <linux/kref.h>
 #include <linux/workqueue.h>
 
 #include <asm/atomic.h>
@@ -86,7 +87,7 @@ typedef struct user_info_t {
 
 /* Socket state information */
 struct pcmcia_bus_socket {
-	atomic_t		refcount;
+	struct kref		refcount;
 	struct pcmcia_callback	callback;
 	int			state;
 	user_info_t		*user;
@@ -109,6 +110,8 @@ static spinlock_t pcmcia_dev_list_lock;
 
 static int major_dev = -1;
 
+static int unbind_request(struct pcmcia_bus_socket *s);
+
 /*====================================================================*/
 
 /* code which was in cs.c before */
@@ -254,22 +257,22 @@ EXPORT_SYMBOL(cs_error);
 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info);
 static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr);
 
-static void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s)
+static void pcmcia_release_bus_socket(struct kref *refcount)
 {
-	if (atomic_dec_and_test(&s->refcount))
-		kfree(s);
+	struct pcmcia_bus_socket *s = container_of(refcount, struct pcmcia_bus_socket, refcount);
+	pcmcia_put_socket(s->parent);
+	kfree(s);
 }
 
-static struct pcmcia_bus_socket *pcmcia_get_bus_socket(int nr)
+static void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s)
 {
-	struct pcmcia_bus_socket *s;
+	kref_put(&s->refcount, pcmcia_release_bus_socket);
+}
 
-	s = get_socket_info_by_nr(nr);
-	if (s) {
-		WARN_ON(atomic_read(&s->refcount) == 0);
-		atomic_inc(&s->refcount);
-	}
-	return s;
+static struct pcmcia_bus_socket *pcmcia_get_bus_socket(struct pcmcia_bus_socket *s)
+{
+	kref_get(&s->refcount);
+	return (s);
 }
 
 /**
@@ -350,6 +353,7 @@ static void pcmcia_put_dev(struct pcmcia
 static void pcmcia_release_dev(struct device *dev)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	pcmcia_put_bus_socket(p_dev->socket->pcmcia);
 	kfree(p_dev);
 }
 
@@ -406,21 +410,48 @@ static int handle_request(struct pcmcia_
     The card status event handler.
     
 ======================================================================*/
+struct send_event_data {
+	struct pcmcia_socket *skt;
+	event_t event;
+	int priority;
+};
+
+static int send_event_callback(struct device *dev, void * _data)
+{
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	struct send_event_data *data = _data;
+
+	/* we get called for all sockets, but may only pass the event
+	 * for drivers _on the affected socket_ */
+	if (p_dev->socket != data->skt)
+		return 0;
+
+	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);
+
+	return 0;
+}
 
 static int send_event(struct pcmcia_socket *s, event_t event, int priority)
 {
 	int ret = 0;
-	client_t *client;
+	struct send_event_data private;
+	struct pcmcia_bus_socket *skt = pcmcia_get_bus_socket(s->pcmcia);
+
+	if (!skt)
+		return 0;
+
+	private.skt = s;
+	private.event = event;
+	private.priority = priority;
+
+	ret = bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback);
+
+	pcmcia_put_bus_socket(skt);
 
-	for (client = s->clients; client; client = client->next) {
-		if (client->state & (CLIENT_UNBOUND|CLIENT_STALE))
-			continue;
-		if (client->EventMask & event) {
-			ret = EVENT(client, event, priority);
-			if (ret != 0)
-				return ret;
-		}
-	}
 	return ret;
 } /* send_event */
 
@@ -443,6 +474,7 @@ static int ds_event(struct pcmcia_socket
 	case CS_EVENT_CARD_REMOVAL:
 		s->state &= ~DS_SOCKET_PRESENT;
 	    	send_event(skt, event, priority);
+		unbind_request(s);
 		handle_event(s, event);
 		break;
 	
@@ -499,8 +531,9 @@ static int bind_mtd(struct pcmcia_bus_so
 
 /*======================================================================
 
-    bind_request() and bind_device() are merged by now. Individual
-    descriptions:
+    bind_request() and bind_device() are merged by now. Register_client()
+    is called right at the end of bind_request(), during the driver's
+    ->attach() call. Individual descriptions:
 
     bind_request() connects a socket to a particular client driver.
     It looks up the specified device ID in the list of registered
@@ -512,6 +545,11 @@ static int bind_mtd(struct pcmcia_bus_so
     a newly inserted card.  An instance of that driver will then be
     eligible to register as a client of this socket.
 
+    Register_client() uses the dev_info_t handle to match the
+    caller with a socket.  The driver must have already been bound
+    to a socket with bind_device() -- in fact, bind_device()
+    allocates the client structure that will be used.
+
 ======================================================================*/
 
 static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
@@ -561,8 +599,16 @@ static int bind_request(struct pcmcia_bu
 	}
 	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->func   = bind_info->function;
+	p_dev->client = client;
 
 	p_dev->dev.bus = &pcmcia_bus_type;
 	p_dev->dev.parent = s->parent->dev.dev;
@@ -573,6 +619,7 @@ static int bind_request(struct pcmcia_bu
 	ret = device_register(&p_dev->dev);
 	if (ret) {
 		kfree(p_dev);
+		pcmcia_put_bus_socket(s);
 		goto err_free_client;
 	}
 
@@ -618,6 +665,103 @@ static int bind_request(struct pcmcia_bu
 	return (ret);
 } /* bind_request */
 
+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) {
+		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;
+			}
+		}
+		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+		pcmcia_put_bus_socket(skt);
+	}
+ found:
+	up_read(&pcmcia_socket_list_rwsem);
+	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.
+	 */
+	down(&s->skt_sem);
+	*handle = client;
+	client->state &= ~CLIENT_UNBOUND;
+	client->Socket = s;
+	client->Attributes = req->Attributes;
+	client->EventMask = req->EventMask;
+	client->event_handler = req->event_handler;
+	client->event_callback_args = req->event_callback_args;
+	client->event_callback_args.client_handle = client;
+
+	if (s->state & SOCKET_CARDBUS)
+		client->state |= CLIENT_CARDBUS;
+
+	if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) &&
+	    (client->Function != BIND_FN_ALL)) {
+		cistpl_longlink_mfc_t mfc;
+		if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc)
+		    == CS_SUCCESS)
+			s->functions = mfc.nfn;
+		else
+			s->functions = 1;
+		s->config = kmalloc(sizeof(config_t) * s->functions,
+				    GFP_KERNEL);
+		if (!s->config)
+			goto out_no_resource;
+		memset(s->config, 0, sizeof(config_t) * s->functions);
+	}
+
+	ds_dbg(1, "register_client(): client 0x%p, dev %s\n",
+	       client, client->dev_info);
+	if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
+		EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
+
+	if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) {
+		if (client->EventMask & CS_EVENT_CARD_INSERTION)
+			EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
+		else
+			client->PendingEvents |= CS_EVENT_CARD_INSERTION;
+	}
+
+	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);
+
+
 /*====================================================================*/
 
 extern struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s);
@@ -709,40 +853,86 @@ static int get_device_info(struct pcmcia
 
 /*====================================================================*/
 
-static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
+/* unbind _all_ devices attached to a given pcmcia_bus_socket. The
+ * drivers have been called with EVENT_CARD_REMOVAL before.
+ */
+static int unbind_request(struct pcmcia_bus_socket *s)
 {
 	struct pcmcia_device	*p_dev;
 	struct pcmcia_driver	*p_drv;
 	unsigned long		flags;
 
-	ds_dbg(2, "unbind_request(%d, '%s')\n", s->parent->sock,
-	       (char *)bind_info->dev_info);
+	ds_dbg(2, "unbind_request(%d)\n", s->parent->sock);
+
+	for (;;) {
+		/* unregister all pcmcia_devices registered with this socket*/
+		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+		if (list_empty(&s->devices_list)) {
+			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ 			return 0;
+		}
+		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;
+		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+
+		/* detach the "instance" */
+		p_drv = to_pcmcia_drv(p_dev->dev.driver);
+		if (p_drv) {
+			if ((p_drv->detach) && (p_dev->instance))
+				p_drv->detach(p_dev->instance);
+			module_put(p_drv->owner);
+		}
+
+		device_unregister(&p_dev->dev);
+  	}
 
-	/* unregister the pcmcia_device */
-	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
-	list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
-		if (p_dev->func == bind_info->function)
-			goto found;
-	}
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 	return 0;
+} /* unbind_request */
 
- found:
-	list_del(&p_dev->socket_device_list);
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+int pcmcia_deregister_client(client_handle_t handle)
+{
+	client_t **client;
+	struct pcmcia_socket *s;
+	u_long flags;
+	int i;
 
-	/* detach the "instance" */
-	p_drv = to_pcmcia_drv(p_dev->dev.driver);
-	if (p_drv) {
-		if ((p_drv->detach) && (p_dev->instance))
-			p_drv->detach(p_dev->instance);
-		module_put(p_drv->owner);
+	if (CHECK_HANDLE(handle))
+		return CS_BAD_HANDLE;
+
+	s = SOCKET(handle);
+	ds_dbg(1, "deregister_client(%p)\n", handle);
+
+	if (handle->state &
+	    (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
+		return CS_IN_USE;
+	for (i = 0; i < MAX_WIN; i++)
+		if (handle->state & CLIENT_WIN_REQ(i))
+			return CS_IN_USE;
+
+	if ((handle->state & CLIENT_STALE) ||
+	    (handle->Attributes & INFO_MASTER_CLIENT)) {
+		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);
+	} else {
+		handle->state = CLIENT_UNBOUND;
+		handle->event_handler = NULL;
 	}
 
-	device_unregister(&p_dev->dev);
+	return CS_SUCCESS;
+} /* deregister_client */
+EXPORT_SYMBOL(pcmcia_deregister_client);
 
-	return 0;
-} /* unbind_request */
 
 /*======================================================================
 
@@ -758,19 +948,27 @@ static int ds_open(struct inode *inode, 
 
     ds_dbg(0, "ds_open(socket %d)\n", i);
 
-    s = pcmcia_get_bus_socket(i);
+    s = get_socket_info_by_nr(i);
+    if (!s)
+	    return -ENODEV;
+    s = pcmcia_get_bus_socket(s);
     if (!s)
 	    return -ENODEV;
 
     if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
-	if (s->state & DS_SOCKET_BUSY)
-	    return -EBUSY;
+	    if (s->state & DS_SOCKET_BUSY) {
+		    pcmcia_put_bus_socket(s);
+		    return -EBUSY;
+	    }
 	else
 	    s->state |= DS_SOCKET_BUSY;
     }
     
     user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
-    if (!user) return -ENOMEM;
+    if (!user) {
+	    pcmcia_put_bus_socket(s);
+	    return -ENOMEM;
+    }
     user->event_tail = user->event_head = 0;
     user->next = s->user;
     user->user_magic = USER_MAGIC;
@@ -1051,7 +1249,7 @@ static int ds_ioctl(struct inode * inode
 	err = get_device_info(s, &buf.bind_info, 0);
 	break;
     case DS_UNBIND_REQUEST:
-	err = unbind_request(s, &buf.bind_info);
+	err = 0;
 	break;
     case DS_BIND_MTD:
 	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
@@ -1105,7 +1303,7 @@ static struct file_operations ds_fops = 
 
 static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
 {
-	struct pcmcia_socket *socket = class_dev->class_data;
+	struct pcmcia_socket *socket = class_get_devdata(class_dev);
 	struct pcmcia_bus_socket *s;
 	int ret;
 
@@ -1113,7 +1311,16 @@ static int __devinit pcmcia_bus_add_sock
 	if(!s)
 		return -ENOMEM;
 	memset(s, 0, sizeof(struct pcmcia_bus_socket));
-	atomic_set(&s->refcount, 1);
+
+	/* get reference to parent socket */
+	s->parent = pcmcia_get_socket(socket);
+	if (!s->parent) {
+		printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket);
+		kfree (s);
+		return -ENODEV;
+	}
+
+	kref_init(&s->refcount);
     
 	/*
 	 * Ugly. But we want to wait for the socket threads to have started up.
@@ -1125,9 +1332,6 @@ static int __devinit pcmcia_bus_add_sock
 	init_waitqueue_head(&s->request);
 	INIT_LIST_HEAD(&s->devices_list);
 
-	/* initialize data */
-	s->parent = socket;
-
 	/* Set up hotline to Card Services */
 	s->callback.owner = THIS_MODULE;
 	s->callback.event = &ds_event;
@@ -1147,7 +1351,7 @@ static int __devinit pcmcia_bus_add_sock
 
 static void pcmcia_bus_remove_socket(struct class_device *class_dev)
 {
-	struct pcmcia_socket *socket = class_dev->class_data;
+	struct pcmcia_socket *socket = class_get_devdata(class_dev);
 
 	if (!socket || !socket->pcmcia)
 		return;
diff -puN drivers/pcmcia/rsrc_mgr.c~pcmcia-b18a-client_t-and-pcmcia_device-integration drivers/pcmcia/rsrc_mgr.c
--- 25/drivers/pcmcia/rsrc_mgr.c~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.423510240 -0800
+++ 25-akpm/drivers/pcmcia/rsrc_mgr.c	2004-11-30 01:23:21.450506136 -0800
@@ -1,35 +1,16 @@
-/*======================================================================
-
-    Resource management routines
-
-    rsrc_mgr.c 1.79 2000/08/30 20:23:58
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    The initial developer of the original code is David A. Hinds
-    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * rsrc_mgr.c -- Resource management routines
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ * (C) 1999		David A. Hinds
+ */
 
 #include <linux/config.h>
 #include <linux/module.h>
diff -puN include/pcmcia/bulkmem.h~pcmcia-b18a-client_t-and-pcmcia_device-integration include/pcmcia/bulkmem.h
--- 25/include/pcmcia/bulkmem.h~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.424510088 -0800
+++ 25-akpm/include/pcmcia/bulkmem.h	2004-11-30 01:23:21.450506136 -0800
@@ -1,33 +1,15 @@
 /*
- * Definitions for bulk memory services
+ * bulkmem.h -- Definitions for bulk memory services
  *
- * bulkmem.h 1.12 2000/06/12 21:55:41
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- * bulkmem.h 1.3 1995/05/27 04:49:49
+ * (C) 1999		David A. Hinds
  */
 
 #ifndef _LINUX_BULKMEM_H
diff -puN include/pcmcia/ciscode.h~pcmcia-b18a-client_t-and-pcmcia_device-integration include/pcmcia/ciscode.h
--- 25/include/pcmcia/ciscode.h~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.426509784 -0800
+++ 25-akpm/include/pcmcia/ciscode.h	2004-11-30 01:23:21.451505984 -0800
@@ -1,30 +1,15 @@
 /*
- * ciscode.h 1.56 2002/10/25 06:37:30
+ * ciscode.h -- Definitions for bulk memory services
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999		David A. Hinds
  */
 
 #ifndef _LINUX_CISCODE_H
diff -puN include/pcmcia/cisreg.h~pcmcia-b18a-client_t-and-pcmcia_device-integration include/pcmcia/cisreg.h
--- 25/include/pcmcia/cisreg.h~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.427509632 -0800
+++ 25-akpm/include/pcmcia/cisreg.h	2004-11-30 01:23:21.451505984 -0800
@@ -1,30 +1,15 @@
 /*
- * cisreg.h 1.17 2000/06/12 21:55:41
+ * cisreg.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_CISREG_H
diff -puN include/pcmcia/cistpl.h~pcmcia-b18a-client_t-and-pcmcia_device-integration include/pcmcia/cistpl.h
--- 25/include/pcmcia/cistpl.h~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.428509480 -0800
+++ 25-akpm/include/pcmcia/cistpl.h	2004-11-30 01:23:21.452505832 -0800
@@ -1,30 +1,15 @@
 /*
- * cistpl.h 1.34 2000/06/19 23:18:12
+ * cistpl.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_CISTPL_H
diff -puN include/pcmcia/cs.h~pcmcia-b18a-client_t-and-pcmcia_device-integration include/pcmcia/cs.h
--- 25/include/pcmcia/cs.h~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.430509176 -0800
+++ 25-akpm/include/pcmcia/cs.h	2004-11-30 01:23:21.453505680 -0800
@@ -1,30 +1,15 @@
 /*
- * cs.h 1.71 2000/08/29 00:54:20
+ * cs.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_CS_H
@@ -441,6 +426,9 @@ int pcmcia_modify_window(window_handle_t
 int pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask);
 #endif
 
+struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt);
+void pcmcia_put_socket(struct pcmcia_socket *skt);
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_CS_H */
diff -puN include/pcmcia/cs_types.h~pcmcia-b18a-client_t-and-pcmcia_device-integration include/pcmcia/cs_types.h
--- 25/include/pcmcia/cs_types.h~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.431509024 -0800
+++ 25-akpm/include/pcmcia/cs_types.h	2004-11-30 01:23:21.453505680 -0800
@@ -1,30 +1,15 @@
 /*
- * cs_types.h 1.18 2000/06/12 21:55:40
+ * cs_types.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_CS_TYPES_H
diff -puN include/pcmcia/ds.h~pcmcia-b18a-client_t-and-pcmcia_device-integration include/pcmcia/ds.h
--- 25/include/pcmcia/ds.h~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.433508720 -0800
+++ 25-akpm/include/pcmcia/ds.h	2004-11-30 01:23:21.454505528 -0800
@@ -128,6 +128,7 @@ typedef struct dev_link_t {
 
 
 struct pcmcia_socket;
+struct client_t;
 
 extern struct bus_type pcmcia_bus_type;
 
@@ -153,6 +154,7 @@ struct pcmcia_device {
 	/* deprecated, a cleaned up version will be moved into this
 	   struct soon */
 	dev_link_t		*instance;
+	struct client_t		*client;
 
 	struct device		dev;
 };
diff -puN include/pcmcia/mem_op.h~pcmcia-b18a-client_t-and-pcmcia_device-integration include/pcmcia/mem_op.h
--- 25/include/pcmcia/mem_op.h~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.434508568 -0800
+++ 25-akpm/include/pcmcia/mem_op.h	2004-11-30 01:23:21.454505528 -0800
@@ -1,30 +1,15 @@
 /*
- * mem_op.h 1.13 2000/06/12 21:55:40
+ * mem_op.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_MEM_OP_H
diff -puN include/pcmcia/ss.h~pcmcia-b18a-client_t-and-pcmcia_device-integration include/pcmcia/ss.h
--- 25/include/pcmcia/ss.h~pcmcia-b18a-client_t-and-pcmcia_device-integration	2004-11-30 01:23:21.435508416 -0800
+++ 25-akpm/include/pcmcia/ss.h	2004-11-30 01:23:21.455505376 -0800
@@ -1,30 +1,15 @@
 /*
- * ss.h 1.28 2000/06/12 21:55:40
+ * ss.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * The initial developer of the original code is David A. Hinds
  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_SS_H
_