From: Dominik Brodowski <linux@dominikbrodowski.net>

Convert all in-kernel drivers to use the one-step removal function

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 drivers/bluetooth/bluecard_cs.c         |   24 +++--------------
 drivers/bluetooth/bt3c_cs.c             |   24 +++--------------
 drivers/bluetooth/btuart_cs.c           |   24 +++--------------
 drivers/bluetooth/dtl1_cs.c             |   24 +++--------------
 drivers/char/pcmcia/synclink_cs.c       |   34 +++++--------------------
 drivers/ide/legacy/ide-cs.c             |   21 +++------------
 drivers/isdn/hardware/avm/avm_cs.c      |   36 +++++---------------------
 drivers/isdn/hisax/avma1_cs.c           |   39 +++++------------------------
 drivers/isdn/hisax/elsa_cs.c            |   26 +++++--------------
 drivers/isdn/hisax/sedlbauer_cs.c       |   38 +++++-----------------------
 drivers/isdn/hisax/teles_cs.c           |   26 +++++--------------
 drivers/mtd/maps/pcmciamtd.c            |   36 ++++++++------------------
 drivers/net/pcmcia/3c574_cs.c           |   18 +++----------
 drivers/net/pcmcia/3c589_cs.c           |   20 ++++----------
 drivers/net/pcmcia/axnet_cs.c           |   18 +++----------
 drivers/net/pcmcia/com20020_cs.c        |   19 +++-----------
 drivers/net/pcmcia/fmvj18x_cs.c         |   19 +++-----------
 drivers/net/pcmcia/ibmtr_cs.c           |   23 +++--------------
 drivers/net/pcmcia/nmclan_cs.c          |   18 +++----------
 drivers/net/pcmcia/smc91c92_cs.c        |   18 +++----------
 drivers/net/pcmcia/xirc2ps_cs.c         |   28 +++-----------------
 drivers/net/wireless/airo_cs.c          |   31 ++++++-----------------
 drivers/net/wireless/atmel_cs.c         |   25 +++++-------------
 drivers/net/wireless/hostap/hostap_cs.c |   28 +++-----------------
 drivers/net/wireless/netwave_cs.c       |   31 +++++------------------
 drivers/net/wireless/orinoco_cs.c       |   30 ++++------------------
 drivers/net/wireless/ray_cs.c           |   43 +++++++++++---------------------
 drivers/net/wireless/wavelan_cs.c       |   31 +++--------------------
 drivers/net/wireless/wavelan_cs.p.h     |    2 -
 drivers/net/wireless/wl3501_cs.c        |   32 +++++++----------------
 drivers/parport/parport_cs.c            |   26 +++++--------------
 drivers/scsi/pcmcia/aha152x_stub.c      |   17 +++---------
 drivers/scsi/pcmcia/fdomain_stub.c      |   17 +++---------
 drivers/scsi/pcmcia/nsp_cs.c            |   23 ++++-------------
 drivers/scsi/pcmcia/nsp_cs.h            |    2 -
 drivers/scsi/pcmcia/qlogic_stub.c       |   17 +++---------
 drivers/scsi/pcmcia/sym53c500_cs.c      |   15 ++---------
 drivers/serial/serial_cs.c              |   19 +++-----------
 drivers/telephony/ixj_pcmcia.c          |   24 +++++------------
 drivers/usb/host/sl811_cs.c             |   31 ++++++-----------------
 sound/pcmcia/pdaudiocf/pdaudiocf.c      |   21 +++------------
 sound/pcmcia/vx/vxpocket.c              |   17 ++----------
 42 files changed, 256 insertions(+), 759 deletions(-)

diff -puN drivers/bluetooth/bluecard_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/bluetooth/bluecard_cs.c
--- devel/drivers/bluetooth/bluecard_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/bluetooth/bluecard_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -92,7 +92,7 @@ static int bluecard_event(event_t event,
 static dev_info_t dev_info = "bluecard_cs";
 
 static dev_link_t *bluecard_attach(void);
-static void bluecard_detach(dev_link_t *);
+static void bluecard_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list = NULL;
 
@@ -900,7 +900,7 @@ static dev_link_t *bluecard_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		bluecard_detach(link);
+		bluecard_detach(link->handle);
 		return NULL;
 	}
 
@@ -908,11 +908,11 @@ static dev_link_t *bluecard_attach(void)
 }
 
 
-static void bluecard_detach(dev_link_t *link)
+static void bluecard_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	bluecard_info_t *info = link->priv;
 	dev_link_t **linkp;
-	int ret;
 
 	/* Locate device structure */
 	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
@@ -925,12 +925,6 @@ static void bluecard_detach(dev_link_t *
 	if (link->state & DEV_CONFIG)
 		bluecard_release(link);
 
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
 	/* Unlink device structure, free bits */
 	*linkp = link->next;
 
@@ -1071,16 +1065,8 @@ static int bluecard_resume(struct pcmcia
 static int bluecard_event(event_t event, int priority, event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	bluecard_info_t *info = link->priv;
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			bluecard_close(info);
-			bluecard_release(link);
-		}
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		bluecard_config(link);
@@ -1105,7 +1091,7 @@ static struct pcmcia_driver bluecard_dri
 	},
 	.attach		= bluecard_attach,
 	.event		= bluecard_event,
-	.detach		= bluecard_detach,
+	.remove		= bluecard_detach,
 	.id_table	= bluecard_ids,
 	.suspend	= bluecard_suspend,
 	.resume		= bluecard_resume,
diff -puN drivers/bluetooth/bt3c_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/bluetooth/bt3c_cs.c
--- devel/drivers/bluetooth/bt3c_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/bluetooth/bt3c_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -95,7 +95,7 @@ static int bt3c_event(event_t event, int
 static dev_info_t dev_info = "bt3c_cs";
 
 static dev_link_t *bt3c_attach(void);
-static void bt3c_detach(dev_link_t *);
+static void bt3c_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list = NULL;
 
@@ -701,7 +701,7 @@ static dev_link_t *bt3c_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		bt3c_detach(link);
+		bt3c_detach(link->handle);
 		return NULL;
 	}
 
@@ -709,11 +709,11 @@ static dev_link_t *bt3c_attach(void)
 }
 
 
-static void bt3c_detach(dev_link_t *link)
+static void bt3c_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	bt3c_info_t *info = link->priv;
 	dev_link_t **linkp;
-	int ret;
 
 	/* Locate device structure */
 	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
@@ -726,12 +726,6 @@ static void bt3c_detach(dev_link_t *link
 	if (link->state & DEV_CONFIG)
 		bt3c_release(link);
 
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
 	/* Unlink device structure, free bits */
 	*linkp = link->next;
 
@@ -917,16 +911,8 @@ static int bt3c_resume(struct pcmcia_dev
 static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	bt3c_info_t *info = link->priv;
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			bt3c_close(info);
-			bt3c_release(link);
-		}
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		bt3c_config(link);
@@ -949,7 +935,7 @@ static struct pcmcia_driver bt3c_driver 
 	},
 	.attach		= bt3c_attach,
 	.event		= bt3c_event,
-	.detach		= bt3c_detach,
+	.remove		= bt3c_detach,
 	.id_table	= bt3c_ids,
 	.suspend	= bt3c_suspend,
 	.resume		= bt3c_resume,
diff -puN drivers/bluetooth/btuart_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/bluetooth/btuart_cs.c
--- devel/drivers/bluetooth/btuart_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/bluetooth/btuart_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -91,7 +91,7 @@ static int btuart_event(event_t event, i
 static dev_info_t dev_info = "btuart_cs";
 
 static dev_link_t *btuart_attach(void);
-static void btuart_detach(dev_link_t *);
+static void btuart_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list = NULL;
 
@@ -620,7 +620,7 @@ static dev_link_t *btuart_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		btuart_detach(link);
+		btuart_detach(link->handle);
 		return NULL;
 	}
 
@@ -628,11 +628,11 @@ static dev_link_t *btuart_attach(void)
 }
 
 
-static void btuart_detach(dev_link_t *link)
+static void btuart_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	btuart_info_t *info = link->priv;
 	dev_link_t **linkp;
-	int ret;
 
 	/* Locate device structure */
 	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
@@ -645,12 +645,6 @@ static void btuart_detach(dev_link_t *li
 	if (link->state & DEV_CONFIG)
 		btuart_release(link);
 
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
 	/* Unlink device structure, free bits */
 	*linkp = link->next;
 
@@ -838,16 +832,8 @@ static int btuart_resume(struct pcmcia_d
 static int btuart_event(event_t event, int priority, event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	btuart_info_t *info = link->priv;
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			btuart_close(info);
-			btuart_release(link);
-		}
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		btuart_config(link);
@@ -870,7 +856,7 @@ static struct pcmcia_driver btuart_drive
 	},
 	.attach		= btuart_attach,
 	.event		= btuart_event,
-	.detach		= btuart_detach,
+	.remove		= btuart_detach,
 	.id_table	= btuart_ids,
 	.suspend	= btuart_suspend,
 	.resume		= btuart_resume,
diff -puN drivers/bluetooth/dtl1_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/bluetooth/dtl1_cs.c
--- devel/drivers/bluetooth/dtl1_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/bluetooth/dtl1_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -94,7 +94,7 @@ static int dtl1_event(event_t event, int
 static dev_info_t dev_info = "dtl1_cs";
 
 static dev_link_t *dtl1_attach(void);
-static void dtl1_detach(dev_link_t *);
+static void dtl1_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list = NULL;
 
@@ -599,7 +599,7 @@ static dev_link_t *dtl1_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		dtl1_detach(link);
+		dtl1_detach(link->handle);
 		return NULL;
 	}
 
@@ -607,11 +607,11 @@ static dev_link_t *dtl1_attach(void)
 }
 
 
-static void dtl1_detach(dev_link_t *link)
+static void dtl1_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dtl1_info_t *info = link->priv;
 	dev_link_t **linkp;
-	int ret;
 
 	/* Locate device structure */
 	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
@@ -624,12 +624,6 @@ static void dtl1_detach(dev_link_t *link
 	if (link->state & DEV_CONFIG)
 		dtl1_release(link);
 
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
 	/* Unlink device structure, free bits */
 	*linkp = link->next;
 
@@ -789,16 +783,8 @@ static int dtl1_resume(struct pcmcia_dev
 static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	dtl1_info_t *info = link->priv;
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			dtl1_close(info);
-			dtl1_release(link);
-		}
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		dtl1_config(link);
@@ -822,7 +808,7 @@ static struct pcmcia_driver dtl1_driver 
 	},
 	.attach		= dtl1_attach,
 	.event		= dtl1_event,
-	.detach		= dtl1_detach,
+	.remove		= dtl1_detach,
 	.id_table	= dtl1_ids,
 	.suspend	= dtl1_suspend,
 	.resume		= dtl1_resume,
diff -puN drivers/char/pcmcia/synclink_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/char/pcmcia/synclink_cs.c
--- devel/drivers/char/pcmcia/synclink_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/char/pcmcia/synclink_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -489,7 +489,7 @@ static void mgslpc_release(u_long arg);
 static int  mgslpc_event(event_t event, int priority,
 			 event_callback_args_t *args);
 static dev_link_t *mgslpc_attach(void);
-static void mgslpc_detach(dev_link_t *);
+static void mgslpc_detach(struct pcmcia_device *p_dev);
 
 static dev_info_t dev_info = "synclink_cs";
 static dev_link_t *dev_list = NULL;
@@ -598,7 +598,7 @@ static dev_link_t *mgslpc_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != CS_SUCCESS) {
 	    cs_error(link->handle, RegisterClient, ret);
-	    mgslpc_detach(link);
+	    mgslpc_detach(link->handle);
 	    return NULL;
     }
 
@@ -736,17 +736,16 @@ static void mgslpc_release(u_long arg)
 	    pcmcia_release_io(link->handle, &link->io);
     if (link->irq.AssignedIRQ)
 	    pcmcia_release_irq(link->handle, &link->irq);
-    if (link->state & DEV_STALE_LINK)
-	    mgslpc_detach(link);
 }
 
-static void mgslpc_detach(dev_link_t *link)
+static void mgslpc_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
 
     if (debug_level >= DEBUG_LEVEL_INFO)
 	    printk("mgslpc_detach(0x%p)\n", link);
-    
+
     /* find device */
     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
 	    if (*linkp == link) break;
@@ -754,20 +753,10 @@ static void mgslpc_detach(dev_link_t *li
 	    return;
 
     if (link->state & DEV_CONFIG) {
-	    /* device is configured/active, mark it so when
-	     * release() is called a proper detach() occurs.
-	     */
-	    if (debug_level >= DEBUG_LEVEL_INFO)
-		    printk(KERN_DEBUG "synclinkpc: detach postponed, '%s' "
-			   "still locked\n", link->dev->dev_name);
-	    link->state |= DEV_STALE_LINK;
-	    return;
+	    ((MGSLPC_INFO *)link->priv)->stop = 1;
+	    mgslpc_release((u_long)link);
     }
 
-    /* Break the link with Card Services */
-    if (link->handle)
-	    pcmcia_deregister_client(link->handle);
-    
     /* Unlink device structure, and free it */
     *linkp = link->next;
     mgslpc_remove_device((MGSLPC_INFO *)link->priv);
@@ -809,13 +798,6 @@ static int mgslpc_event(event_t event, i
 	    printk("mgslpc_event(0x%06x)\n", event);
     
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	    link->state &= ~DEV_PRESENT;
-	    if (link->state & DEV_CONFIG) {
-		    ((MGSLPC_INFO *)link->priv)->stop = 1;
-		    mgslpc_release((u_long)link);
-	    }
-	    break;
     case CS_EVENT_CARD_INSERTION:
 	    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	    mgslpc_config(link);
@@ -3091,7 +3073,7 @@ static struct pcmcia_driver mgslpc_drive
 	},
 	.attach		= mgslpc_attach,
 	.event		= mgslpc_event,
-	.detach		= mgslpc_detach,
+	.remove		= mgslpc_detach,
 	.id_table	= mgslpc_ids,
 	.suspend	= mgslpc_suspend,
 	.resume		= mgslpc_resume,
diff -puN drivers/ide/legacy/ide-cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/ide/legacy/ide-cs.c
--- devel/drivers/ide/legacy/ide-cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/ide/legacy/ide-cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -93,7 +93,7 @@ static int ide_event(event_t event, int 
 static dev_info_t dev_info = "ide-cs";
 
 static dev_link_t *ide_attach(void);
-static void ide_detach(dev_link_t *);
+static void ide_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list = NULL;
 
@@ -138,7 +138,7 @@ static dev_link_t *ide_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != CS_SUCCESS) {
 	cs_error(link->handle, RegisterClient, ret);
-	ide_detach(link);
+	ide_detach(link->handle);
 	return NULL;
     }
     
@@ -154,10 +154,10 @@ static dev_link_t *ide_attach(void)
 
 ======================================================================*/
 
-static void ide_detach(dev_link_t *link)
+static void ide_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
-    int ret;
 
     DEBUG(0, "ide_detach(0x%p)\n", link);
     
@@ -170,12 +170,6 @@ static void ide_detach(dev_link_t *link)
     if (link->state & DEV_CONFIG)
 	ide_release(link);
     
-    if (link->handle) {
-	ret = pcmcia_deregister_client(link->handle);
-	if (ret != CS_SUCCESS)
-	    cs_error(link->handle, DeregisterClient, ret);
-    }
-    
     /* Unlink, free device structure */
     *linkp = link->next;
     kfree(link->priv);
@@ -446,11 +440,6 @@ int ide_event(event_t event, int priorit
     DEBUG(1, "ide_event(0x%06x)\n", event);
     
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-		ide_release(link);
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	ide_config(link);
@@ -505,7 +494,7 @@ static struct pcmcia_driver ide_cs_drive
 	},
 	.attach		= ide_attach,
 	.event		= ide_event,
-	.detach		= ide_detach,
+	.remove		= ide_detach,
 	.id_table       = ide_ids,
 	.suspend	= ide_suspend,
 	.resume		= ide_resume,
diff -puN drivers/isdn/hardware/avm/avm_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/isdn/hardware/avm/avm_cs.c
--- devel/drivers/isdn/hardware/avm/avm_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/isdn/hardware/avm/avm_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -63,7 +63,7 @@ static int avmcs_event(event_t event, in
 */
 
 static dev_link_t *avmcs_attach(void);
-static void avmcs_detach(dev_link_t *);
+static void avmcs_detach(struct pcmcia_device *p_dev);
 
 /*
    The dev_info variable is the "key" that is used to match up this
@@ -165,7 +165,7 @@ static dev_link_t *avmcs_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != 0) {
 	cs_error(link->handle, RegisterClient, ret);
-	avmcs_detach(link);
+	avmcs_detach(link->handle);
 	goto err;
     }
     return link;
@@ -185,8 +185,9 @@ static dev_link_t *avmcs_attach(void)
 
 ======================================================================*/
 
-static void avmcs_detach(dev_link_t *link)
+static void avmcs_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
 
     /* Locate device structure */
@@ -195,28 +196,16 @@ static void avmcs_detach(dev_link_t *lin
     if (*linkp == NULL)
 	return;
 
-    /*
-       If the device is currently configured and active, we won't
-       actually delete it yet.  Instead, it is marked so that when
-       the release() function is called, that will trigger a proper
-       detach().
-    */
-    if (link->state & DEV_CONFIG) {
-	link->state |= DEV_STALE_LINK;
-	return;
-    }
+    if (link->state & DEV_CONFIG)
+        avmcs_release(link);
+
 
-    /* Break the link with Card Services */
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
     /* Unlink device structure, free pieces */
     *linkp = link->next;
     if (link->priv) {
 	kfree(link->priv);
     }
     kfree(link);
-    
 } /* avmcs_detach */
 
 /*======================================================================
@@ -427,10 +416,6 @@ static void avmcs_release(dev_link_t *li
     pcmcia_release_io(link->handle, &link->io);
     pcmcia_release_irq(link->handle, &link->irq);
     link->state &= ~DEV_CONFIG;
-    
-    if (link->state & DEV_STALE_LINK)
-	avmcs_detach(link);
-    
 } /* avmcs_release */
 
 static int avmcs_suspend(struct pcmcia_device *dev)
@@ -475,11 +460,6 @@ static int avmcs_event(event_t event, in
     dev_link_t *link = args->client_data;
 
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-		avmcs_release(link);
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	avmcs_config(link);
@@ -503,7 +483,7 @@ static struct pcmcia_driver avmcs_driver
 	},
 	.attach	= avmcs_attach,
 	.event	= avmcs_event,
-	.detach	= avmcs_detach,
+	.remove	= avmcs_detach,
 	.id_table = avmcs_ids,
 	.suspend= avmcs_suspend,
 	.resume = avmcs_resume,
diff -puN drivers/isdn/hisax/avma1_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/isdn/hisax/avma1_cs.c
--- devel/drivers/isdn/hisax/avma1_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/isdn/hisax/avma1_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -79,7 +79,7 @@ static int avma1cs_event(event_t event, 
 */
 
 static dev_link_t *avma1cs_attach(void);
-static void avma1cs_detach(dev_link_t *);
+static void avma1cs_detach(struct pcmcia_device *p_dev);
 
 /*
    The dev_info variable is the "key" that is used to match up this
@@ -187,7 +187,7 @@ static dev_link_t *avma1cs_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != 0) {
 	cs_error(link->handle, RegisterClient, ret);
-	avma1cs_detach(link);
+	avma1cs_detach(link->handle);
 	return NULL;
     }
 
@@ -203,44 +203,28 @@ static dev_link_t *avma1cs_attach(void)
 
 ======================================================================*/
 
-static void avma1cs_detach(dev_link_t *link)
+static void avma1cs_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
 
     DEBUG(0, "avma1cs_detach(0x%p)\n", link);
-    
+
     /* Locate device structure */
     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
 	if (*linkp == link) break;
     if (*linkp == NULL)
 	return;
 
-    /*
-       If the device is currently configured and active, we won't
-       actually delete it yet.  Instead, it is marked so that when
-       the release() function is called, that will trigger a proper
-       detach().
-    */
-    if (link->state & DEV_CONFIG) {
-#ifdef PCMCIA_DEBUG
-	printk(KERN_DEBUG "avma1_cs: detach postponed, '%s' "
-	       "still locked\n", link->dev->dev_name);
-#endif
-	link->state |= DEV_STALE_LINK;
-	return;
-    }
+    if (link->state & DEV_CONFIG)
+	    avma1cs_release(link);
 
-    /* Break the link with Card Services */
-    if (link->handle)
-    	pcmcia_deregister_client(link->handle);
-    
     /* Unlink device structure, free pieces */
     *linkp = link->next;
     if (link->priv) {
 	kfree(link->priv);
     }
     kfree(link);
-    
 } /* avma1cs_detach */
 
 /*======================================================================
@@ -442,9 +426,6 @@ static void avma1cs_release(dev_link_t *
     pcmcia_release_io(link->handle, &link->io);
     pcmcia_release_irq(link->handle, &link->irq);
     link->state &= ~DEV_CONFIG;
-    
-    if (link->state & DEV_STALE_LINK)
-	avma1cs_detach(link);
 } /* avma1cs_release */
 
 static int avma1cs_suspend(struct pcmcia_device *dev)
@@ -491,10 +472,6 @@ static int avma1cs_event(event_t event, 
     DEBUG(1, "avma1cs_event(0x%06x)\n", event);
     
     switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-	    if (link->state & DEV_CONFIG)
-		avma1cs_release(link);
-	    break;
 	case CS_EVENT_CARD_INSERTION:
 	    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	    avma1cs_config(link);
@@ -517,7 +494,7 @@ static struct pcmcia_driver avma1cs_driv
 	},
 	.attach		= avma1cs_attach,
 	.event		= avma1cs_event,
-	.detach		= avma1cs_detach,
+	.remove		= avma1cs_detach,
 	.id_table	= avma1cs_ids,
 	.suspend	= avma1cs_suspend,
 	.resume		= avma1cs_resume,
diff -puN drivers/isdn/hisax/elsa_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/isdn/hisax/elsa_cs.c
--- devel/drivers/isdn/hisax/elsa_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/isdn/hisax/elsa_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -106,7 +106,7 @@ static int elsa_cs_event(event_t event, 
 */
 
 static dev_link_t *elsa_cs_attach(void);
-static void elsa_cs_detach(dev_link_t *);
+static void elsa_cs_detach(struct pcmcia_device *p_dev);
 
 /*
    The dev_info variable is the "key" that is used to match up this
@@ -216,7 +216,7 @@ static dev_link_t *elsa_cs_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != CS_SUCCESS) {
         cs_error(link->handle, RegisterClient, ret);
-        elsa_cs_detach(link);
+        elsa_cs_detach(link->handle);
         return NULL;
     }
 
@@ -232,11 +232,11 @@ static dev_link_t *elsa_cs_attach(void)
 
 ======================================================================*/
 
-static void elsa_cs_detach(dev_link_t *link)
+static void elsa_cs_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
     local_info_t *info = link->priv;
-    int ret;
 
     DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
 
@@ -246,14 +246,9 @@ static void elsa_cs_detach(dev_link_t *l
     if (*linkp == NULL)
         return;
 
-    if (link->state & DEV_CONFIG)
+    if (link->state & DEV_CONFIG) {
+        ((local_info_t*)link->priv)->busy = 1;
         elsa_cs_release(link);
-
-    /* Break the link with Card Services */
-    if (link->handle) {
-        ret = pcmcia_deregister_client(link->handle);
-	if (ret != CS_SUCCESS)
-	    cs_error(link->handle, DeregisterClient, ret);
     }
 
     /* Unlink device structure and free it */
@@ -495,13 +490,6 @@ static int elsa_cs_event(event_t event, 
     DEBUG(1, "elsa_cs_event(%d)\n", event);
 
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-        link->state &= ~DEV_PRESENT;
-        if (link->state & DEV_CONFIG) {
-            ((local_info_t*)link->priv)->busy = 1;
-	    elsa_cs_release(link);
-        }
-        break;
     case CS_EVENT_CARD_INSERTION:
         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
         elsa_cs_config(link);
@@ -524,7 +512,7 @@ static struct pcmcia_driver elsa_cs_driv
 	},
 	.attach		= elsa_cs_attach,
 	.event		= elsa_cs_event,
-	.detach		= elsa_cs_detach,
+	.remove		= elsa_cs_detach,
 	.id_table	= elsa_ids,
 	.suspend	= elsa_suspend,
 	.resume		= elsa_resume,
diff -puN drivers/isdn/hisax/sedlbauer_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/isdn/hisax/sedlbauer_cs.c
--- devel/drivers/isdn/hisax/sedlbauer_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/isdn/hisax/sedlbauer_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -107,7 +107,7 @@ static int sedlbauer_event(event_t event
 */
 
 static dev_link_t *sedlbauer_attach(void);
-static void sedlbauer_detach(dev_link_t *);
+static void sedlbauer_detach(struct pcmcia_device *p_dev);
 
 /*
    You'll also need to prototype all the functions that will actually
@@ -230,7 +230,7 @@ static dev_link_t *sedlbauer_attach(void
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != CS_SUCCESS) {
 	cs_error(link->handle, RegisterClient, ret);
-	sedlbauer_detach(link);
+	sedlbauer_detach(link->handle);
 	return NULL;
     }
 
@@ -246,8 +246,9 @@ static dev_link_t *sedlbauer_attach(void
 
 ======================================================================*/
 
-static void sedlbauer_detach(dev_link_t *link)
+static void sedlbauer_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
 
     DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
@@ -258,25 +259,11 @@ static void sedlbauer_detach(dev_link_t 
     if (*linkp == NULL)
 	return;
 
-    /*
-       If the device is currently configured and active, we won't
-       actually delete it yet.  Instead, it is marked so that when
-       the release() function is called, that will trigger a proper
-       detach().
-    */
     if (link->state & DEV_CONFIG) {
-#ifdef PCMCIA_DEBUG
-	printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' "
-	       "still locked\n", link->dev->dev_name);
-#endif
-	link->state |= DEV_STALE_LINK;
-	return;
+	((local_info_t *)link->priv)->stop = 1;
+	sedlbauer_release(link);
     }
 
-    /* Break the link with Card Services */
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
     /* Unlink device structure, and free it */
     *linkp = link->next;
     /* This points to the parent local_info_t struct */
@@ -547,10 +534,6 @@ static void sedlbauer_release(dev_link_t
     if (link->irq.AssignedIRQ)
 	pcmcia_release_irq(link->handle, &link->irq);
     link->state &= ~DEV_CONFIG;
-    
-    if (link->state & DEV_STALE_LINK)
-	sedlbauer_detach(link);
-    
 } /* sedlbauer_release */
 
 static int sedlbauer_suspend(struct pcmcia_device *p_dev)
@@ -599,13 +582,6 @@ static int sedlbauer_event(event_t event
     DEBUG(1, "sedlbauer_event(0x%06x)\n", event);
     
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG) {
-	    ((local_info_t *)link->priv)->stop = 1;
-	    sedlbauer_release(link);
-	}
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	sedlbauer_config(link);
@@ -633,7 +609,7 @@ static struct pcmcia_driver sedlbauer_dr
 	},
 	.attach		= sedlbauer_attach,
 	.event		= sedlbauer_event,
-	.detach		= sedlbauer_detach,
+	.remove		= sedlbauer_detach,
 	.id_table	= sedlbauer_ids,
 	.suspend	= sedlbauer_suspend,
 	.resume		= sedlbauer_resume,
diff -puN drivers/isdn/hisax/teles_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/isdn/hisax/teles_cs.c
--- devel/drivers/isdn/hisax/teles_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/isdn/hisax/teles_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -87,7 +87,7 @@ static int teles_cs_event(event_t event,
 */
 
 static dev_link_t *teles_attach(void);
-static void teles_detach(dev_link_t *);
+static void teles_detach(struct pcmcia_device *p_dev);
 
 /*
    The dev_info variable is the "key" that is used to match up this
@@ -197,7 +197,7 @@ static dev_link_t *teles_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != CS_SUCCESS) {
         cs_error(link->handle, RegisterClient, ret);
-        teles_detach(link);
+        teles_detach(link->handle);
         return NULL;
     }
 
@@ -213,11 +213,11 @@ static dev_link_t *teles_attach(void)
 
 ======================================================================*/
 
-static void teles_detach(dev_link_t *link)
+static void teles_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
     local_info_t *info = link->priv;
-    int ret;
 
     DEBUG(0, "teles_detach(0x%p)\n", link);
 
@@ -227,14 +227,9 @@ static void teles_detach(dev_link_t *lin
     if (*linkp == NULL)
         return;
 
-    if (link->state & DEV_CONFIG)
+    if (link->state & DEV_CONFIG) {
+        info->busy = 1;
         teles_cs_release(link);
-
-    /* Break the link with Card Services */
-    if (link->handle) {
-        ret = pcmcia_deregister_client(link->handle);
-	if (ret != CS_SUCCESS)
-	    cs_error(link->handle, DeregisterClient, ret);
     }
 
     /* Unlink device structure and free it */
@@ -476,13 +471,6 @@ static int teles_cs_event(event_t event,
     DEBUG(1, "teles_cs_event(%d)\n", event);
 
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-        link->state &= ~DEV_PRESENT;
-        if (link->state & DEV_CONFIG) {
-            ((local_info_t*)link->priv)->busy = 1;
-	    teles_cs_release(link);
-        }
-        break;
     case CS_EVENT_CARD_INSERTION:
         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
         teles_cs_config(link);
@@ -504,7 +492,7 @@ static struct pcmcia_driver teles_cs_dri
 	},
 	.attach		= teles_attach,
 	.event		= teles_cs_event,
-	.detach		= teles_detach,
+	.remove		= teles_detach,
 	.id_table       = teles_ids,
 	.suspend	= teles_suspend,
 	.resume		= teles_resume,
diff -puN drivers/mtd/maps/pcmciamtd.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/mtd/maps/pcmciamtd.c
--- devel/drivers/mtd/maps/pcmciamtd.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/mtd/maps/pcmciamtd.c	2005-09-07 20:10:52.000000000 -0700
@@ -722,18 +722,6 @@ static int pcmciamtd_event(event_t event
 
 	DEBUG(1, "event=0x%06x", event);
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		DEBUG(2, "EVENT_CARD_REMOVAL");
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			struct pcmciamtd_dev *dev = link->priv;
-			if(dev->mtd_info) {
-				del_mtd_device(dev->mtd_info);
-				info("mtd%d: Removed", dev->mtd_info->index);
-			}
-			pcmciamtd_release(link);
-		}
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		DEBUG(2, "EVENT_CARD_INSERTION");
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
@@ -752,23 +740,21 @@ static int pcmciamtd_event(event_t event
  * when the device is released.
  */
 
-static void pcmciamtd_detach(dev_link_t *link)
+static void pcmciamtd_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
+
 	DEBUG(3, "link=0x%p", link);
 
 	if(link->state & DEV_CONFIG) {
-		pcmciamtd_release(link);
-	}
+		struct pcmciamtd_dev *dev = link->priv;
+		if(dev->mtd_info) {
+			del_mtd_device(dev->mtd_info);
+			info("mtd%d: Removed", dev->mtd_info->index);
+		}
 
-	if (link->handle) {
-		int ret;
-		DEBUG(2, "Deregistering with card services");
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
+		pcmciamtd_release(link);
 	}
-
-	link->state |= DEV_STALE_LINK;
 }
 
 
@@ -807,7 +793,7 @@ static dev_link_t *pcmciamtd_attach(void
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != 0) {
 		cs_error(link->handle, RegisterClient, ret);
-		pcmciamtd_detach(link);
+		pcmciamtd_detach(link->handle);
 		return NULL;
 	}
 	DEBUG(2, "link = %p", link);
@@ -847,7 +833,7 @@ static struct pcmcia_driver pcmciamtd_dr
 	},
 	.attach		= pcmciamtd_attach,
 	.event		= pcmciamtd_event,
-	.detach		= pcmciamtd_detach,
+	.remove		= pcmciamtd_detach,
 	.owner		= THIS_MODULE,
 	.id_table	= pcmciamtd_ids,
 	.suspend	= pcmciamtd_suspend,
diff -puN drivers/net/pcmcia/3c574_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/pcmcia/3c574_cs.c
--- devel/drivers/net/pcmcia/3c574_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/pcmcia/3c574_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -253,7 +253,7 @@ static void set_rx_mode(struct net_devic
 static dev_info_t dev_info = "3c574_cs";
 
 static dev_link_t *tc574_attach(void);
-static void tc574_detach(dev_link_t *);
+static void tc574_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list;
 
@@ -316,7 +316,7 @@ static dev_link_t *tc574_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != 0) {
 		cs_error(link->handle, RegisterClient, ret);
-		tc574_detach(link);
+		tc574_detach(link->handle);
 		return NULL;
 	}
 
@@ -332,8 +332,9 @@ static dev_link_t *tc574_attach(void)
 
 */
 
-static void tc574_detach(dev_link_t *link)
+static void tc574_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 	dev_link_t **linkp;
 
@@ -351,9 +352,6 @@ static void tc574_detach(dev_link_t *lin
 	if (link->state & DEV_CONFIG)
 		tc574_release(link);
 
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
 	/* Unlink device structure, free bits */
 	*linkp = link->next;
 	free_netdev(dev);
@@ -590,16 +588,10 @@ static int tc574_event(event_t event, in
 					   event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	struct net_device *dev = link->priv;
 
 	DEBUG(1, "3c574_event(0x%06x)\n", event);
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
-			netif_device_detach(dev);
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		tc574_config(link);
@@ -1304,7 +1296,7 @@ static struct pcmcia_driver tc574_driver
 	},
 	.attach		= tc574_attach,
 	.event		= tc574_event,
-	.detach		= tc574_detach,
+	.remove		= tc574_detach,
 	.id_table       = tc574_ids,
 	.suspend	= tc574_suspend,
 	.resume		= tc574_resume,
diff -puN drivers/net/pcmcia/3c589_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/pcmcia/3c589_cs.c
--- devel/drivers/net/pcmcia/3c589_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/pcmcia/3c589_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -164,7 +164,7 @@ static struct ethtool_ops netdev_ethtool
 static dev_info_t dev_info = "3c589_cs";
 
 static dev_link_t *tc589_attach(void);
-static void tc589_detach(dev_link_t *);
+static void tc589_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list;
 
@@ -230,7 +230,7 @@ static dev_link_t *tc589_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != 0) {
 	cs_error(link->handle, RegisterClient, ret);
-	tc589_detach(link);
+	tc589_detach(link->handle);
 	return NULL;
     }
     
@@ -246,8 +246,9 @@ static dev_link_t *tc589_attach(void)
 
 ======================================================================*/
 
-static void tc589_detach(dev_link_t *link)
+static void tc589_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
     dev_link_t **linkp;
     
@@ -264,10 +265,7 @@ static void tc589_detach(dev_link_t *lin
 
     if (link->state & DEV_CONFIG)
 	tc589_release(link);
-    
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
+
     /* Unlink device structure, free bits */
     *linkp = link->next;
     free_netdev(dev);
@@ -466,16 +464,10 @@ static int tc589_event(event_t event, in
 		       event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
     
     DEBUG(1, "3c589_event(0x%06x)\n", event);
     
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	tc589_config(link);
@@ -1079,7 +1071,7 @@ static struct pcmcia_driver tc589_driver
 	},
 	.attach		= tc589_attach,
 	.event		= tc589_event,
-	.detach		= tc589_detach,
+	.remove		= tc589_detach,
         .id_table       = tc589_ids,
 	.suspend	= tc589_suspend,
 	.resume		= tc589_resume,
diff -puN drivers/net/pcmcia/axnet_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/pcmcia/axnet_cs.c
--- devel/drivers/net/pcmcia/axnet_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/pcmcia/axnet_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -108,7 +108,7 @@ static void block_output(struct net_devi
 			 const u_char *buf, const int start_page);
 
 static dev_link_t *axnet_attach(void);
-static void axnet_detach(dev_link_t *);
+static void axnet_detach(struct pcmcia_device *p_dev);
 
 static dev_info_t dev_info = "axnet_cs";
 static dev_link_t *dev_list;
@@ -185,7 +185,7 @@ static dev_link_t *axnet_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != CS_SUCCESS) {
 	cs_error(link->handle, RegisterClient, ret);
-	axnet_detach(link);
+	axnet_detach(link->handle);
 	return NULL;
     }
 
@@ -201,8 +201,9 @@ static dev_link_t *axnet_attach(void)
 
 ======================================================================*/
 
-static void axnet_detach(dev_link_t *link)
+static void axnet_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
     dev_link_t **linkp;
 
@@ -220,9 +221,6 @@ static void axnet_detach(dev_link_t *lin
     if (link->state & DEV_CONFIG)
 	axnet_release(link);
 
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-
     /* Unlink device structure, free bits */
     *linkp = link->next;
     free_netdev(dev);
@@ -537,16 +535,10 @@ static int axnet_event(event_t event, in
 		       event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
 
     DEBUG(2, "axnet_event(0x%06x)\n", event);
 
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	axnet_config(link);
@@ -890,7 +882,7 @@ static struct pcmcia_driver axnet_cs_dri
 	},
 	.attach		= axnet_attach,
 	.event		= axnet_event,
-	.detach		= axnet_detach,
+	.remove		= axnet_detach,
 	.id_table       = axnet_ids,
 	.suspend	= axnet_suspend,
 	.resume		= axnet_resume,
diff -puN drivers/net/pcmcia/com20020_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/pcmcia/com20020_cs.c
--- devel/drivers/net/pcmcia/com20020_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/pcmcia/com20020_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -126,7 +126,7 @@ static int com20020_event(event_t event,
 static dev_info_t dev_info = "com20020_cs";
 
 static dev_link_t *com20020_attach(void);
-static void com20020_detach(dev_link_t *);
+static void com20020_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list;
 
@@ -204,7 +204,7 @@ static dev_link_t *com20020_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != 0) {
         cs_error(link->handle, RegisterClient, ret);
-        com20020_detach(link);
+        com20020_detach(link->handle);
         return NULL;
     }
 
@@ -226,8 +226,9 @@ fail_alloc_info:
 
 ======================================================================*/
 
-static void com20020_detach(dev_link_t *link)
+static void com20020_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct com20020_dev_t *info = link->priv;
     dev_link_t **linkp;
     struct net_device *dev; 
@@ -260,9 +261,6 @@ static void com20020_detach(dev_link_t *
     if (link->state & DEV_CONFIG)
         com20020_release(link);
 
-    if (link->handle)
-        pcmcia_deregister_client(link->handle);
-
     /* Unlink device structure, free bits */
     DEBUG(1,"unlinking...\n");
     *linkp = link->next;
@@ -470,17 +468,10 @@ static int com20020_event(event_t event,
 			  event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    com20020_dev_t *info = link->priv;
-    struct net_device *dev = info->dev;
 
     DEBUG(1, "com20020_event(0x%06x)\n", event);
     
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-        link->state &= ~DEV_PRESENT;
-        if (link->state & DEV_CONFIG)
-            netif_device_detach(dev);
-        break;
     case CS_EVENT_CARD_INSERTION:
         link->state |= DEV_PRESENT;
 	com20020_config(link); 
@@ -502,7 +493,7 @@ static struct pcmcia_driver com20020_cs_
 	},
 	.attach		= com20020_attach,
 	.event		= com20020_event,
-	.detach		= com20020_detach,
+	.remove		= com20020_detach,
 	.id_table	= com20020_ids,
 	.suspend	= com20020_suspend,
 	.resume		= com20020_resume,
diff -puN drivers/net/pcmcia/fmvj18x_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/pcmcia/fmvj18x_cs.c
--- devel/drivers/net/pcmcia/fmvj18x_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/pcmcia/fmvj18x_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -91,7 +91,7 @@ static void fmvj18x_release(dev_link_t *
 static int fmvj18x_event(event_t event, int priority,
 			  event_callback_args_t *args);
 static dev_link_t *fmvj18x_attach(void);
-static void fmvj18x_detach(dev_link_t *);
+static void fmvj18x_detach(struct pcmcia_device *p_dev);
 
 /*
     LAN controller(MBH86960A) specific routines
@@ -292,7 +292,7 @@ static dev_link_t *fmvj18x_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != 0) {
 	cs_error(link->handle, RegisterClient, ret);
-	fmvj18x_detach(link);
+	fmvj18x_detach(link->handle);
 	return NULL;
     }
 
@@ -301,8 +301,9 @@ static dev_link_t *fmvj18x_attach(void)
 
 /*====================================================================*/
 
-static void fmvj18x_detach(dev_link_t *link)
+static void fmvj18x_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
     dev_link_t **linkp;
     
@@ -320,10 +321,6 @@ static void fmvj18x_detach(dev_link_t *l
     if (link->state & DEV_CONFIG)
 	fmvj18x_release(link);
 
-    /* Break the link with Card Services */
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
     /* Unlink device structure, free pieces */
     *linkp = link->next;
     free_netdev(dev);
@@ -753,16 +750,10 @@ static int fmvj18x_event(event_t event, 
 			  event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
 
     DEBUG(1, "fmvj18x_event(0x%06x)\n", event);
     
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	fmvj18x_config(link);
@@ -803,7 +794,7 @@ static struct pcmcia_driver fmvj18x_cs_d
 	},
 	.attach		= fmvj18x_attach,
 	.event		= fmvj18x_event,
-	.detach		= fmvj18x_detach,
+	.remove		= fmvj18x_detach,
 	.id_table       = fmvj18x_ids,
 	.suspend	= fmvj18x_suspend,
 	.resume		= fmvj18x_resume,
diff -puN drivers/net/pcmcia/ibmtr_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/pcmcia/ibmtr_cs.c
--- devel/drivers/net/pcmcia/ibmtr_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/pcmcia/ibmtr_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -114,7 +114,7 @@ static int ibmtr_event(event_t event, in
 static dev_info_t dev_info = "ibmtr_cs";
 
 static dev_link_t *ibmtr_attach(void);
-static void ibmtr_detach(dev_link_t *);
+static void ibmtr_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list;
 
@@ -201,7 +201,7 @@ out:
     return link;
 
 out_detach:
-    ibmtr_detach(link);
+    ibmtr_detach(link->handle);
     link = NULL;
     goto out;
 } /* ibmtr_attach */
@@ -215,8 +215,9 @@ out_detach:
 
 ======================================================================*/
 
-static void ibmtr_detach(dev_link_t *link)
+static void ibmtr_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct ibmtr_dev_t *info = link->priv;
     dev_link_t **linkp;
     struct net_device *dev;
@@ -241,9 +242,6 @@ static void ibmtr_detach(dev_link_t *lin
     if (link->state & DEV_CONFIG)
         ibmtr_release(link);
 
-    if (link->handle)
-        pcmcia_deregister_client(link->handle);
-
     /* Unlink device structure, free bits */
     *linkp = link->next;
     free_netdev(dev);
@@ -449,21 +447,10 @@ static int ibmtr_event(event_t event, in
                        event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    ibmtr_dev_t *info = link->priv;
-    struct net_device *dev = info->dev;
 
     DEBUG(1, "ibmtr_event(0x%06x)\n", event);
 
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-        link->state &= ~DEV_PRESENT;
-        if (link->state & DEV_CONFIG) {
-	    /* set flag to bypass normal interrupt code */
-	    struct tok_info *priv = netdev_priv(dev);
-	    priv->sram_phys |= 1;
-	    netif_device_detach(dev);
-        }
-        break;
     case CS_EVENT_CARD_INSERTION:
         link->state |= DEV_PRESENT;
 	ibmtr_config(link);
@@ -529,7 +516,7 @@ static struct pcmcia_driver ibmtr_cs_dri
 	},
 	.attach		= ibmtr_attach,
 	.event		= ibmtr_event,
-	.detach		= ibmtr_detach,
+	.remove		= ibmtr_detach,
 	.id_table       = ibmtr_ids,
 	.suspend	= ibmtr_suspend,
 	.resume		= ibmtr_resume,
diff -puN drivers/net/pcmcia/nmclan_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/pcmcia/nmclan_cs.c
--- devel/drivers/net/pcmcia/nmclan_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/pcmcia/nmclan_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -440,7 +440,7 @@ static struct ethtool_ops netdev_ethtool
 
 
 static dev_link_t *nmclan_attach(void);
-static void nmclan_detach(dev_link_t *);
+static void nmclan_detach(struct pcmcia_device *p_dev);
 
 /* ----------------------------------------------------------------------------
 nmclan_attach
@@ -506,7 +506,7 @@ static dev_link_t *nmclan_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != 0) {
 	cs_error(link->handle, RegisterClient, ret);
-	nmclan_detach(link);
+	nmclan_detach(link->handle);
 	return NULL;
     }
 
@@ -521,8 +521,9 @@ nmclan_detach
 	when the device is released.
 ---------------------------------------------------------------------------- */
 
-static void nmclan_detach(dev_link_t *link)
+static void nmclan_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
     dev_link_t **linkp;
 
@@ -540,9 +541,6 @@ static void nmclan_detach(dev_link_t *li
     if (link->state & DEV_CONFIG)
 	nmclan_release(link);
 
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-
     /* Unlink device structure, free bits */
     *linkp = link->next;
     free_netdev(dev);
@@ -845,16 +843,10 @@ static int nmclan_event(event_t event, i
 		       event_callback_args_t *args)
 {
   dev_link_t *link = args->client_data;
-  struct net_device *dev = link->priv;
 
   DEBUG(1, "nmclan_event(0x%06x)\n", event);
 
   switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-      link->state &= ~DEV_PRESENT;
-      if (link->state & DEV_CONFIG)
-	netif_device_detach(dev);
-      break;
     case CS_EVENT_CARD_INSERTION:
       link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
       nmclan_config(link);
@@ -1694,7 +1686,7 @@ static struct pcmcia_driver nmclan_cs_dr
 	},
 	.attach		= nmclan_attach,
 	.event		= nmclan_event,
-	.detach		= nmclan_detach,
+	.remove		= nmclan_detach,
 	.id_table       = nmclan_ids,
 	.suspend	= nmclan_suspend,
 	.resume		= nmclan_resume,
diff -puN drivers/net/pcmcia/smc91c92_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/pcmcia/smc91c92_cs.c
--- devel/drivers/net/pcmcia/smc91c92_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/pcmcia/smc91c92_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -282,7 +282,7 @@ enum RxCfg { RxAllMulti = 0x0004, RxProm
 /*====================================================================*/
 
 static dev_link_t *smc91c92_attach(void);
-static void smc91c92_detach(dev_link_t *);
+static void smc91c92_detach(struct pcmcia_device *p_dev);
 static void smc91c92_config(dev_link_t *link);
 static void smc91c92_release(dev_link_t *link);
 static int smc91c92_event(event_t event, int priority,
@@ -375,7 +375,7 @@ static dev_link_t *smc91c92_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != 0) {
 	cs_error(link->handle, RegisterClient, ret);
-	smc91c92_detach(link);
+	smc91c92_detach(link->handle);
 	return NULL;
     }
 
@@ -391,8 +391,9 @@ static dev_link_t *smc91c92_attach(void)
 
 ======================================================================*/
 
-static void smc91c92_detach(dev_link_t *link)
+static void smc91c92_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
     dev_link_t **linkp;
 
@@ -410,9 +411,6 @@ static void smc91c92_detach(dev_link_t *
     if (link->state & DEV_CONFIG)
 	smc91c92_release(link);
 
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-
     /* Unlink device structure, free bits */
     *linkp = link->next;
     free_netdev(dev);
@@ -1237,16 +1235,10 @@ static int smc91c92_event(event_t event,
 			  event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
 
     DEBUG(1, "smc91c92_event(0x%06x)\n", event);
 
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	smc91c92_config(link);
@@ -2371,7 +2363,7 @@ static struct pcmcia_driver smc91c92_cs_
 	},
 	.attach		= smc91c92_attach,
 	.event		= smc91c92_event,
-	.detach		= smc91c92_detach,
+	.remove		= smc91c92_detach,
 	.id_table       = smc91c92_ids,
 	.suspend	= smc91c92_suspend,
 	.resume		= smc91c92_resume,
diff -puN drivers/net/pcmcia/xirc2ps_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/pcmcia/xirc2ps_cs.c
--- devel/drivers/net/pcmcia/xirc2ps_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/pcmcia/xirc2ps_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -302,7 +302,7 @@ static int xirc2ps_event(event_t event, 
  */
 
 static dev_link_t *xirc2ps_attach(void);
-static void xirc2ps_detach(dev_link_t *);
+static void xirc2ps_detach(struct pcmcia_device *p_dev);
 
 /****************
  * You'll also need to prototype all the functions that will actually
@@ -622,7 +622,7 @@ xirc2ps_attach(void)
     client_reg.event_callback_args.client_data = link;
     if ((err = pcmcia_register_client(&link->handle, &client_reg))) {
 	cs_error(link->handle, RegisterClient, err);
-	xirc2ps_detach(link);
+	xirc2ps_detach(link->handle);
 	return NULL;
     }
 
@@ -637,8 +637,9 @@ xirc2ps_attach(void)
  */
 
 static void
-xirc2ps_detach(dev_link_t * link)
+xirc2ps_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
     dev_link_t **linkp;
 
@@ -656,19 +657,9 @@ xirc2ps_detach(dev_link_t * link)
     if (link->dev)
 	unregister_netdev(dev);
 
-    /*
-     * If the device is currently configured and active, we won't
-     * actually delete it yet.	Instead, it is marked so that when
-     * the release() function is called, that will trigger a proper
-     * detach().
-     */
     if (link->state & DEV_CONFIG)
 	xirc2ps_release(link);
 
-    /* Break the link with Card Services */
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-
     /* Unlink device structure, free it */
     *linkp = link->next;
     free_netdev(dev);
@@ -1209,19 +1200,10 @@ xirc2ps_event(event_t event, int priorit
 	      event_callback_args_t * args)
 {
     dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
 
     DEBUG(0, "event(%d)\n", (int)event);
 
     switch (event) {
-    case CS_EVENT_REGISTRATION_COMPLETE:
-	DEBUG(0, "registration complete\n");
-	break;
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	xirc2ps_config(link);
@@ -2022,7 +2004,7 @@ static struct pcmcia_driver xirc2ps_cs_d
 	},
 	.attach		= xirc2ps_attach,
 	.event		= xirc2ps_event,
-	.detach		= xirc2ps_detach,
+	.remove		= xirc2ps_detach,
 	.id_table       = xirc2ps_ids,
 	.suspend	= xirc2ps_suspend,
 	.resume		= xirc2ps_resume,
diff -puN drivers/net/wireless/airo_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/wireless/airo_cs.c
--- devel/drivers/net/wireless/airo_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/wireless/airo_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -94,7 +94,7 @@ static int airo_event(event_t event, int
 */
 
 static dev_link_t *airo_attach(void);
-static void airo_detach(dev_link_t *);
+static void airo_detach(struct pcmcia_device *p_dev);
 
 /*
    You'll also need to prototype all the functions that will actually
@@ -214,7 +214,7 @@ static dev_link_t *airo_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != 0) {
 		cs_error(link->handle, RegisterClient, ret);
-		airo_detach(link);
+		airo_detach(link->handle);
 		return NULL;
 	}
 	
@@ -230,8 +230,9 @@ static dev_link_t *airo_attach(void)
   
   ======================================================================*/
 
-static void airo_detach(dev_link_t *link)
+static void airo_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
 	
 	DEBUG(0, "airo_detach(0x%p)\n", link);
@@ -248,14 +249,8 @@ static void airo_detach(dev_link_t *link
 	if ( ((local_info_t*)link->priv)->eth_dev ) {
 		stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
 	}
-	((local_info_t*)link->priv)->eth_dev = NULL;   
-	
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-	
-	
-	
+	((local_info_t*)link->priv)->eth_dev = NULL;
+
 	/* Unlink device structure, free pieces */
 	*linkp = link->next;
 	if (link->priv) {
@@ -543,18 +538,10 @@ static int airo_event(event_t event, int
 		      event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	local_info_t *local = link->priv;
-	
+
 	DEBUG(1, "airo_event(0x%06x)\n", event);
-	
+
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			netif_device_detach(local->eth_dev);
-			airo_release(link);
-		}
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		airo_config(link);
@@ -579,7 +566,7 @@ static struct pcmcia_driver airo_driver 
 	},
 	.attach		= airo_attach,
 	.event		= airo_event,
-	.detach		= airo_detach,
+	.remove		= airo_detach,
 	.id_table       = airo_ids,
 	.suspend	= airo_suspend,
 	.resume		= airo_resume,
diff -puN drivers/net/wireless/atmel_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/wireless/atmel_cs.c
--- devel/drivers/net/wireless/atmel_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/wireless/atmel_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -102,7 +102,7 @@ static int atmel_event(event_t event, in
 */
 
 static dev_link_t *atmel_attach(void);
-static void atmel_detach(dev_link_t *);
+static void atmel_detach(struct pcmcia_device *p_dev);
 
 /*
    You'll also need to prototype all the functions that will actually
@@ -222,7 +222,7 @@ static dev_link_t *atmel_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != 0) {
 		cs_error(link->handle, RegisterClient, ret);
-		atmel_detach(link);
+		atmel_detach(link->handle);
 		return NULL;
 	}
 	
@@ -238,8 +238,9 @@ static dev_link_t *atmel_attach(void)
   
   ======================================================================*/
 
-static void atmel_detach(dev_link_t *link)
+static void atmel_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
 	
 	DEBUG(0, "atmel_detach(0x%p)\n", link);
@@ -253,10 +254,6 @@ static void atmel_detach(dev_link_t *lin
 	if (link->state & DEV_CONFIG)
 		atmel_release(link);
 		
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
 	/* Unlink device structure, free pieces */
 	*linkp = link->next;
 	if (link->priv)
@@ -629,18 +626,10 @@ static int atmel_event(event_t event, in
 		      event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	local_info_t *local = link->priv;
-	
+
 	DEBUG(1, "atmel_event(0x%06x)\n", event);
-	
+
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			netif_device_detach(local->eth_dev);
-			atmel_release(link);
-		}
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		atmel_config(link);
@@ -678,7 +667,7 @@ static struct pcmcia_driver atmel_driver
         },
 	.attach         = atmel_attach,
 	.event		= atmel_event,
-	.detach		= atmel_detach,
+	.remove		= atmel_detach,
 	.id_table	= atmel_ids,
 	.suspend	= atmel_suspend,
 	.resume		= atmel_resume,
diff -puN drivers/net/wireless/hostap/hostap_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/wireless/hostap/hostap_cs.c
--- devel/drivers/net/wireless/hostap/hostap_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/wireless/hostap/hostap_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -203,7 +203,7 @@ static int hfa384x_to_bap(struct net_dev
 
 
 
-static void prism2_detach(dev_link_t *link);
+static void prism2_detach(struct pcmcia_device *p_dev);
 static void prism2_release(u_long arg);
 static int prism2_event(event_t event, int priority,
 			event_callback_args_t *args);
@@ -560,15 +560,16 @@ static dev_link_t *prism2_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		prism2_detach(link);
+		prism2_detach(link->handle);
 		return NULL;
 	}
 	return link;
 }
 
 
-static void prism2_detach(dev_link_t *link)
+static void prism2_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
 
 	PDEBUG(DEBUG_FLOW, "prism2_detach\n");
@@ -586,14 +587,6 @@ static void prism2_detach(dev_link_t *li
 		prism2_release((u_long)link);
 	}
 
-	if (link->handle) {
-		int res = pcmcia_deregister_client(link->handle);
-		if (res) {
-			printk("CardService(DeregisterClient) => %d\n", res);
-			cs_error(link->handle, DeregisterClient, res);
-		}
-	}
-
 	*linkp = link->next;
 	/* release net devices */
 	if (link->priv) {
@@ -923,7 +916,6 @@ static int prism2_event(event_t event, i
 			event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	struct net_device *dev = (struct net_device *) link->priv;
 
 	switch (event) {
 	case CS_EVENT_CARD_INSERTION:
@@ -934,16 +926,6 @@ static int prism2_event(event_t event, i
 		}
 		break;
 
-	case CS_EVENT_CARD_REMOVAL:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info);
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			netif_stop_queue(dev);
-			netif_device_detach(dev);
-			prism2_release((u_long) link);
-		}
-		break;
-
 	default:
 		PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
 		       dev_info, event);
@@ -1012,7 +994,7 @@ static struct pcmcia_driver hostap_drive
 		.name	= "hostap_cs",
 	},
 	.attach		= prism2_attach,
-	.detach		= prism2_detach,
+	.remove		= prism2_detach,
 	.owner		= THIS_MODULE,
 	.event		= prism2_event,
 	.id_table	= hostap_cs_ids,
diff -puN drivers/net/wireless/netwave_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/wireless/netwave_cs.c
--- devel/drivers/net/wireless/netwave_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/wireless/netwave_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -202,7 +202,7 @@ static int  netwave_event(event_t event,
 static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card 
 													   insertion */
 static dev_link_t *netwave_attach(void);     /* Create instance */
-static void netwave_detach(dev_link_t *);    /* Destroy instance */
+static void netwave_detach(struct pcmcia_device *p_dev);    /* Destroy instance */
 
 /* Hardware configuration */
 static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase);
@@ -495,7 +495,7 @@ static dev_link_t *netwave_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != 0) {
 	cs_error(link->handle, RegisterClient, ret);
-	netwave_detach(link);
+	netwave_detach(link->handle);
 	return NULL;
     }
 
@@ -510,8 +510,9 @@ static dev_link_t *netwave_attach(void)
  *    structures are freed.  Otherwise, the structures will be freed
  *    when the device is released.
  */
-static void netwave_detach(dev_link_t *link)
+static void netwave_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
     dev_link_t **linkp;
 
@@ -525,11 +526,7 @@ static void netwave_detach(dev_link_t *l
 	*/
     if (link->state & DEV_CONFIG)
 	netwave_release(link);
-	
-    /* Break the link with Card Services */
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
+
     /* Locate device structure */
     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
 	if (*linkp == link) break;
@@ -1171,22 +1168,10 @@ static int netwave_event(event_t event, 
 			 event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
-	
+
     DEBUG(1, "netwave_event(0x%06x)\n", event);
-  
-    switch (event) {
-    case CS_EVENT_REGISTRATION_COMPLETE:
-	DEBUG(0, "netwave_cs: registration complete\n");
-	break;
 
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG) {
-	    netif_device_detach(dev);
-	    netwave_release(link);
-	}
-	break;
+    switch (event) {
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	netwave_pcmcia_config( link);
@@ -1689,7 +1674,7 @@ static struct pcmcia_driver netwave_driv
 	},
 	.attach		= netwave_attach,
 	.event		= netwave_event,
-	.detach		= netwave_detach,
+	.remove		= netwave_detach,
 	.id_table       = netwave_ids,
 	.suspend	= netwave_suspend,
 	.resume		= netwave_resume,
diff -puN drivers/net/wireless/orinoco_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/wireless/orinoco_cs.c
--- devel/drivers/net/wireless/orinoco_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/wireless/orinoco_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -107,7 +107,7 @@ static int orinoco_cs_event(event_t even
 			    event_callback_args_t * args);
 
 static dev_link_t *orinoco_cs_attach(void);
-static void orinoco_cs_detach(dev_link_t *);
+static void orinoco_cs_detach(struct pcmcia_device *p_dev);
 
 /********************************************************************/
 /* Device methods     						    */
@@ -191,7 +191,7 @@ orinoco_cs_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		orinoco_cs_detach(link);
+		orinoco_cs_detach(link->handle);
 		return NULL;
 	}
 
@@ -204,8 +204,9 @@ orinoco_cs_attach(void)
  * are freed.  Otherwise, the structures will be freed when the device
  * is released.
  */
-static void orinoco_cs_detach(dev_link_t *link)
+static void orinoco_cs_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
 	struct net_device *dev = link->priv;
 
@@ -219,10 +220,6 @@ static void orinoco_cs_detach(dev_link_t
 	if (link->state & DEV_CONFIG)
 		orinoco_cs_release(link);
 
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
 	/* Unlink device structure, and free it */
 	*linkp = link->next;
 	DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
@@ -577,30 +574,15 @@ orinoco_cs_event(event_t event, int prio
 		       event_callback_args_t * args)
 {
 	dev_link_t *link = args->client_data;
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			unsigned long flags;
-
-			spin_lock_irqsave(&priv->lock, flags);
-			netif_device_detach(dev);
-			priv->hw_unavailable++;
-			spin_unlock_irqrestore(&priv->lock, flags);
-		}
-		break;
-
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		orinoco_cs_config(link);
 		break;
 	}
 
-	return err;
+	return 0;
 }				/* orinoco_cs_event */
 
 /********************************************************************/
@@ -667,7 +649,7 @@ static struct pcmcia_driver orinoco_driv
 	},
 	.attach		= orinoco_cs_attach,
 	.event		= orinoco_cs_event,
-	.detach		= orinoco_cs_detach,
+	.remove		= orinoco_cs_detach,
 	.id_table       = orinoco_cs_ids,
 	.suspend	= orinoco_cs_suspend,
 	.resume		= orinoco_cs_resume,
diff -puN drivers/net/wireless/ray_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/wireless/ray_cs.c
--- devel/drivers/net/wireless/ray_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/wireless/ray_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -94,7 +94,7 @@ static void ray_config(dev_link_t *link)
 static void ray_release(dev_link_t *link);
 static int ray_event(event_t event, int priority, event_callback_args_t *args);
 static dev_link_t *ray_attach(void);
-static void ray_detach(dev_link_t *);
+static void ray_detach(struct pcmcia_device *p_dev);
 
 /***** Prototypes indicated by device structure ******************************/
 static int ray_dev_close(struct net_device *dev);
@@ -402,7 +402,7 @@ static dev_link_t *ray_attach(void)
     if (ret != 0) {
         printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");
         cs_error(link->handle, RegisterClient, ret);
-        ray_detach(link);
+        ray_detach(link->handle);
         return NULL;
     }
     DEBUG(2,"ray_cs ray_attach ending\n");
@@ -418,9 +418,12 @@ fail_alloc_dev:
     structures are freed.  Otherwise, the structures will be freed
     when the device is released.
 =============================================================================*/
-static void ray_detach(dev_link_t *link)
+static void ray_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
+    struct net_device *dev;
+    ray_dev_t *local;
 
     DEBUG(1, "ray_detach(0x%p)\n", link);
     
@@ -430,22 +433,18 @@ static void ray_detach(dev_link_t *link)
     if (*linkp == NULL)
         return;
 
-    /* If the device is currently configured and active, we won't
-      actually delete it yet.  Instead, it is marked so that when
-      the release() function is called, that will trigger a proper
-      detach().
-    */
-    if (link->state & DEV_CONFIG)
-        ray_release(link);
+    dev = link->priv;
+
+    if (link->state & DEV_CONFIG) {
+	    ray_release(link);
+
+	    local = (ray_dev_t *)dev->priv;
+            del_timer(&local->timer);
+    }
 
-    /* Break the link with Card Services */
-    if (link->handle)
-        pcmcia_deregister_client(link->handle);
-    
     /* Unlink device structure, free pieces */
     *linkp = link->next;
     if (link->priv) {
-        struct net_device *dev = link->priv;
 	if (link->dev) unregister_netdev(dev);
         free_netdev(dev);
     }
@@ -940,19 +939,9 @@ static int ray_event(event_t event, int 
                      event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
     DEBUG(1, "ray_event(0x%06x)\n", event);
-    
+
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-        link->state &= ~DEV_PRESENT;
-        netif_device_detach(dev);
-        if (link->state & DEV_CONFIG) {
-	    ray_release(link);
-            del_timer(&local->timer);
-        }
-        break;
     case CS_EVENT_CARD_INSERTION:
         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
         ray_config(link);
@@ -2958,7 +2947,7 @@ static struct pcmcia_driver ray_driver =
 	},
 	.attach		= ray_attach,
 	.event		= ray_event,
-	.detach		= ray_detach,
+	.remove		= ray_detach,
 	.id_table       = ray_ids,
 	.suspend	= ray_suspend,
 	.resume		= ray_resume,
diff -puN drivers/net/wireless/wavelan_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/wireless/wavelan_cs.c
--- devel/drivers/net/wireless/wavelan_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/wireless/wavelan_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -4701,7 +4701,7 @@ wavelan_attach(void)
   if(ret != 0)
     {
       cs_error(link->handle, RegisterClient, ret);
-      wavelan_detach(link);
+      wavelan_detach(link->handle);
       return NULL;
     }
 
@@ -4720,8 +4720,10 @@ wavelan_attach(void)
  * is released.
  */
 static void
-wavelan_detach(dev_link_t *	link)
+wavelan_detach(struct pcmcia_device *p_dev)
 {
+   dev_link_t *link = dev_to_instance(p_dev);
+
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
 #endif
@@ -4738,10 +4740,6 @@ wavelan_detach(dev_link_t *	link)
       wv_pcmcia_release(link);
     }
 
-  /* Break the link with Card Services */
-  if(link->handle)
-    pcmcia_deregister_client(link->handle);
-    
   /* Remove the interface data from the linked list */
   if(dev_list == link)
     dev_list = link->next;
@@ -4863,25 +4861,6 @@ wavelan_event(event_t		event,		/* The ev
 
     switch(event)
       {
-      case CS_EVENT_REGISTRATION_COMPLETE:
-#ifdef DEBUG_CONFIG_INFO
-	printk(KERN_DEBUG "wavelan_cs: registration complete\n");
-#endif
-	break;
-
-      case CS_EVENT_CARD_REMOVAL:
-	/* Oups ! The card is no more there */
-	link->state &= ~DEV_PRESENT;
-	if(link->state & DEV_CONFIG)
-	  {
-	    /* Accept no more transmissions */
-	    netif_device_detach(dev);
-
-	    /* Release the card */
-	    wv_pcmcia_release(link);
-	  }
-	break;
-
       case CS_EVENT_CARD_INSERTION:
 	/* Reset and configure the card */
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
@@ -4915,7 +4894,7 @@ static struct pcmcia_driver wavelan_driv
 	},
 	.attach		= wavelan_attach,
 	.event		= wavelan_event,
-	.detach		= wavelan_detach,
+	.remove		= wavelan_detach,
 	.id_table       = wavelan_ids,
 	.suspend	= wavelan_suspend,
 	.resume		= wavelan_resume,
diff -puN drivers/net/wireless/wavelan_cs.p.h~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/wireless/wavelan_cs.p.h
--- devel/drivers/net/wireless/wavelan_cs.p.h~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/wireless/wavelan_cs.p.h	2005-09-07 20:10:52.000000000 -0700
@@ -761,7 +761,7 @@ static int
 static dev_link_t *
 	wavelan_attach(void);		/* Create a new device */
 static void
-	wavelan_detach(dev_link_t *);	/* Destroy a removed device */
+	wavelan_detach(struct pcmcia_device *p_dev);	/* Destroy a removed device */
 static int
 	wavelan_event(event_t,		/* Manage pcmcia events */
 		      int,
diff -puN drivers/net/wireless/wl3501_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/net/wireless/wl3501_cs.c
--- devel/drivers/net/wireless/wl3501_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/net/wireless/wl3501_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -1498,9 +1498,11 @@ static struct ethtool_ops ops = {
  * Services. If it has been released, all local data structures are freed.
  * Otherwise, the structures will be freed when the device is released.
  */
-static void wl3501_detach(dev_link_t *link)
+static void wl3501_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
+	struct net_device *dev = link->priv;
 
 	/* Locate device structure */
 	for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next)
@@ -1514,16 +1516,12 @@ static void wl3501_detach(dev_link_t *li
 	 * function is called, that will trigger a proper detach(). */
 
 	if (link->state & DEV_CONFIG) {
-#ifdef PCMCIA_DEBUG
-		printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' "
-		       "still locked\n", link->dev->dev_name);
-#endif
-		goto out;
-	}
+		while (link->open > 0)
+			wl3501_close(dev);
 
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
+		netif_device_detach(dev);
+		wl3501_release(link);
+	}
 
 	/* Unlink device structure, free pieces */
 	*linkp = link->next;
@@ -2013,7 +2011,7 @@ static dev_link_t *wl3501_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret) {
 		cs_error(link->handle, RegisterClient, ret);
-		wl3501_detach(link);
+		wl3501_detach(link->handle);
 		link = NULL;
 	}
 out:
@@ -2226,18 +2224,8 @@ static int wl3501_resume(struct pcmcia_d
 static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	struct net_device *dev = link->priv;
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			while (link->open > 0)
-				wl3501_close(dev);
-			netif_device_detach(dev);
-			wl3501_release(link);
-		}
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		wl3501_config(link);
@@ -2259,7 +2247,7 @@ static struct pcmcia_driver wl3501_drive
 	},
 	.attach		= wl3501_attach,
 	.event		= wl3501_event,
-	.detach		= wl3501_detach,
+	.remove		= wl3501_detach,
 	.id_table	= wl3501_ids,
 	.suspend	= wl3501_suspend,
 	.resume		= wl3501_resume,
diff -puN drivers/parport/parport_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/parport/parport_cs.c
--- devel/drivers/parport/parport_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/parport/parport_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -88,7 +88,7 @@ typedef struct parport_info_t {
 } parport_info_t;
 
 static dev_link_t *parport_attach(void);
-static void parport_detach(dev_link_t *);
+static void parport_detach(struct pcmcia_device *p_dev);
 static void parport_config(dev_link_t *link);
 static void parport_cs_release(dev_link_t *);
 static int parport_event(event_t event, int priority,
@@ -137,7 +137,7 @@ static dev_link_t *parport_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != CS_SUCCESS) {
 	cs_error(link->handle, RegisterClient, ret);
-	parport_detach(link);
+	parport_detach(link->handle);
 	return NULL;
     }
     
@@ -153,13 +153,13 @@ static dev_link_t *parport_attach(void)
 
 ======================================================================*/
 
-static void parport_detach(dev_link_t *link)
+static void parport_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
-    int ret;
 
     DEBUG(0, "parport_detach(0x%p)\n", link);
-    
+
     /* Locate device structure */
     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
 	if (*linkp == link) break;
@@ -168,17 +168,10 @@ static void parport_detach(dev_link_t *l
 
     if (link->state & DEV_CONFIG)
 	parport_cs_release(link);
-    
-    if (link->handle) {
-	ret = pcmcia_deregister_client(link->handle);
-	if (ret != CS_SUCCESS)
-	    cs_error(link->handle, DeregisterClient, ret);
-    }
-    
+
     /* Unlink, free device structure */
     *linkp = link->next;
     kfree(link->priv);
-    
 } /* parport_detach */
 
 /*======================================================================
@@ -362,11 +355,6 @@ int parport_event(event_t event, int pri
     DEBUG(1, "parport_event(0x%06x)\n", event);
     
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-		parport_cs_release(link);
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	parport_config(link);
@@ -389,7 +377,7 @@ static struct pcmcia_driver parport_cs_d
 	},
 	.attach		= parport_attach,
 	.event		= parport_event,
-	.detach		= parport_detach,
+	.remove		= parport_detach,
 	.id_table	= parport_ids,
 	.suspend	= parport_suspend,
 	.resume		= parport_resume,
diff -puN drivers/scsi/pcmcia/aha152x_stub.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/scsi/pcmcia/aha152x_stub.c
--- devel/drivers/scsi/pcmcia/aha152x_stub.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/scsi/pcmcia/aha152x_stub.c	2005-09-07 20:10:52.000000000 -0700
@@ -99,7 +99,7 @@ static int aha152x_event(event_t event, 
 			 event_callback_args_t *args);
 
 static dev_link_t *aha152x_attach(void);
-static void aha152x_detach(dev_link_t *);
+static void aha152x_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list;
 static dev_info_t dev_info = "aha152x_cs";
@@ -138,7 +138,7 @@ static dev_link_t *aha152x_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != 0) {
 	cs_error(link->handle, RegisterClient, ret);
-	aha152x_detach(link);
+	aha152x_detach(link->handle);
 	return NULL;
     }
     
@@ -147,8 +147,9 @@ static dev_link_t *aha152x_attach(void)
 
 /*====================================================================*/
 
-static void aha152x_detach(dev_link_t *link)
+static void aha152x_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
 
     DEBUG(0, "aha152x_detach(0x%p)\n", link);
@@ -162,9 +163,6 @@ static void aha152x_detach(dev_link_t *l
     if (link->state & DEV_CONFIG)
 	aha152x_release_cs(link);
 
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
     /* Unlink device structure, free bits */
     *linkp = link->next;
     kfree(link->priv);
@@ -307,11 +305,6 @@ static int aha152x_event(event_t event, 
     DEBUG(0, "aha152x_event(0x%06x)\n", event);
     
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    aha152x_release_cs(link);
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	aha152x_config_cs(link);
@@ -337,7 +330,7 @@ static struct pcmcia_driver aha152x_cs_d
 	},
 	.attach		= aha152x_attach,
 	.event		= aha152x_event,
-	.detach		= aha152x_detach,
+	.remove		= aha152x_detach,
 	.id_table       = aha152x_ids,
 	.suspend	= aha152x_suspend,
 	.resume		= aha152x_resume,
diff -puN drivers/scsi/pcmcia/fdomain_stub.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/scsi/pcmcia/fdomain_stub.c
--- devel/drivers/scsi/pcmcia/fdomain_stub.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/scsi/pcmcia/fdomain_stub.c	2005-09-07 20:10:52.000000000 -0700
@@ -84,7 +84,7 @@ static int fdomain_event(event_t event, 
 			event_callback_args_t *args);
 
 static dev_link_t *fdomain_attach(void);
-static void fdomain_detach(dev_link_t *);
+static void fdomain_detach(struct pcmcia_device *p_dev);
 
 
 static dev_link_t *dev_list = NULL;
@@ -124,7 +124,7 @@ static dev_link_t *fdomain_attach(void)
     ret = pcmcia_register_client(&link->handle, &client_reg);
     if (ret != 0) {
 	cs_error(link->handle, RegisterClient, ret);
-	fdomain_detach(link);
+	fdomain_detach(link->handle);
 	return NULL;
     }
     
@@ -133,8 +133,9 @@ static dev_link_t *fdomain_attach(void)
 
 /*====================================================================*/
 
-static void fdomain_detach(dev_link_t *link)
+static void fdomain_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
 
     DEBUG(0, "fdomain_detach(0x%p)\n", link);
@@ -148,9 +149,6 @@ static void fdomain_detach(dev_link_t *l
     if (link->state & DEV_CONFIG)
 	fdomain_release(link);
 
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
     /* Unlink device structure, free bits */
     *linkp = link->next;
     kfree(link->priv);
@@ -288,11 +286,6 @@ static int fdomain_event(event_t event, 
     DEBUG(1, "fdomain_event(0x%06x)\n", event);
     
     switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    fdomain_release(link);
-	break;
     case CS_EVENT_CARD_INSERTION:
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	fdomain_config(link);
@@ -317,7 +310,7 @@ static struct pcmcia_driver fdomain_cs_d
 	},
 	.attach		= fdomain_attach,
 	.event		= fdomain_event,
-	.detach		= fdomain_detach,
+	.remove		= fdomain_detach,
 	.id_table       = fdomain_ids,
 	.suspend	= fdomain_suspend,
 	.resume		= fdomain_resume,
diff -puN drivers/scsi/pcmcia/nsp_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/scsi/pcmcia/nsp_cs.c
--- devel/drivers/scsi/pcmcia/nsp_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/scsi/pcmcia/nsp_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -1646,7 +1646,7 @@ static dev_link_t *nsp_cs_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		nsp_cs_detach(link);
+		nsp_cs_detach(link->handle);
 		return NULL;
 	}
 
@@ -1662,8 +1662,9 @@ static dev_link_t *nsp_cs_attach(void)
     structures are freed.  Otherwise, the structures will be freed
     when the device is released.
 ======================================================================*/
-static void nsp_cs_detach(dev_link_t *link)
+static void nsp_cs_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
 
 	nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
@@ -1678,12 +1679,9 @@ static void nsp_cs_detach(dev_link_t *li
 		return;
 	}
 
-	if (link->state & DEV_CONFIG)
+	if (link->state & DEV_CONFIG) {
+		((scsi_info_t *)link->priv)->stop = 1;
 		nsp_cs_release(link);
-
-	/* Break the link with Card Services */
-	if (link->handle) {
-		pcmcia_deregister_client(link->handle);
 	}
 
 	/* Unlink device structure, free bits */
@@ -2096,15 +2094,6 @@ static int nsp_cs_event(event_t		       
 	nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		nsp_dbg(NSP_DEBUG_INIT, "event: remove");
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			((scsi_info_t *)link->priv)->stop = 1;
-			nsp_cs_release(link);
-		}
-		break;
-
 	case CS_EVENT_CARD_INSERTION:
 		nsp_dbg(NSP_DEBUG_INIT, "event: insert");
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
@@ -2144,7 +2133,7 @@ static struct pcmcia_driver nsp_driver =
 	},
 	.attach		= nsp_cs_attach,
 	.event		= nsp_cs_event,
-	.detach		= nsp_cs_detach,
+	.remove		= nsp_cs_detach,
 	.id_table	= nsp_cs_ids,
 	.suspend	= nsp_cs_suspend,
 	.resume		= nsp_cs_resume,
diff -puN drivers/scsi/pcmcia/nsp_cs.h~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/scsi/pcmcia/nsp_cs.h
--- devel/drivers/scsi/pcmcia/nsp_cs.h~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/scsi/pcmcia/nsp_cs.h	2005-09-07 20:10:52.000000000 -0700
@@ -297,7 +297,7 @@ typedef struct _nsp_hw_data {
 
 /* Card service functions */
 static dev_link_t *nsp_cs_attach (void);
-static void        nsp_cs_detach (dev_link_t *link);
+static void        nsp_cs_detach (struct pcmcia_device *p_dev);
 static void        nsp_cs_release(dev_link_t *link);
 static void        nsp_cs_config (dev_link_t *link);
 static int         nsp_cs_event  (event_t event, int priority, event_callback_args_t *args);
diff -puN drivers/scsi/pcmcia/qlogic_stub.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/scsi/pcmcia/qlogic_stub.c
--- devel/drivers/scsi/pcmcia/qlogic_stub.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/scsi/pcmcia/qlogic_stub.c	2005-09-07 20:10:52.000000000 -0700
@@ -101,7 +101,7 @@ static void qlogic_release(dev_link_t *l
 static int qlogic_event(event_t event, int priority, event_callback_args_t * args);
 
 static dev_link_t *qlogic_attach(void);
-static void qlogic_detach(dev_link_t *);
+static void qlogic_detach(struct pcmcia_device *p_dev);
 
 
 static dev_link_t *dev_list = NULL;
@@ -198,7 +198,7 @@ static dev_link_t *qlogic_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != 0) {
 		cs_error(link->handle, RegisterClient, ret);
-		qlogic_detach(link);
+		qlogic_detach(link->handle);
 		return NULL;
 	}
 
@@ -207,8 +207,9 @@ static dev_link_t *qlogic_attach(void)
 
 /*====================================================================*/
 
-static void qlogic_detach(dev_link_t * link)
+static void qlogic_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
 
 	DEBUG(0, "qlogic_detach(0x%p)\n", link);
@@ -223,9 +224,6 @@ static void qlogic_detach(dev_link_t * l
 	if (link->state & DEV_CONFIG)
 		qlogic_release(link);
 
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
 	/* Unlink device structure, free bits */
 	*linkp = link->next;
 	kfree(link->priv);
@@ -390,11 +388,6 @@ static int qlogic_event(event_t event, i
 	DEBUG(1, "qlogic_event(0x%06x)\n", event);
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
-			qlogic_release(link);
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		qlogic_config(link);
@@ -432,7 +425,7 @@ static struct pcmcia_driver qlogic_cs_dr
 	},
 	.attach		= qlogic_attach,
 	.event		= qlogic_event,
-	.detach		= qlogic_detach,
+	.remove		= qlogic_detach,
 	.id_table       = qlogic_ids,
 	.suspend	= qlogic_suspend,
 	.resume		= qlogic_resume,
diff -puN drivers/scsi/pcmcia/sym53c500_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/scsi/pcmcia/sym53c500_cs.c
--- devel/drivers/scsi/pcmcia/sym53c500_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/scsi/pcmcia/sym53c500_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -918,11 +918,6 @@ SYM53C500_event(event_t event, int prior
 	DEBUG(1, "SYM53C500_event(0x%06x)\n", event);
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
-			SYM53C500_release(link);
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		SYM53C500_config(link);
@@ -932,8 +927,9 @@ SYM53C500_event(event_t event, int prior
 } /* SYM53C500_event */
 
 static void
-SYM53C500_detach(dev_link_t *link)
+SYM53C500_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
 
 	DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
@@ -948,9 +944,6 @@ SYM53C500_detach(dev_link_t *link)
 	if (link->state & DEV_CONFIG)
 		SYM53C500_release(link);
 
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
 	/* Unlink device structure, free bits. */
 	*linkp = link->next;
 	kfree(link->priv);
@@ -993,7 +986,7 @@ SYM53C500_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != 0) {
 		cs_error(link->handle, RegisterClient, ret);
-		SYM53C500_detach(link);
+		SYM53C500_detach(link->handle);
 		return NULL;
 	}
 
@@ -1019,7 +1012,7 @@ static struct pcmcia_driver sym53c500_cs
 	},
 	.attach		= SYM53C500_attach,
 	.event		= SYM53C500_event,
-	.detach		= SYM53C500_detach,
+	.remove		= SYM53C500_detach,
 	.id_table       = sym53c500_ids,
 	.suspend	= sym53c500_suspend,
 	.resume		= sym53c500_resume,
diff -puN drivers/serial/serial_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/serial/serial_cs.c
--- devel/drivers/serial/serial_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/serial/serial_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -120,7 +120,7 @@ static int serial_event(event_t event, i
 static dev_info_t dev_info = "serial_cs";
 
 static dev_link_t *serial_attach(void);
-static void serial_detach(dev_link_t *);
+static void serial_detach(struct pcmcia_device *p_dev);
 
 static dev_link_t *dev_list = NULL;
 
@@ -242,7 +242,7 @@ static dev_link_t *serial_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		serial_detach(link);
+		serial_detach(link->handle);
 		return NULL;
 	}
 
@@ -258,11 +258,11 @@ static dev_link_t *serial_attach(void)
 
 ======================================================================*/
 
-static void serial_detach(dev_link_t * link)
+static void serial_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct serial_info *info = link->priv;
 	dev_link_t **linkp;
-	int ret;
 
 	DEBUG(0, "serial_detach(0x%p)\n", link);
 
@@ -283,12 +283,6 @@ static void serial_detach(dev_link_t * l
 	 */
 	serial_remove(link);
 
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
 	/* Unlink device structure, free bits */
 	*linkp = link->next;
 	kfree(info);
@@ -741,9 +735,6 @@ serial_event(event_t event, int priority
 	DEBUG(1, "serial_event(0x%06x)\n", event);
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		serial_remove(link);
-		break;
 
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
@@ -865,7 +856,7 @@ static struct pcmcia_driver serial_cs_dr
 	},
 	.attach		= serial_attach,
 	.event		= serial_event,
-	.detach		= serial_detach,
+	.remove		= serial_detach,
 	.id_table	= serial_ids,
 	.suspend	= serial_suspend,
 	.resume		= serial_resume,
diff -puN drivers/telephony/ixj_pcmcia.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/telephony/ixj_pcmcia.c
--- devel/drivers/telephony/ixj_pcmcia.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/telephony/ixj_pcmcia.c	2005-09-07 20:10:52.000000000 -0700
@@ -35,7 +35,7 @@ typedef struct ixj_info_t {
 } ixj_info_t;
 
 static dev_link_t *ixj_attach(void);
-static void ixj_detach(dev_link_t *);
+static void ixj_detach(struct pcmcia_device *p_dev);
 static void ixj_config(dev_link_t * link);
 static void ixj_cs_release(dev_link_t * link);
 static int ixj_event(event_t event, int priority, event_callback_args_t * args);
@@ -73,16 +73,17 @@ static dev_link_t *ixj_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		ixj_detach(link);
+		ixj_detach(link->handle);
 		return NULL;
 	}
 	return link;
 }
 
-static void ixj_detach(dev_link_t * link)
+static void ixj_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
-	int ret;
+
 	DEBUG(0, "ixj_detach(0x%p)\n", link);
 	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
 		if (*linkp == link)
@@ -92,11 +93,7 @@ static void ixj_detach(dev_link_t * link
 	link->state &= ~DEV_RELEASE_PENDING;
 	if (link->state & DEV_CONFIG)
 		ixj_cs_release(link);
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
+
 	/* Unlink device structure, free bits */
 	*linkp = link->next;
         kfree(link->priv);
@@ -282,13 +279,6 @@ static int ixj_event(event_t event, int 
 	dev_link_t *link = args->client_data;
 	DEBUG(1, "ixj_event(0x%06x)\n", event);
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			link->state |= DEV_RELEASE_PENDING;
-			ixj_cs_release(link);
-		}
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		ixj_config(link);
@@ -310,7 +300,7 @@ static struct pcmcia_driver ixj_driver =
 	},
 	.attach		= ixj_attach,
 	.event		= ixj_event,
-	.detach		= ixj_detach,
+	.remove		= ixj_detach,
 	.id_table	= ixj_ids,
 	.suspend	= ixj_suspend,
 	.resume		= ixj_resume,
diff -puN drivers/usb/host/sl811_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path drivers/usb/host/sl811_cs.c
--- devel/drivers/usb/host/sl811_cs.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/drivers/usb/host/sl811_cs.c	2005-09-07 20:10:52.000000000 -0700
@@ -72,6 +72,8 @@ typedef struct local_info_t {
 	dev_node_t		node;
 } local_info_t;
 
+static void sl811_cs_release(dev_link_t * link);
+
 /*====================================================================*/
 
 static void release_platform_dev(struct device * dev)
@@ -136,8 +138,9 @@ static int sl811_hc_init(struct device *
 
 /*====================================================================*/
 
-static void sl811_cs_detach(dev_link_t *link)
+static void sl811_cs_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
 
 	DBG(0, "sl811_cs_detach(0x%p)\n", link);
@@ -150,9 +153,9 @@ static void sl811_cs_detach(dev_link_t *
 	if (*linkp == NULL)
 		return;
 
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
+	link->state &= ~DEV_PRESENT;
+	if (link->state & DEV_CONFIG)
+		sl811_cs_release(link);
 
 	/* Unlink device structure, and free it */
 	*linkp = link->next;
@@ -165,13 +168,6 @@ static void sl811_cs_release(dev_link_t 
 
 	DBG(0, "sl811_cs_release(0x%p)\n", link);
 
-	if (link->open) {
-		DBG(1, "sl811_cs: release postponed, '%s' still open\n",
-		    link->dev->dev_name);
-		link->state |= DEV_STALE_CONFIG;
-		return;
-	}
-
 	/* Unlink the device chain */
 	link->dev = NULL;
 
@@ -182,9 +178,6 @@ static void sl811_cs_release(dev_link_t 
 	if (link->irq.AssignedIRQ)
 		pcmcia_release_irq(link->handle, &link->irq);
 	link->state &= ~DEV_CONFIG;
-
-	if (link->state & DEV_STALE_LINK)
-		sl811_cs_detach(link);
 }
 
 static void sl811_cs_config(dev_link_t *link)
@@ -351,12 +344,6 @@ sl811_cs_event(event_t event, int priori
 	DBG(1, "sl811_cs_event(0x%06x)\n", event);
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
-			sl811_cs_release(link);
-		break;
-
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 		sl811_cs_config(link);
@@ -398,7 +385,7 @@ static dev_link_t *sl811_cs_attach(void)
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		sl811_cs_detach(link);
+		sl811_cs_detach(link->handle);
 		return NULL;
 	}
 
@@ -418,7 +405,7 @@ static struct pcmcia_driver sl811_cs_dri
 	},
 	.attach		= sl811_cs_attach,
 	.event		= sl811_cs_event,
-	.detach		= sl811_cs_detach,
+	.remove		= sl811_cs_detach,
 	.id_table	= sl811_ids,
 	.suspend	= sl811_suspend,
 	.resume		= sl811_resume,
diff -puN sound/pcmcia/pdaudiocf/pdaudiocf.c~pcmcia-convert-drivers-to-use-unified-removal-code-path sound/pcmcia/pdaudiocf/pdaudiocf.c
--- devel/sound/pcmcia/pdaudiocf/pdaudiocf.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/sound/pcmcia/pdaudiocf/pdaudiocf.c	2005-09-07 20:10:52.000000000 -0700
@@ -61,7 +61,7 @@ static dev_link_t *dev_list;
  */
 static void pdacf_config(dev_link_t *link);
 static int pdacf_event(event_t event, int priority, event_callback_args_t *args);
-static void snd_pdacf_detach(dev_link_t *link);
+static void snd_pdacf_detach(struct pcmcia_device *p_dev);
 
 static void pdacf_release(dev_link_t *link)
 {
@@ -83,10 +83,6 @@ static int snd_pdacf_free(pdacf_t *pdacf
 
 	pdacf_release(link);
 
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
 	card_list[pdacf->index] = NULL;
 	pdacf->card = NULL;
 
@@ -176,7 +172,7 @@ static dev_link_t *snd_pdacf_attach(void
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		snd_pdacf_detach(link);
+		snd_pdacf_detach(link->handle);
 		return NULL;
 	}
 
@@ -229,8 +225,9 @@ static int snd_pdacf_assign_resources(pd
 /*
  * snd_pdacf_detach - detach callback for cs
  */
-static void snd_pdacf_detach(dev_link_t *link)
+static void snd_pdacf_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	pdacf_t *chip = link->priv;
 
 	snd_printdd(KERN_DEBUG "pdacf_detach called\n");
@@ -363,16 +360,8 @@ static int pdacf_resume(struct pcmcia_de
 static int pdacf_event(event_t event, int priority, event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	pdacf_t *chip = link->priv;
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n");
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			chip->chip_status |= PDAUDIOCF_STAT_IS_STALE;
-		}
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n");
 		link->state |= DEV_PRESENT;
@@ -398,7 +387,7 @@ static struct pcmcia_driver pdacf_cs_dri
 	},
 	.attach		= snd_pdacf_attach,
 	.event		= pdacf_event,
-	.detach		= snd_pdacf_detach,
+	.remove		= snd_pdacf_detach,
 	.id_table	= snd_pdacf_ids,
 #ifdef CONFIG_PM
 	.suspend	= pdacf_suspend,
diff -puN sound/pcmcia/vx/vxpocket.c~pcmcia-convert-drivers-to-use-unified-removal-code-path sound/pcmcia/vx/vxpocket.c
--- devel/sound/pcmcia/vx/vxpocket.c~pcmcia-convert-drivers-to-use-unified-removal-code-path	2005-09-07 20:10:52.000000000 -0700
+++ devel-akpm/sound/pcmcia/vx/vxpocket.c	2005-09-07 20:10:52.000000000 -0700
@@ -73,11 +73,6 @@ static void vxpocket_release(dev_link_t 
 		pcmcia_release_irq(link->handle, &link->irq);
 		link->state &= ~DEV_CONFIG;
 	}
-	if (link->handle) {
-		/* Break the link with Card Services */
-		pcmcia_deregister_client(link->handle);
-		link->handle = NULL;
-	}
 }
 
 /*
@@ -368,15 +363,8 @@ static int vxp_resume(struct pcmcia_devi
 static int vxpocket_event(event_t event, int priority, event_callback_args_t *args)
 {
 	dev_link_t *link = args->client_data;
-	vx_core_t *chip = link->priv;
 
 	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n");
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
-			chip->chip_status |= VX_STAT_IS_STALE;
-		break;
 	case CS_EVENT_CARD_INSERTION:
 		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n");
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
@@ -430,8 +418,9 @@ static dev_link_t *vxpocket_attach(void)
 	return &vxp->link;
 }
 
-static void vxpocket_detach(dev_link_t *link)
+static void vxpocket_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct snd_vxpocket *vxp;
 	vx_core_t *chip;
 	dev_link_t **linkp;
@@ -472,7 +461,7 @@ static struct pcmcia_driver vxp_cs_drive
 		.name	= "snd-vxpocket",
 	},
 	.attach		= vxpocket_attach,
-	.detach		= vxpocket_detach,
+	.remove		= vxpocket_detach,
 	.event		= vxpocket_event,
 	.id_table	= vxp_ids,
 #ifdef CONFIG_PM
_