From: Dominik Brodowski <linux@dominikbrodowski.de>

01-move-and-remove-stuff

Move pcmcia_{de,}register_client() from cs.c to ds.c, and remove the unused
pcmcia_get_{first,next}_client() calls -- they would be an unnecessary
hassle to deal with in the next patches.

02-license

As discussed previously, my integration of ds.c and cs.c with the driver
model can and will only be available under the GPL, as it's too much
derived of other buses' implementation of integration with the driver
model.

cs_internal.h did only contain the MPL header before - I contacted Dave
Hinds because of this, and as far as he can tell, it was just an oversight
that this was not marked as dual-licensed as the other files are.

03-ds-kref

Switch pcmcia_bus_socket's reference counting to struct kref.  Also, split
the access by number into two calls, so that get_bus_socket can be used in
a more generic way.

04-cs-class_dev

Add pcmcia_{put,get}_socket

05-ds-grab-cs-ref

Grab a reference of struct pcmcia_socket for every struct
pcmcia_bus_socket.

06-ds-get-ref-for-p_dev

Obtain a reference to struct pcmcia_bus_socket for each pcmcia_device. 
This means that pcmcia_device always holds an indirect reference to struct
pcmcia_socket as well.

07-p_dev-client-pointer

Add a pointer to the "client" structure to struct pcmcia_device.

08-send_event-p_dev

Use a struct pcmcia_device-based approach to inform "clients" of events. 
It needs to be done using bus_for_each_device() so that we don't need to
take the device_list spinlock.

09-removal-p_dev

Use pcmcia_dev instead of the "client" single-linked list to mark clients
as stale.

10-move-inside-ds

Move some code around in ds.c.  Avoids forward-declarations, and keeps
related code close to each other.

11-register_client-p_dev

Search the devices_list for an UNBOUND client in register_client, instead
of the single linked list clients.

12-direct_ordered_unbind

Restructure unbind_request():
Before, unbind_request was called by cardmgr on the following occasions:
a) if the CS_EVENT_CARD_INSERTION event failed
b) during do_remove(), which is called on
	1) when cardmgr is informed of a CS_EVENT_CARD_REMOVAL event
	2) when cardmgr is informed of a CS_EVENT_EJECTION_REQUEST event, if
	   do_check() succeeds
	3) cardmgr exit (SIGINT/SIGTERM), if do_check() succeeds

We can ignore a), as the user is informed of the problem anyway, and can
take appropriate action then (eject the card, update config, write new
driver, insert card...).

b1) can be done directly, even before the userspace cardmgr is
    informed.  This speeds up the call to ->detach().

b2) All drivers I checked were based on the assumption that a
    CS_EVENT_CARD_REMOVAL event is received _first_, before a call to
    ->detach().  Most notably, some drivers issue first a call to their
    release() function [which else is called during EVENT_CARD_REMOVAL]
    during ->detach() if it hasn't been issued before.  So, it doesn't hurt
    if unbind is only called during the EVENT_CARD_REMOVAL step, and not
    during EJECTION_REQUEST.  The REMOVAL step is only called anyway if
    EJECTION_REQUEST succeeds, and the latter can only succeed if
    do_check() succeeds.

b3) If cardmgr exits, ds_release() is called.  We can check for any
    16-bit devices there, and call a CARD_REMOVAL event there.  Only
    difference is that a failure of do_check() does not block CARD_REMOVAL.
     IMHO this is accepatble.

Consequences:
- call unbind_request during CARD_REMOVAL handling, even before userspace
  is informed.
- return "0" if UNBIND_REQUEST is called from userspace.
- clean up 16-bit pcmcia devices existing during cardmgr exit
- the driver's event handler is called with CARD_REMOVAL _always_ before
  ->detach() is called.

Signed-off-by: Dominik Brodowski <linux@brodo.de>
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          |  329 +++++++++++++++++++++++++++++------
 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, 419 insertions(+), 572 deletions(-)

diff -puN drivers/pcmcia/bulkmem.c~pcmcia-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/bulkmem.c
--- 25/drivers/pcmcia/bulkmem.c~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/drivers/pcmcia/bulkmem.c	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cardbus.c
--- 25/drivers/pcmcia/cardbus.c~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/drivers/pcmcia/cardbus.c	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cistpl.c
--- 25/drivers/pcmcia/cistpl.c~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/drivers/pcmcia/cistpl.c	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cs.c
--- 25/drivers/pcmcia/cs.c~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/drivers/pcmcia/cs.c	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/cs_internal.h
--- 25/drivers/pcmcia/cs_internal.h~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/drivers/pcmcia/cs_internal.h	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/ds.c
--- 25/drivers/pcmcia/ds.c~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/drivers/pcmcia/ds.c	Wed Nov  3 16:11:54 2004
@@ -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;
@@ -111,6 +112,8 @@ static int major_dev = -1;
 
 static struct proc_dir_entry *proc_pccard;
 
+static int unbind_request(struct pcmcia_bus_socket *s);
+
 /*====================================================================*/
 
 /* code which was in cs.c before */
@@ -256,22 +259,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);
 }
 
 /**
@@ -347,6 +350,7 @@ static inline void put_p_dev(struct pcmc
 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);
 }
 
@@ -403,21 +407,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 */
 
@@ -440,6 +471,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;
 	
@@ -496,8 +528,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
@@ -509,6 +542,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)
@@ -554,12 +592,21 @@ static int bind_request(struct pcmcia_bu
 	p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
 	if (!p_dev) {
 		ret = -ENOMEM;
+		pcmcia_put_bus_socket(s);
 		goto err_free_client;
 	}
 	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;
@@ -570,6 +617,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;
 	}
 
@@ -615,6 +663,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 = get_p_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);
+	put_p_dev(p_dev); /* FIXME: put in deregister_client. */
+	return CS_SUCCESS;
+
+ out_no_resource:
+	up(&s->skt_sem);
+	put_p_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);
@@ -706,40 +851,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);
 
-	/* 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;
+	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) {
+			module_put(p_drv->owner);
+			if ((p_drv->detach) && (p_dev->instance))
+				p_drv->detach(p_dev->instance);
+		}
+
+		device_unregister(&p_dev->dev);
 	}
-	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) {
-		module_put(p_drv->owner);
-		if ((p_drv->detach) && (p_dev->instance))
-			p_drv->detach(p_dev->instance);
+	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 */
 
 /*======================================================================
 
@@ -755,19 +946,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;
@@ -786,6 +985,8 @@ static int ds_release(struct inode *inod
 {
     struct pcmcia_bus_socket *s;
     user_info_t *user, **link;
+    unsigned long flags;
+    unsigned int has_p_devs = 0;
 
     ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
 
@@ -795,6 +996,16 @@ static int ds_release(struct inode *inod
 
     s = user->socket;
 
+    /* if 16-bit devices are associated with this device, remove them */
+    down(&s->parent->skt_sem);
+    spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+    if (!list_empty(&s->devices_list))
+	    has_p_devs = 1;
+    spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+    if (has_p_devs)
+	    ds_event(s->parent, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
+    up(&s->parent->skt_sem);
+
     /* Unlink user data structure */
     if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
 	s->state &= ~DS_SOCKET_BUSY;
@@ -1048,7 +1259,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;
@@ -1102,7 +1313,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;
 
@@ -1110,7 +1321,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.
@@ -1122,9 +1342,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;
@@ -1144,7 +1361,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-18a-client_t-and-pcmcia_device-integration drivers/pcmcia/rsrc_mgr.c
--- 25/drivers/pcmcia/rsrc_mgr.c~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/drivers/pcmcia/rsrc_mgr.c	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration include/pcmcia/bulkmem.h
--- 25/include/pcmcia/bulkmem.h~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/include/pcmcia/bulkmem.h	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration include/pcmcia/ciscode.h
--- 25/include/pcmcia/ciscode.h~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/include/pcmcia/ciscode.h	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration include/pcmcia/cisreg.h
--- 25/include/pcmcia/cisreg.h~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/include/pcmcia/cisreg.h	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration include/pcmcia/cistpl.h
--- 25/include/pcmcia/cistpl.h~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/include/pcmcia/cistpl.h	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration include/pcmcia/cs.h
--- 25/include/pcmcia/cs.h~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/include/pcmcia/cs.h	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration include/pcmcia/cs_types.h
--- 25/include/pcmcia/cs_types.h~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/include/pcmcia/cs_types.h	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration include/pcmcia/ds.h
--- 25/include/pcmcia/ds.h~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/include/pcmcia/ds.h	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration include/pcmcia/mem_op.h
--- 25/include/pcmcia/mem_op.h~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/include/pcmcia/mem_op.h	Wed Nov  3 16:11:54 2004
@@ -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-18a-client_t-and-pcmcia_device-integration include/pcmcia/ss.h
--- 25/include/pcmcia/ss.h~pcmcia-18a-client_t-and-pcmcia_device-integration	Wed Nov  3 16:11:54 2004
+++ 25-akpm/include/pcmcia/ss.h	Wed Nov  3 16:11:54 2004
@@ -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
_