summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorJody McIntyre <scjody@modernduck.com>2006-01-05 22:22:50 -0500
committerJody McIntyre <scjody@modernduck.com>2006-01-05 22:22:50 -0500
commit52cab57873c25d3c8324ee3e4d463db6e8e73fd7 (patch)
tree826cb36827afa363944e6478d19512e669446c64 /drivers
parent0a75c23a009ff65f651532cecc16675d05f4de37 (diff)
parent46f25dffbaba48c571d75f5f574f31978287b8d2 (diff)
downloadlinux-52cab57873c25d3c8324ee3e4d463db6e8e73fd7.tar.gz
Merge with http://kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/power/runtime.c1
-rw-r--r--drivers/bluetooth/bluecard_cs.c109
-rw-r--r--drivers/bluetooth/bt3c_cs.c110
-rw-r--r--drivers/bluetooth/btuart_cs.c110
-rw-r--r--drivers/bluetooth/dtl1_cs.c111
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c162
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c151
-rw-r--r--drivers/char/pcmcia/synclink_cs.c132
-rw-r--r--drivers/ide/legacy/ide-cs.c132
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c145
-rw-r--r--drivers/isdn/hisax/avma1_cs.c150
-rw-r--r--drivers/isdn/hisax/elsa_cs.c158
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c169
-rw-r--r--drivers/isdn/hisax/teles_cs.c149
-rw-r--r--drivers/mtd/maps/pcmciamtd.c121
-rw-r--r--drivers/net/pcmcia/3c574_cs.c124
-rw-r--r--drivers/net/pcmcia/3c589_cs.c136
-rw-r--r--drivers/net/pcmcia/axnet_cs.c128
-rw-r--r--drivers/net/pcmcia/com20020_cs.c142
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c128
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c152
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c134
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c129
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c195
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c158
-rw-r--r--drivers/net/wireless/airo_cs.c161
-rw-r--r--drivers/net/wireless/atmel_cs.c156
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c156
-rw-r--r--drivers/net/wireless/netwave_cs.c184
-rw-r--r--drivers/net/wireless/orinoco_cs.c208
-rw-r--r--drivers/net/wireless/ray_cs.c154
-rw-r--r--drivers/net/wireless/spectrum_cs.c175
-rw-r--r--drivers/net/wireless/wavelan_cs.c183
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h11
-rw-r--r--drivers/net/wireless/wl3501_cs.c133
-rw-r--r--drivers/parport/parport_cs.c120
-rw-r--r--drivers/pcmcia/Kconfig32
-rw-r--r--drivers/pcmcia/au1000_generic.c21
-rw-r--r--drivers/pcmcia/cistpl.c36
-rw-r--r--drivers/pcmcia/cs.c102
-rw-r--r--drivers/pcmcia/cs_internal.h4
-rw-r--r--drivers/pcmcia/ds.c351
-rw-r--r--drivers/pcmcia/hd64465_ss.c13
-rw-r--r--drivers/pcmcia/i82092.c73
-rw-r--r--drivers/pcmcia/i82092aa.h1
-rw-r--r--drivers/pcmcia/i82365.c83
-rw-r--r--drivers/pcmcia/m32r_cfc.c32
-rw-r--r--drivers/pcmcia/m32r_pcc.c20
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c114
-rw-r--r--drivers/pcmcia/pd6729.c74
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c3
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c3
-rw-r--r--drivers/pcmcia/rsrc_mgr.c108
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c140
-rw-r--r--drivers/pcmcia/soc_common.c23
-rw-r--r--drivers/pcmcia/socket_sysfs.c30
-rw-r--r--drivers/pcmcia/tcic.c61
-rw-r--r--drivers/pcmcia/ti113x.h4
-rw-r--r--drivers/pcmcia/vrc4171_card.c70
-rw-r--r--drivers/pcmcia/vrc4173_cardu.c43
-rw-r--r--drivers/pcmcia/yenta_socket.c140
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c99
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c117
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c167
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h4
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c127
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c133
-rw-r--r--drivers/serial/serial_cs.c119
-rw-r--r--drivers/telephony/ixj_pcmcia.c112
-rw-r--r--drivers/usb/host/sl811_cs.c110
-rw-r--r--drivers/video/aty/atyfb_base.c2
71 files changed, 2400 insertions, 5148 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 4bafef83e79f..96370ec1d673 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -62,6 +62,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
 	up(&dpm_sem);
 	return error;
 }
+EXPORT_SYMBOL(dpm_runtime_suspend);
 
 
 #if 0
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index f36c563d72c4..9888bc151755 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -87,14 +87,8 @@ typedef struct bluecard_info_t {
 
 static void bluecard_config(dev_link_t *link);
 static void bluecard_release(dev_link_t *link);
-static int bluecard_event(event_t event, int priority, event_callback_args_t *args);
 
-static dev_info_t dev_info = "bluecard_cs";
-
-static dev_link_t *bluecard_attach(void);
-static void bluecard_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
+static void bluecard_detach(struct pcmcia_device *p_dev);
 
 
 /* Default baud rate: 57600, 115200, 230400 or 460800 */
@@ -862,17 +856,15 @@ static int bluecard_close(bluecard_info_t *info)
 	return 0;
 }
 
-static dev_link_t *bluecard_attach(void)
+static int bluecard_attach(struct pcmcia_device *p_dev)
 {
 	bluecard_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 
 	link = &info->link;
 	link->priv = info;
@@ -889,50 +881,24 @@ static dev_link_t *bluecard_attach(void)
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		bluecard_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	bluecard_config(link);
+
+	return 0;
 }
 
 
-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)
-		if (*linkp == link)
-			break;
-
-	if (*linkp == NULL)
-		return;
 
 	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;
-
 	kfree(info);
 }
 
@@ -1045,39 +1011,24 @@ static void bluecard_release(dev_link_t *link)
 	link->state &= ~DEV_CONFIG;
 }
 
+static int bluecard_suspend(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-static int bluecard_event(event_t event, int priority, event_callback_args_t *args)
+	return 0;
+}
+
+static int bluecard_resume(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-	bluecard_info_t *info = link->priv;
+	dev_link_t *link = dev_to_instance(dev);
 
-	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);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link))
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
 
 	return 0;
 }
@@ -1095,10 +1046,11 @@ static struct pcmcia_driver bluecard_driver = {
 	.drv		= {
 		.name	= "bluecard_cs",
 	},
-	.attach		= bluecard_attach,
-	.event		= bluecard_event,
-	.detach		= bluecard_detach,
+	.probe		= bluecard_attach,
+	.remove		= bluecard_detach,
 	.id_table	= bluecard_ids,
+	.suspend	= bluecard_suspend,
+	.resume		= bluecard_resume,
 };
 
 static int __init init_bluecard_cs(void)
@@ -1110,7 +1062,6 @@ static int __init init_bluecard_cs(void)
 static void __exit exit_bluecard_cs(void)
 {
 	pcmcia_unregister_driver(&bluecard_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_bluecard_cs);
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index d2a0add19cc8..e522d19ad886 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -90,14 +90,8 @@ typedef struct bt3c_info_t {
 
 static void bt3c_config(dev_link_t *link);
 static void bt3c_release(dev_link_t *link);
-static int bt3c_event(event_t event, int priority, event_callback_args_t *args);
 
-static dev_info_t dev_info = "bt3c_cs";
-
-static dev_link_t *bt3c_attach(void);
-static void bt3c_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
+static void bt3c_detach(struct pcmcia_device *p_dev);
 
 
 /* Transmit states  */
@@ -663,17 +657,15 @@ static int bt3c_close(bt3c_info_t *info)
 	return 0;
 }
 
-static dev_link_t *bt3c_attach(void)
+static int bt3c_attach(struct pcmcia_device *p_dev)
 {
 	bt3c_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 
 	link = &info->link;
 	link->priv = info;
@@ -690,50 +682,24 @@ static dev_link_t *bt3c_attach(void)
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		bt3c_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	bt3c_config(link);
+
+	return 0;
 }
 
 
-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)
-		if (*linkp == link)
-			break;
-
-	if (*linkp == NULL)
-		return;
 
 	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;
-
 	kfree(info);
 }
 
@@ -891,43 +857,29 @@ static void bt3c_release(dev_link_t *link)
 	link->state &= ~DEV_CONFIG;
 }
 
+static int bt3c_suspend(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
 
-static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int bt3c_resume(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-	bt3c_info_t *info = link->priv;
+	dev_link_t *link = dev_to_instance(dev);
 
-	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);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link))
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
 
 	return 0;
 }
 
+
 static struct pcmcia_device_id bt3c_ids[] = {
 	PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
 	PCMCIA_DEVICE_NULL
@@ -939,10 +891,11 @@ static struct pcmcia_driver bt3c_driver = {
 	.drv		= {
 		.name	= "bt3c_cs",
 	},
-	.attach		= bt3c_attach,
-	.event		= bt3c_event,
-	.detach		= bt3c_detach,
+	.probe		= bt3c_attach,
+	.remove		= bt3c_detach,
 	.id_table	= bt3c_ids,
+	.suspend	= bt3c_suspend,
+	.resume		= bt3c_resume,
 };
 
 static int __init init_bt3c_cs(void)
@@ -954,7 +907,6 @@ static int __init init_bt3c_cs(void)
 static void __exit exit_bt3c_cs(void)
 {
 	pcmcia_unregister_driver(&bt3c_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_bt3c_cs);
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 529a28a3209d..7b4bff4cfa2d 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -86,14 +86,8 @@ typedef struct btuart_info_t {
 
 static void btuart_config(dev_link_t *link);
 static void btuart_release(dev_link_t *link);
-static int btuart_event(event_t event, int priority, event_callback_args_t *args);
 
-static dev_info_t dev_info = "btuart_cs";
-
-static dev_link_t *btuart_attach(void);
-static void btuart_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
+static void btuart_detach(struct pcmcia_device *p_dev);
 
 
 /* Maximum baud rate */
@@ -582,17 +576,15 @@ static int btuart_close(btuart_info_t *info)
 	return 0;
 }
 
-static dev_link_t *btuart_attach(void)
+static int btuart_attach(struct pcmcia_device *p_dev)
 {
 	btuart_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 
 	link = &info->link;
 	link->priv = info;
@@ -609,50 +601,24 @@ static dev_link_t *btuart_attach(void)
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		btuart_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	btuart_config(link);
+
+	return 0;
 }
 
 
-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)
-		if (*linkp == link)
-			break;
-
-	if (*linkp == NULL)
-		return;
 
 	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;
-
 	kfree(info);
 }
 
@@ -811,43 +777,29 @@ static void btuart_release(dev_link_t *link)
 	link->state &= ~DEV_CONFIG;
 }
 
+static int btuart_suspend(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
 
-static int btuart_event(event_t event, int priority, event_callback_args_t *args)
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int btuart_resume(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-	btuart_info_t *info = link->priv;
+	dev_link_t *link = dev_to_instance(dev);
 
-	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);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link))
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
 
 	return 0;
 }
 
+
 static struct pcmcia_device_id btuart_ids[] = {
 	/* don't use this driver. Use serial_cs + hci_uart instead */
 	PCMCIA_DEVICE_NULL
@@ -859,10 +811,11 @@ static struct pcmcia_driver btuart_driver = {
 	.drv		= {
 		.name	= "btuart_cs",
 	},
-	.attach		= btuart_attach,
-	.event		= btuart_event,
-	.detach		= btuart_detach,
+	.probe		= btuart_attach,
+	.remove		= btuart_detach,
 	.id_table	= btuart_ids,
+	.suspend	= btuart_suspend,
+	.resume		= btuart_resume,
 };
 
 static int __init init_btuart_cs(void)
@@ -874,7 +827,6 @@ static int __init init_btuart_cs(void)
 static void __exit exit_btuart_cs(void)
 {
 	pcmcia_unregister_driver(&btuart_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_btuart_cs);
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index dec5980a1cd6..0449bc45ae5e 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -89,14 +89,8 @@ typedef struct dtl1_info_t {
 
 static void dtl1_config(dev_link_t *link);
 static void dtl1_release(dev_link_t *link);
-static int dtl1_event(event_t event, int priority, event_callback_args_t *args);
 
-static dev_info_t dev_info = "dtl1_cs";
-
-static dev_link_t *dtl1_attach(void);
-static void dtl1_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
+static void dtl1_detach(struct pcmcia_device *p_dev);
 
 
 /* Transmit states  */
@@ -561,17 +555,15 @@ static int dtl1_close(dtl1_info_t *info)
 	return 0;
 }
 
-static dev_link_t *dtl1_attach(void)
+static int dtl1_attach(struct pcmcia_device *p_dev)
 {
 	dtl1_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 
 	link = &info->link;
 	link->priv = info;
@@ -588,50 +580,24 @@ static dev_link_t *dtl1_attach(void)
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		dtl1_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	dtl1_config(link);
+
+	return 0;
 }
 
 
-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)
-		if (*linkp == link)
-			break;
-
-	if (*linkp == NULL)
-		return;
 
 	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;
-
 	kfree(info);
 }
 
@@ -763,46 +729,33 @@ static void dtl1_release(dev_link_t *link)
 	link->state &= ~DEV_CONFIG;
 }
 
+static int dtl1_suspend(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
 
-static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int dtl1_resume(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-	dtl1_info_t *info = link->priv;
+	dev_link_t *link = dev_to_instance(dev);
 
-	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);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link))
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
 
 	return 0;
 }
 
+
 static struct pcmcia_device_id dtl1_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
 	PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
+	PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
 	PCMCIA_DEVICE_NULL
 };
 MODULE_DEVICE_TABLE(pcmcia, dtl1_ids);
@@ -812,10 +765,11 @@ static struct pcmcia_driver dtl1_driver = {
 	.drv		= {
 		.name	= "dtl1_cs",
 	},
-	.attach		= dtl1_attach,
-	.event		= dtl1_event,
-	.detach		= dtl1_detach,
+	.probe		= dtl1_attach,
+	.remove		= dtl1_detach,
 	.id_table	= dtl1_ids,
+	.suspend	= dtl1_suspend,
+	.resume		= dtl1_resume,
 };
 
 static int __init init_dtl1_cs(void)
@@ -827,7 +781,6 @@ static int __init init_dtl1_cs(void)
 static void __exit exit_dtl1_cs(void)
 {
 	pcmcia_unregister_driver(&dtl1_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_dtl1_cs);
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 61681c9f3f72..649677b5dc36 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -66,7 +66,6 @@ static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte";
 #define	T_100MSEC	msecs_to_jiffies(100)
 #define	T_500MSEC	msecs_to_jiffies(500)
 
-static void cm4000_detach(dev_link_t *link);
 static void cm4000_release(dev_link_t *link);
 
 static int major;		/* major number we get from the kernel */
@@ -156,7 +155,6 @@ struct cm4000_dev {
 		/*sbuf*/ 512*sizeof(char) - 			\
 		/*queue*/ 4*sizeof(wait_queue_head_t))
 
-static dev_info_t dev_info = MODULE_NAME;
 static dev_link_t *dev_table[CM4000_MAX_DEV];
 
 /* This table doesn't use spaces after the comma between fields and thus
@@ -1864,68 +1862,36 @@ cs_release:
 	link->state &= ~DEV_CONFIG_PENDING;
 }
 
-static int cm4000_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int cm4000_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct cm4000_dev *dev;
-	int devno;
 
-	link = args->client_data;
 	dev = link->priv;
 
-	DEBUGP(3, dev, "-> cm4000_event\n");
-	for (devno = 0; devno < CM4000_MAX_DEV; devno++)
-		if (dev_table[devno] == link)
-			break;
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+	stop_monitor(dev);
 
-	if (devno == CM4000_MAX_DEV)
-		return CS_BAD_ADAPTER;
+	return 0;
+}
 
-	switch (event) {
-	case CS_EVENT_CARD_INSERTION:
-		DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		cm4000_config(link, devno);
-		break;
-	case CS_EVENT_CARD_REMOVAL:
-		DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
-		link->state &= ~DEV_PRESENT;
-		stop_monitor(dev);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
-		      "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
-		link->state |= DEV_SUSPEND;
-		/* fall-through */
-	case CS_EVENT_RESET_PHYSICAL:
-		DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
-		if (link->state & DEV_CONFIG) {
-			DEBUGP(5, dev, "ReleaseConfiguration\n");
-			pcmcia_release_configuration(link->handle);
-		}
-		stop_monitor(dev);
-		break;
-	case CS_EVENT_PM_RESUME:
-		DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
-		      "(fall-through to CS_EVENT_CARD_RESET)\n");
-		link->state &= ~DEV_SUSPEND;
-		/* fall-through */
-	case CS_EVENT_CARD_RESET:
-		DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
-		if ((link->state & DEV_CONFIG)) {
-			DEBUGP(5, dev, "RequestConfiguration\n");
-			pcmcia_request_configuration(link->handle, &link->conf);
-		}
-		if (link->open)
-			start_monitor(dev);
-		break;
-	default:
-		DEBUGP(5, dev, "unknown event %.2x\n", event);
-		break;
-	}
-	DEBUGP(3, dev, "<- cm4000_event\n");
-	return CS_SUCCESS;
+static int cm4000_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct cm4000_dev *dev;
+
+	dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	if (link->open)
+		start_monitor(dev);
+
+	return 0;
 }
 
 static void cm4000_release(dev_link_t *link)
@@ -1935,11 +1901,10 @@ static void cm4000_release(dev_link_t *link)
 	pcmcia_release_io(link->handle, &link->io);
 }
 
-static dev_link_t *cm4000_attach(void)
+static int cm4000_attach(struct pcmcia_device *p_dev)
 {
 	struct cm4000_dev *dev;
 	dev_link_t *link;
-	client_reg_t client_reg;
 	int i;
 
 	for (i = 0; i < CM4000_MAX_DEV; i++)
@@ -1948,76 +1913,55 @@ static dev_link_t *cm4000_attach(void)
 
 	if (i == CM4000_MAX_DEV) {
 		printk(KERN_NOTICE MODULE_NAME ": all devices in use\n");
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* create a new cm4000_cs device */
 	dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL);
 	if (dev == NULL)
-		return NULL;
+		return -ENOMEM;
 
 	link = &dev->link;
 	link->priv = dev;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	dev_table[i] = link;
 
-	/* register with card services */
-	client_reg.dev_info = &dev_info;
-	client_reg.EventMask =
-	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-	    CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-
-	i = pcmcia_register_client(&link->handle, &client_reg);
-	if (i) {
-		cs_error(link->handle, RegisterClient, i);
-		cm4000_detach(link);
-		return NULL;
-	}
-
 	init_waitqueue_head(&dev->devq);
 	init_waitqueue_head(&dev->ioq);
 	init_waitqueue_head(&dev->atrq);
 	init_waitqueue_head(&dev->readq);
 
-	return link;
-}
-
-static void cm4000_detach_by_devno(int devno, dev_link_t * link)
-{
-	struct cm4000_dev *dev = link->priv;
-
-	DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno);
-
-	if (link->state & DEV_CONFIG) {
-		DEBUGP(5, dev, "device still configured (try to release it)\n");
-		cm4000_release(link);
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	if (link->handle) {
-		pcmcia_deregister_client(link->handle);
-	}
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	cm4000_config(link, i);
 
-	dev_table[devno] = NULL;
-	kfree(dev);
-	return;
+	return 0;
 }
 
-static void cm4000_detach(dev_link_t * link)
+static void cm4000_detach(struct pcmcia_device *p_dev)
 {
-	int i;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct cm4000_dev *dev = link->priv;
+	int devno;
 
 	/* find device */
-	for (i = 0; i < CM4000_MAX_DEV; i++)
-		if (dev_table[i] == link)
+	for (devno = 0; devno < CM4000_MAX_DEV; devno++)
+		if (dev_table[devno] == link)
 			break;
-
-	if (i == CM4000_MAX_DEV)
+	if (devno == CM4000_MAX_DEV)
 		return;
 
-	cm4000_detach_by_devno(i, link);
+	link->state &= ~DEV_PRESENT;
+	stop_monitor(dev);
+
+	if (link->state & DEV_CONFIG)
+ 		cm4000_release(link);
+
+	dev_table[devno] = NULL;
+ 	kfree(dev);
+
 	return;
 }
 
@@ -2042,9 +1986,10 @@ static struct pcmcia_driver cm4000_driver = {
 	.drv	  = {
 		.name = "cm4000_cs",
 		},
-	.attach   = cm4000_attach,
-	.detach   = cm4000_detach,
-	.event	  = cm4000_event,
+	.probe    = cm4000_attach,
+	.remove   = cm4000_detach,
+	.suspend  = cm4000_suspend,
+	.resume   = cm4000_resume,
 	.id_table = cm4000_ids,
 };
 
@@ -2064,13 +2009,8 @@ static int __init cmm_init(void)
 
 static void __exit cmm_exit(void)
 {
-	int i;
-
 	printk(KERN_INFO MODULE_NAME ": unloading\n");
 	pcmcia_unregister_driver(&cm4000_driver);
-	for (i = 0; i < CM4000_MAX_DEV; i++)
-		if (dev_table[i])
-			cm4000_detach_by_devno(i, dev_table[i]);
 	unregister_chrdev(major, DEVICE_NAME);
 };
 
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 4c698d908ffa..46eb371bf17e 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -65,7 +65,6 @@ static char *version =
 #define POLL_PERIOD 				msecs_to_jiffies(10)
 
 static void reader_release(dev_link_t *link);
-static void reader_detach(dev_link_t *link);
 
 static int major;
 
@@ -86,7 +85,6 @@ struct reader_dev {
 	struct timer_list 	poll_timer;
 };
 
-static dev_info_t dev_info = MODULE_NAME;
 static dev_link_t *dev_table[CM_MAX_DEV];
 
 #ifndef PCMCIA_DEBUG
@@ -629,65 +627,26 @@ cs_release:
 	link->state &= ~DEV_CONFIG_PENDING;
 }
 
-static int reader_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int reader_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link;
-	struct reader_dev *dev;
-	int devno;
+	dev_link_t *link = dev_to_instance(p_dev);
 
-	link = args->client_data;
-	dev = link->priv;
-	DEBUGP(3, dev, "-> reader_event\n");
-	for (devno = 0; devno < CM_MAX_DEV; devno++) {
-		if (dev_table[devno] == link)
-			break;
-	}
-	if (devno == CM_MAX_DEV)
-		return CS_BAD_ADAPTER;
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-	switch (event) {
-		case CS_EVENT_CARD_INSERTION:
-			DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
-			link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-			reader_config(link, devno);
-			break;
-		case CS_EVENT_CARD_REMOVAL:
-			DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
-			link->state &= ~DEV_PRESENT;
-			break;
-		case CS_EVENT_PM_SUSPEND:
-			DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
-			      "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
-			link->state |= DEV_SUSPEND;
-
-		case CS_EVENT_RESET_PHYSICAL:
-			DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
-			if (link->state & DEV_CONFIG) {
-		  		DEBUGP(5, dev, "ReleaseConfiguration\n");
-		  		pcmcia_release_configuration(link->handle);
-			}
-			break;
-		case CS_EVENT_PM_RESUME:
-			DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
-			      "(fall-through to CS_EVENT_CARD_RESET)\n");
-			link->state &= ~DEV_SUSPEND;
-
-		case CS_EVENT_CARD_RESET:
-			DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
-			if ((link->state & DEV_CONFIG)) {
-				DEBUGP(5, dev, "RequestConfiguration\n");
-		  		pcmcia_request_configuration(link->handle,
-							     &link->conf);
-			}
-			break;
-		default:
-			DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
-			       event);
-			break;
-	}
-	DEBUGP(3, dev, "<- reader_event\n");
-	return CS_SUCCESS;
+	return 0;
+}
+
+static int reader_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
 }
 
 static void reader_release(dev_link_t *link)
@@ -697,11 +656,10 @@ static void reader_release(dev_link_t *link)
 	pcmcia_release_io(link->handle, &link->io);
 }
 
-static dev_link_t *reader_attach(void)
+static int reader_attach(struct pcmcia_device *p_dev)
 {
 	struct reader_dev *dev;
 	dev_link_t *link;
-	client_reg_t client_reg;
 	int i;
 
 	for (i = 0; i < CM_MAX_DEV; i++) {
@@ -710,11 +668,11 @@ static dev_link_t *reader_attach(void)
 	}
 
 	if (i == CM_MAX_DEV)
-		return NULL;
+		return -ENODEV;
 
 	dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL);
 	if (dev == NULL)
-		return NULL;
+		return -ENOMEM;
 
 	dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
 	dev->buffer_status = 0;
@@ -725,20 +683,6 @@ static dev_link_t *reader_attach(void)
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	dev_table[i] = link;
 
-	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-	client_reg.EventMask=
-		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-		CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	i = pcmcia_register_client(&link->handle, &client_reg);
-	if (i) {
-		cs_error(link->handle, RegisterClient, i);
-		reader_detach(link);
-		return NULL;
-	}
 	init_waitqueue_head(&dev->devq);
 	init_waitqueue_head(&dev->poll_wait);
 	init_waitqueue_head(&dev->read_wait);
@@ -746,39 +690,37 @@ static dev_link_t *reader_attach(void)
 	init_timer(&dev->poll_timer);
 	dev->poll_timer.function = &cm4040_do_poll;
 
-	return link;
-}
-
-static void reader_detach_by_devno(int devno, dev_link_t *link)
-{
-	struct reader_dev *dev = link->priv;
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	if (link->state & DEV_CONFIG) {
-		DEBUGP(5, dev, "device still configured (try to release it)\n");
-		reader_release(link);
-	}
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	reader_config(link, i);
 
-	pcmcia_deregister_client(link->handle);
-	dev_table[devno] = NULL;
-	DEBUGP(5, dev, "freeing dev=%p\n", dev);
-	cm4040_stop_poll(dev);
-	kfree(dev);
-	return;
+	return 0;
 }
 
-static void reader_detach(dev_link_t *link)
+static void reader_detach(struct pcmcia_device *p_dev)
 {
-	int i;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct reader_dev *dev = link->priv;
+	int devno;
 
 	/* find device */
-	for (i = 0; i < CM_MAX_DEV; i++) {
-		if (dev_table[i] == link)
+	for (devno = 0; devno < CM_MAX_DEV; devno++) {
+		if (dev_table[devno] == link)
 			break;
 	}
-	if (i == CM_MAX_DEV)
+	if (devno == CM_MAX_DEV)
 		return;
 
-	reader_detach_by_devno(i, link);
+	link->state &= ~DEV_PRESENT;
+
+	if (link->state & DEV_CONFIG)
+		reader_release(link);
+
+	dev_table[devno] = NULL;
+	kfree(dev);
+
 	return;
 }
 
@@ -804,9 +746,10 @@ static struct pcmcia_driver reader_driver = {
   	.drv		= {
 		.name	= "cm4040_cs",
 	},
-	.attach		= reader_attach,
-	.detach		= reader_detach,
-	.event		= reader_event,
+	.probe		= reader_attach,
+	.remove		= reader_detach,
+	.suspend	= reader_suspend,
+	.resume		= reader_resume,
 	.id_table	= cm4040_ids,
 };
 
@@ -825,14 +768,8 @@ static int __init cm4040_init(void)
 
 static void __exit cm4040_exit(void)
 {
-	int i;
-
 	printk(KERN_INFO MODULE_NAME ": unloading\n");
 	pcmcia_unregister_driver(&reader_driver);
-	for (i = 0; i < CM_MAX_DEV; i++) {
-		if (dev_table[i])
-			reader_detach_by_devno(i, dev_table[i]);
-	}
 	unregister_chrdev(major, DEVICE_NAME);
 }
 
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 2c326ea53421..cf45b100eff1 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -486,13 +486,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout);
 
 static void mgslpc_config(dev_link_t *link);
 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 dev_info_t dev_info = "synclink_cs";
-static dev_link_t *dev_list = NULL;
+static void mgslpc_detach(struct pcmcia_device *p_dev);
 
 /*
  * 1st function defined in .text section. Calling this function in
@@ -539,12 +533,10 @@ static void ldisc_receive_buf(struct tty_struct *tty,
 	}
 }
 
-static dev_link_t *mgslpc_attach(void)
+static int mgslpc_attach(struct pcmcia_device *p_dev)
 {
     MGSLPC_INFO *info;
     dev_link_t *link;
-    client_reg_t client_reg;
-    int ret;
     
     if (debug_level >= DEBUG_LEVEL_INFO)
 	    printk("mgslpc_attach\n");
@@ -552,7 +544,7 @@ static dev_link_t *mgslpc_attach(void)
     info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
     if (!info) {
 	    printk("Error can't allocate device instance data\n");
-	    return NULL;
+	    return -ENOMEM;
     }
 
     memset(info, 0, sizeof(MGSLPC_INFO));
@@ -587,24 +579,15 @@ static dev_link_t *mgslpc_attach(void)
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	    cs_error(link->handle, RegisterClient, ret);
-	    mgslpc_detach(link);
-	    return NULL;
-    }
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    mgslpc_config(link);
 
     mgslpc_add_device(info);
 
-    return link;
+    return 0;
 }
 
 /* Card has been inserted.
@@ -736,85 +719,50 @@ 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 **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     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;
-    if (*linkp == NULL)
-	    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);
 }
 
-static int mgslpc_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int mgslpc_suspend(struct pcmcia_device *dev)
 {
-    dev_link_t *link = args->client_data;
-    MGSLPC_INFO *info = link->priv;
-    
-    if (debug_level >= DEBUG_LEVEL_INFO)
-	    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);
-	    break;
-    case CS_EVENT_PM_SUSPEND:
-	    link->state |= DEV_SUSPEND;
-	    /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	    /* Mark the device as stopped, to block IO until later */
-	    info->stop = 1;
-	    if (link->state & DEV_CONFIG)
-		    pcmcia_release_configuration(link->handle);
-	    break;
-    case CS_EVENT_PM_RESUME:
-	    link->state &= ~DEV_SUSPEND;
-	    /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	    if (link->state & DEV_CONFIG)
-		    pcmcia_request_configuration(link->handle, &link->conf);
-	    info->stop = 0;
-	    break;
-    }
-    return 0;
+	dev_link_t *link = dev_to_instance(dev);
+	MGSLPC_INFO *info = link->priv;
+
+	link->state |= DEV_SUSPEND;
+	info->stop = 1;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
 }
 
+static int mgslpc_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	MGSLPC_INFO *info = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
+	info->stop = 0;
+
+	return 0;
+}
+
+
 static inline int mgslpc_paranoia_check(MGSLPC_INFO *info,
 					char *name, const char *routine)
 {
@@ -3091,10 +3039,11 @@ static struct pcmcia_driver mgslpc_driver = {
 	.drv		= {
 		.name	= "synclink_cs",
 	},
-	.attach		= mgslpc_attach,
-	.event		= mgslpc_event,
-	.detach		= mgslpc_detach,
+	.probe		= mgslpc_attach,
+	.remove		= mgslpc_detach,
 	.id_table	= mgslpc_ids,
+	.suspend	= mgslpc_suspend,
+	.resume		= mgslpc_resume,
 };
 
 static struct tty_operations mgslpc_ops = {
@@ -3138,7 +3087,6 @@ static void synclink_cs_cleanup(void)
 	}
 
 	pcmcia_unregister_driver(&mgslpc_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 static int __init synclink_cs_init(void)
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index ef79805218e4..4c2af9020905 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -88,15 +88,12 @@ typedef struct ide_info_t {
 } ide_info_t;
 
 static void ide_release(dev_link_t *);
-static int ide_event(event_t event, int priority,
-		     event_callback_args_t *args);
+static void ide_config(dev_link_t *);
+
+static void ide_detach(struct pcmcia_device *p_dev);
 
-static dev_info_t dev_info = "ide-cs";
 
-static dev_link_t *ide_attach(void);
-static void ide_detach(dev_link_t *);
 
-static dev_link_t *dev_list = NULL;
 
 /*======================================================================
 
@@ -106,18 +103,17 @@ static dev_link_t *dev_list = NULL;
 
 ======================================================================*/
 
-static dev_link_t *ide_attach(void)
+static int ide_attach(struct pcmcia_device *p_dev)
 {
     ide_info_t *info;
     dev_link_t *link;
-    client_reg_t client_reg;
-    int ret;
-    
+
     DEBUG(0, "ide_attach()\n");
 
     /* Create new ide device */
     info = kzalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
+    if (!info)
+	return -ENOMEM;
     link = &info->link; link->priv = info;
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -128,21 +124,14 @@ static dev_link_t *ide_attach(void)
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	ide_detach(link);
-	return NULL;
-    }
-    
-    return link;
+
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    ide_config(link);
+
+    return 0;
 } /* ide_attach */
 
 /*======================================================================
@@ -154,32 +143,16 @@ 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 **linkp;
-    int ret;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "ide_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 (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);
-    
 } /* ide_detach */
 
 static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
@@ -406,6 +379,28 @@ void ide_release(dev_link_t *link)
 
 } /* ide_release */
 
+static int ide_suspend(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int ide_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -415,48 +410,15 @@ void ide_release(dev_link_t *link)
     
 ======================================================================*/
 
-int ide_event(event_t event, int priority,
-	      event_callback_args_t *args)
-{
-    dev_link_t *link = args->client_data;
-
-    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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (DEV_OK(link))
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	break;
-    }
-    return 0;
-} /* ide_event */
-
 static struct pcmcia_device_id ide_ids[] = {
 	PCMCIA_DEVICE_FUNC_ID(4),
+	PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000),	/* Hitachi */
 	PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
 	PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
 	PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),	/* Toshiba */
 	PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
 	PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),	/* Samsung */
+ 	PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000),	/* Hitachi */
 	PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
 	PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200),	/* Lexar */
 	PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
@@ -471,6 +433,8 @@ static struct pcmcia_device_id ide_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("EXP   ", "CD-ROM", 0x0a5c52fd, 0x66536591),
 	PCMCIA_DEVICE_PROD_ID12("EXP   ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
 	PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
+	PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
+	PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
 	PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -494,10 +458,11 @@ static struct pcmcia_driver ide_cs_driver = {
 	.drv		= {
 		.name	= "ide-cs",
 	},
-	.attach		= ide_attach,
-	.event		= ide_event,
-	.detach		= ide_detach,
+	.probe		= ide_attach,
+	.remove		= ide_detach,
 	.id_table       = ide_ids,
+	.suspend	= ide_suspend,
+	.resume		= ide_resume,
 };
 
 static int __init init_ide_cs(void)
@@ -508,7 +473,6 @@ static int __init init_ide_cs(void)
 static void __exit exit_ide_cs(void)
 {
 	pcmcia_unregister_driver(&ide_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 late_initcall(init_ide_cs);
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index 27391c32f3eb..2a2b03ff096b 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -53,8 +53,6 @@ MODULE_LICENSE("GPL");
 
 static void avmcs_config(dev_link_t *link);
 static void avmcs_release(dev_link_t *link);
-static int avmcs_event(event_t event, int priority,
-			  event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -62,16 +60,7 @@ static int avmcs_event(event_t event, int priority,
    needed to manage one actual PCMCIA card.
 */
 
-static dev_link_t *avmcs_attach(void);
-static void avmcs_detach(dev_link_t *);
-
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "avm_cs";
+static void avmcs_detach(struct pcmcia_device *p_dev);
 
 /*
    A linked list of "instances" of the skeleton device.  Each actual
@@ -83,15 +72,7 @@ static dev_info_t dev_info = "avm_cs";
    device numbers are used to derive the corresponding array index.
 */
 
-static dev_link_t *dev_list = NULL;
-
 /*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -118,13 +99,11 @@ typedef struct local_info_t {
     
 ======================================================================*/
 
-static dev_link_t *avmcs_attach(void)
+static int avmcs_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret;
-    
+
     /* Initialize the dev_link_t structure */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
     if (!link)
@@ -155,25 +134,19 @@ static dev_link_t *avmcs_attach(void)
         goto err_kfree;
     memset(local, 0, sizeof(local_info_t));
     link->priv = local;
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	avmcs_detach(link);
-	goto err;
-    }
-    return link;
+
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    avmcs_config(link);
+
+    return 0;
 
  err_kfree:
     kfree(link);
  err:
-    return NULL;
+    return -EINVAL;
 } /* avmcs_attach */
 
 /*======================================================================
@@ -185,33 +158,13 @@ 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 **linkp;
-
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
+    dev_link_t *link = dev_to_instance(p_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) {
-	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;
     kfree(link->priv);
     kfree(link);
 } /* avmcs_detach */
@@ -424,12 +377,30 @@ static void avmcs_release(dev_link_t *link)
     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)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int avmcs_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -444,38 +415,6 @@ static void avmcs_release(dev_link_t *link)
     
 ======================================================================*/
 
-static int avmcs_event(event_t event, int priority,
-			  event_callback_args_t *args)
-{
-    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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (link->state & DEV_CONFIG)
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	break;
-    }
-    return 0;
-} /* avmcs_event */
 
 static struct pcmcia_device_id avmcs_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
@@ -490,10 +429,11 @@ static struct pcmcia_driver avmcs_driver = {
 	.drv	= {
 		.name	= "avm_cs",
 	},
-	.attach	= avmcs_attach,
-	.event	= avmcs_event,
-	.detach	= avmcs_detach,
+	.probe = avmcs_attach,
+	.remove	= avmcs_detach,
 	.id_table = avmcs_ids,
+	.suspend= avmcs_suspend,
+	.resume = avmcs_resume,
 };
 
 static int __init avmcs_init(void)
@@ -504,7 +444,6 @@ static int __init avmcs_init(void)
 static void __exit avmcs_exit(void)
 {
 	pcmcia_unregister_driver(&avmcs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(avmcs_init);
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 5f5a5ae740d2..969da40c4248 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -69,8 +69,6 @@ module_param(isdnprot, int, 0);
 
 static void avma1cs_config(dev_link_t *link);
 static void avma1cs_release(dev_link_t *link);
-static int avma1cs_event(event_t event, int priority,
-			  event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -78,16 +76,8 @@ static int avma1cs_event(event_t event, int priority,
    needed to manage one actual PCMCIA card.
 */
 
-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
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "avma1_cs";
 
 /*
    A linked list of "instances" of the skeleton device.  Each actual
@@ -99,15 +89,7 @@ static dev_info_t dev_info = "avma1_cs";
    device numbers are used to derive the corresponding array index.
 */
 
-static dev_link_t *dev_list = NULL;
-
 /*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -134,26 +116,24 @@ typedef struct local_info_t {
     
 ======================================================================*/
 
-static dev_link_t *avma1cs_attach(void)
+static int avma1cs_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret;
-    
+
     DEBUG(0, "avma1cs_attach()\n");
 
     /* Initialize the dev_link_t structure */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
     if (!link)
-	return NULL;
+	return -ENOMEM;
     memset(link, 0, sizeof(struct dev_link_t));
 
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local) {
 	kfree(link);
-	return NULL;
+	return -ENOMEM;
     }
     memset(local, 0, sizeof(local_info_t));
     link->priv = local;
@@ -178,20 +158,13 @@ static dev_link_t *avma1cs_attach(void)
     link->conf.ConfigIndex = 1;
     link->conf.Present = PRESENT_OPTION;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	avma1cs_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    avma1cs_config(link);
+
+    return 0;
 } /* avma1cs_attach */
 
 /*======================================================================
@@ -203,42 +176,17 @@ 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 **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     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;
     kfree(link->priv);
     kfree(link);
-    
 } /* avma1cs_detach */
 
 /*======================================================================
@@ -440,58 +388,30 @@ static void avma1cs_release(dev_link_t *link)
     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)
+{
+	dev_link_t *link = dev_to_instance(dev);
 
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
-    
-======================================================================*/
+	return 0;
+}
 
-static int avma1cs_event(event_t event, int priority,
-			  event_callback_args_t *args)
+static int avma1cs_resume(struct pcmcia_device *dev)
 {
-    dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 
-    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);
-	    break;
-	case CS_EVENT_PM_SUSPEND:
-	    link->state |= DEV_SUSPEND;
-	    /* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-	    if (link->state & DEV_CONFIG)
-		pcmcia_release_configuration(link->handle);
-	    break;
-	case CS_EVENT_PM_RESUME:
-	    link->state &= ~DEV_SUSPEND;
-	    /* Fall through... */
-	case CS_EVENT_CARD_RESET:
- 	    if (link->state & DEV_CONFIG)
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
 		pcmcia_request_configuration(link->handle, &link->conf);
-	    break;
-    }
-    return 0;
-} /* avma1cs_event */
+
+	return 0;
+}
+
 
 static struct pcmcia_device_id avma1cs_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
@@ -505,10 +425,11 @@ static struct pcmcia_driver avma1cs_driver = {
 	.drv		= {
 		.name	= "avma1_cs",
 	},
-	.attach		= avma1cs_attach,
-	.event		= avma1cs_event,
-	.detach		= avma1cs_detach,
+	.probe		= avma1cs_attach,
+	.remove		= avma1cs_detach,
 	.id_table	= avma1cs_ids,
+	.suspend	= avma1cs_suspend,
+	.resume		= avma1cs_resume,
 };
  
 /*====================================================================*/
@@ -521,7 +442,6 @@ static int __init init_avma1_cs(void)
 static void __exit exit_avma1_cs(void)
 {
 	pcmcia_unregister_driver(&avma1cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_avma1_cs);
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 6fc6868de0b0..062fb8f0739f 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -96,8 +96,6 @@ module_param(protocol, int, 0);
 
 static void elsa_cs_config(dev_link_t *link);
 static void elsa_cs_release(dev_link_t *link);
-static int elsa_cs_event(event_t event, int priority,
-                          event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -105,39 +103,9 @@ static int elsa_cs_event(event_t event, int priority,
    needed to manage one actual PCMCIA card.
 */
 
-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
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "elsa_cs";
-
-/*
-   A linked list of "instances" of the elsa_cs device.  Each actual
-   PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
-
-   You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of dev_link_t pointers, where minor
-   device numbers are used to derive the corresponding array index.
-*/
-
-static dev_link_t *dev_list = NULL;
-
-/*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
-   To simplify the data structure handling, we actually include the
-   dev_link_t structure in the device's private data structure.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -171,18 +139,16 @@ typedef struct local_info_t {
 
 ======================================================================*/
 
-static dev_link_t *elsa_cs_attach(void)
+static int elsa_cs_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret;
 
     DEBUG(0, "elsa_cs_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
-    if (!local) return NULL;
+    if (!local) return -ENOMEM;
     memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
     link = &local->link; link->priv = local;
@@ -207,20 +173,13 @@ static dev_link_t *elsa_cs_attach(void)
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-        cs_error(link->handle, RegisterClient, ret);
-        elsa_cs_detach(link);
-        return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    elsa_cs_config(link);
+
+    return 0;
 } /* elsa_cs_attach */
 
 /*======================================================================
@@ -232,32 +191,18 @@ 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 **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
     local_info_t *info = link->priv;
-    int ret;
 
     DEBUG(0, "elsa_cs_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 (link->state & DEV_CONFIG)
-        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);
+    if (link->state & DEV_CONFIG) {
+	    info->busy = 1;
+	    elsa_cs_release(link);
     }
 
-    /* Unlink device structure and free it */
-    *linkp = link->next;
     kfree(info);
 
 } /* elsa_cs_detach */
@@ -447,60 +392,31 @@ static void elsa_cs_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 } /* elsa_cs_release */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
+static int elsa_suspend(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
 
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
+	link->state |= DEV_SUSPEND;
+        dev->busy = 1;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-======================================================================*/
+	return 0;
+}
 
-static int elsa_cs_event(event_t event, int priority,
-                          event_callback_args_t *args)
+static int elsa_resume(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    local_info_t *dev = link->priv;
-
-    DEBUG(1, "elsa_cs_event(%d)\n", event);
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
 
-    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);
-        break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        /* Mark the device as stopped, to block IO until later */
-        dev->busy = 1;
-        if (link->state & DEV_CONFIG)
-            pcmcia_release_configuration(link->handle);
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG)
-            pcmcia_request_configuration(link->handle, &link->conf);
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
         dev->busy = 0;
-        break;
-    }
-    return 0;
-} /* elsa_cs_event */
+
+	return 0;
+}
 
 static struct pcmcia_device_id elsa_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257),
@@ -514,10 +430,11 @@ static struct pcmcia_driver elsa_cs_driver = {
 	.drv		= {
 		.name	= "elsa_cs",
 	},
-	.attach		= elsa_cs_attach,
-	.event		= elsa_cs_event,
-	.detach		= elsa_cs_detach,
+	.probe		= elsa_cs_attach,
+	.remove		= elsa_cs_detach,
 	.id_table	= elsa_ids,
+	.suspend	= elsa_suspend,
+	.resume		= elsa_resume,
 };
 
 static int __init init_elsa_cs(void)
@@ -528,7 +445,6 @@ static int __init init_elsa_cs(void)
 static void __exit exit_elsa_cs(void)
 {
 	pcmcia_unregister_driver(&elsa_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_elsa_cs);
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index dc334aab433e..6f5213a18a8d 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -97,8 +97,6 @@ module_param(protocol, int, 0);
 
 static void sedlbauer_config(dev_link_t *link);
 static void sedlbauer_release(dev_link_t *link);
-static int sedlbauer_event(event_t event, int priority,
-		       event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -106,8 +104,7 @@ static int sedlbauer_event(event_t event, int priority,
    needed to manage one actual PCMCIA card.
 */
 
-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
@@ -117,35 +114,6 @@ static void sedlbauer_detach(dev_link_t *);
 */
 
 /*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "sedlbauer_cs";
-
-/*
-   A linked list of "instances" of the sedlbauer device.  Each actual
-   PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
-
-   You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of dev_link_t pointers, where minor
-   device numbers are used to derive the corresponding array index.
-*/
-
-static dev_link_t *dev_list = NULL;
-
-/*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
-   To simplify the data structure handling, we actually include the
-   dev_link_t structure in the device's private data structure.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -180,18 +148,16 @@ typedef struct local_info_t {
     
 ======================================================================*/
 
-static dev_link_t *sedlbauer_attach(void)
+static int sedlbauer_attach(struct pcmcia_device *p_dev)
 {
     local_info_t *local;
     dev_link_t *link;
-    client_reg_t client_reg;
-    int ret;
     
     DEBUG(0, "sedlbauer_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
-    if (!local) return NULL;
+    if (!local) return -ENOMEM;
     memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
     link = &local->link; link->priv = local;
@@ -221,20 +187,13 @@ static dev_link_t *sedlbauer_attach(void)
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	sedlbauer_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    sedlbauer_config(link);
 
-    return link;
+    return 0;
 } /* sedlbauer_attach */
 
 /*======================================================================
@@ -246,39 +205,17 @@ 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 **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "sedlbauer_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 "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 */
     kfree(link->priv);
 } /* sedlbauer_detach */
@@ -547,68 +484,34 @@ static void sedlbauer_release(dev_link_t *link)
     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 */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.
-
-    When a CARD_REMOVAL event is received, we immediately set a
-    private flag to block future accesses to this device.  All the
-    functions that actually access the device should check this flag
-    to make sure the card is still present.
-    
-======================================================================*/
-
-static int sedlbauer_event(event_t event, int priority,
-		       event_callback_args_t *args)
+static int sedlbauer_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    local_info_t *dev = link->priv;
-    
-    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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
+
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	/* Mark the device as stopped, to block IO until later */
 	dev->stop = 1;
 	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int sedlbauer_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG)
-	    pcmcia_request_configuration(link->handle, &link->conf);
+		pcmcia_request_configuration(link->handle, &link->conf);
 	dev->stop = 0;
-	/*
-	  In a normal driver, additional code may go here to restore
-	  the device state and restart IO. 
-	*/
-	break;
-    }
-    return 0;
-} /* sedlbauer_event */
+
+	return 0;
+}
+
 
 static struct pcmcia_device_id sedlbauer_ids[] = {
 	PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a),
@@ -627,10 +530,11 @@ static struct pcmcia_driver sedlbauer_driver = {
 	.drv		= {
 		.name	= "sedlbauer_cs",
 	},
-	.attach		= sedlbauer_attach,
-	.event		= sedlbauer_event,
-	.detach		= sedlbauer_detach,
+	.probe		= sedlbauer_attach,
+	.remove		= sedlbauer_detach,
 	.id_table	= sedlbauer_ids,
+	.suspend	= sedlbauer_suspend,
+	.resume		= sedlbauer_resume,
 };
 
 static int __init init_sedlbauer_cs(void)
@@ -641,7 +545,6 @@ static int __init init_sedlbauer_cs(void)
 static void __exit exit_sedlbauer_cs(void)
 {
 	pcmcia_unregister_driver(&sedlbauer_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_sedlbauer_cs);
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 0ddef1bf778b..4e5c14c7240e 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -77,8 +77,6 @@ module_param(protocol, int, 0);
 
 static void teles_cs_config(dev_link_t *link);
 static void teles_cs_release(dev_link_t *link);
-static int teles_cs_event(event_t event, int priority,
-                          event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -86,16 +84,7 @@ static int teles_cs_event(event_t event, int priority,
    needed to manage one actual PCMCIA card.
 */
 
-static dev_link_t *teles_attach(void);
-static void teles_detach(dev_link_t *);
-
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "teles_cs";
+static void teles_detach(struct pcmcia_device *p_dev);
 
 /*
    A linked list of "instances" of the teles_cs device.  Each actual
@@ -107,18 +96,7 @@ static dev_info_t dev_info = "teles_cs";
    device numbers are used to derive the corresponding array index.
 */
 
-static dev_link_t *dev_list = NULL;
-
 /*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
-   To simplify the data structure handling, we actually include the
-   dev_link_t structure in the device's private data structure.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -152,18 +130,16 @@ typedef struct local_info_t {
 
 ======================================================================*/
 
-static dev_link_t *teles_attach(void)
+static int teles_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret;
 
     DEBUG(0, "teles_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
-    if (!local) return NULL;
+    if (!local) return -ENOMEM;
     memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
     link = &local->link; link->priv = local;
@@ -188,20 +164,13 @@ static dev_link_t *teles_attach(void)
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-        cs_error(link->handle, RegisterClient, ret);
-        teles_detach(link);
-        return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    teles_cs_config(link);
 
-    return link;
+    return 0;
 } /* teles_attach */
 
 /*======================================================================
@@ -213,32 +182,18 @@ 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 **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
     local_info_t *info = link->priv;
-    int ret;
 
     DEBUG(0, "teles_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 (link->state & DEV_CONFIG)
-        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);
+    if (link->state & DEV_CONFIG) {
+	    info->busy = 1;
+	    teles_cs_release(link);
     }
 
-    /* Unlink device structure and free it */
-    *linkp = link->next;
     kfree(info);
 
 } /* teles_detach */
@@ -428,60 +383,32 @@ static void teles_cs_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 } /* teles_cs_release */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
+static int teles_suspend(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
 
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
+	link->state |= DEV_SUSPEND;
+        dev->busy = 1;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-======================================================================*/
+	return 0;
+}
 
-static int teles_cs_event(event_t event, int priority,
-                          event_callback_args_t *args)
+static int teles_resume(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    local_info_t *dev = link->priv;
-
-    DEBUG(1, "teles_cs_event(%d)\n", event);
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
 
-    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);
-        break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        /* Mark the device as stopped, to block IO until later */
-        dev->busy = 1;
-        if (link->state & DEV_CONFIG)
-            pcmcia_release_configuration(link->handle);
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG)
-            pcmcia_request_configuration(link->handle, &link->conf);
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
         dev->busy = 0;
-        break;
-    }
-    return 0;
-} /* teles_cs_event */
+
+	return 0;
+}
+
 
 static struct pcmcia_device_id teles_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119),
@@ -494,10 +421,11 @@ static struct pcmcia_driver teles_cs_driver = {
 	.drv		= {
 		.name	= "teles_cs",
 	},
-	.attach		= teles_attach,
-	.event		= teles_cs_event,
-	.detach		= teles_detach,
+	.probe		= teles_attach,
+	.remove		= teles_detach,
 	.id_table       = teles_ids,
+	.suspend	= teles_suspend,
+	.resume		= teles_resume,
 };
 
 static int __init init_teles_cs(void)
@@ -508,7 +436,6 @@ static int __init init_teles_cs(void)
 static void __exit exit_teles_cs(void)
 {
 	pcmcia_unregister_driver(&teles_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_teles_cs);
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index af24216a0626..f0f8916da7ad 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -66,9 +66,6 @@ struct pcmciamtd_dev {
 };
 
 
-static dev_info_t dev_info = "pcmciamtd";
-static dev_link_t *dev_list;
-
 /* Module parameters */
 
 /* 2 = do 16-bit transfers, 1 = do 8-bit transfers */
@@ -691,55 +688,21 @@ static void pcmciamtd_config(dev_link_t *link)
 }
 
 
-/* The card status event handler.  Mostly, this schedules other
- * stuff to run after an event is received.  A CARD_REMOVAL event
- * also sets some flags to discourage the driver from trying
- * to talk to the card any more.
- */
+static int pcmciamtd_suspend(struct pcmcia_device *dev)
+{
+	DEBUG(2, "EVENT_PM_RESUME");
+
+	/* get_lock(link); */
+
+	return 0;
+}
 
-static int pcmciamtd_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int pcmciamtd_resume(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-
-	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;
-		pcmciamtd_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		DEBUG(2, "EVENT_PM_SUSPEND");
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		DEBUG(2, "EVENT_RESET_PHYSICAL");
-		/* get_lock(link); */
-		break;
-	case CS_EVENT_PM_RESUME:
-		DEBUG(2, "EVENT_PM_RESUME");
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		DEBUG(2, "EVENT_CARD_RESET");
-		/* free_lock(link); */
-		break;
-	default:
-		DEBUG(2, "Unknown event %d", event);
-	}
+	DEBUG(2, "EVENT_PM_SUSPEND");
+
+	/* free_lock(link); */
+
 	return 0;
 }
 
@@ -750,23 +713,21 @@ static int pcmciamtd_event(event_t event, int priority,
  * 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;
 }
 
 
@@ -775,16 +736,14 @@ static void pcmciamtd_detach(dev_link_t *link)
  * with Card Services.
  */
 
-static dev_link_t *pcmciamtd_attach(void)
+static int pcmciamtd_attach(struct pcmcia_device *p_dev)
 {
 	struct pcmciamtd_dev *dev;
 	dev_link_t *link;
-	client_reg_t client_reg;
-	int ret;
 
 	/* Create new memory card device */
 	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev) return NULL;
+	if (!dev) return -ENOMEM;
 	DEBUG(1, "dev=0x%p", dev);
 
 	memset(dev, 0, sizeof(*dev));
@@ -794,22 +753,14 @@ static dev_link_t *pcmciamtd_attach(void)
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY;
 
-	link->next = dev_list;
-	dev_list = link;
-
-	/* Register with Card Services */
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	DEBUG(2, "Calling RegisterClient");
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		pcmciamtd_detach(link);
-		return NULL;
-	}
-	DEBUG(2, "link = %p", link);
-	return link;
+	link->next = NULL;
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	pcmciamtd_config(link);
+
+	return 0;
 }
 
 static struct pcmcia_device_id pcmciamtd_ids[] = {
@@ -843,11 +794,12 @@ static struct pcmcia_driver pcmciamtd_driver = {
 	.drv		= {
 		.name	= "pcmciamtd"
 	},
-	.attach		= pcmciamtd_attach,
-	.event		= pcmciamtd_event,
-	.detach		= pcmciamtd_detach,
+	.probe		= pcmciamtd_attach,
+	.remove		= pcmciamtd_detach,
 	.owner		= THIS_MODULE,
 	.id_table	= pcmciamtd_ids,
+	.suspend	= pcmciamtd_suspend,
+	.resume		= pcmciamtd_resume,
 };
 
 
@@ -875,7 +827,6 @@ static void __exit exit_pcmciamtd(void)
 {
 	DEBUG(1, DRIVER_DESC " unloading");
 	pcmcia_unregister_driver(&pcmciamtd_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_pcmciamtd);
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 71fd41122c91..48774efeec71 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -227,8 +227,6 @@ static char mii_preamble_required = 0;
 
 static void tc574_config(dev_link_t *link);
 static void tc574_release(dev_link_t *link);
-static int tc574_event(event_t event, int priority,
-					   event_callback_args_t *args);
 
 static void mdio_sync(kio_addr_t ioaddr, int bits);
 static int mdio_read(kio_addr_t ioaddr, int phy_id, int location);
@@ -250,12 +248,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static struct ethtool_ops netdev_ethtool_ops;
 static void set_rx_mode(struct net_device *dev);
 
-static dev_info_t dev_info = "3c574_cs";
-
-static dev_link_t *tc574_attach(void);
-static void tc574_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void tc574_detach(struct pcmcia_device *p_dev);
 
 /*
 	tc574_attach() creates an "instance" of the driver, allocating
@@ -263,20 +256,18 @@ static dev_link_t *dev_list;
 	with Card Services.
 */
 
-static dev_link_t *tc574_attach(void)
+static int tc574_attach(struct pcmcia_device *p_dev)
 {
 	struct el3_private *lp;
-	client_reg_t client_reg;
 	dev_link_t *link;
 	struct net_device *dev;
-	int ret;
 
 	DEBUG(0, "3c574_attach()\n");
 
 	/* Create the PC card device object. */
 	dev = alloc_etherdev(sizeof(struct el3_private));
 	if (!dev)
-		return NULL;
+		return -ENOMEM;
 	lp = netdev_priv(dev);
 	link = &lp->link;
 	link->priv = dev;
@@ -307,20 +298,13 @@ static dev_link_t *tc574_attach(void)
 	dev->watchdog_timeo = TX_TIMEOUT;
 #endif
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		tc574_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	tc574_config(link);
+
+	return 0;
 } /* tc574_attach */
 
 /*
@@ -332,30 +316,19 @@ 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;
 
 	DEBUG(0, "3c574_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 (link->dev)
 		unregister_netdev(dev);
 
 	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);
 } /* tc574_detach */
 
@@ -547,56 +520,37 @@ static void tc574_release(dev_link_t *link)
 	link->state &= ~DEV_CONFIG;
 }
 
-/*
-	The card status event handler.  Mostly, this schedules other
-	stuff to run after an event is received.  A CARD_REMOVAL event
-	also sets some flags to discourage the net drivers from trying
-	to talk to the card any more.
-*/
-
-static int tc574_event(event_t event, int priority,
-					   event_callback_args_t *args)
+static int tc574_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	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)
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		if (link->open)
 			netif_device_detach(dev);
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		tc574_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG) {
-			if (link->open)
-				netif_device_detach(dev);
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-			if (link->open) {
-				tc574_reset(dev);
-				netif_device_attach(dev);
-			}
+		pcmcia_release_configuration(link->handle);
+	}
+
+	return 0;
+}
+
+static int tc574_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			tc574_reset(dev);
+			netif_device_attach(dev);
 		}
-		break;
 	}
+
 	return 0;
-} /* tc574_event */
+}
 
 static void dump_status(struct net_device *dev)
 {
@@ -1292,10 +1246,11 @@ static struct pcmcia_driver tc574_driver = {
 	.drv		= {
 		.name	= "3c574_cs",
 	},
-	.attach		= tc574_attach,
-	.event		= tc574_event,
-	.detach		= tc574_detach,
+	.probe		= tc574_attach,
+	.remove		= tc574_detach,
 	.id_table       = tc574_ids,
+	.suspend	= tc574_suspend,
+	.resume		= tc574_resume,
 };
 
 static int __init init_tc574(void)
@@ -1306,7 +1261,6 @@ static int __init init_tc574(void)
 static void __exit exit_tc574(void)
 {
 	pcmcia_unregister_driver(&tc574_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_tc574);
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index d83fdd8c1943..1c3c9c666f74 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -143,8 +143,6 @@ DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
 
 static void tc589_config(dev_link_t *link);
 static void tc589_release(dev_link_t *link);
-static int tc589_event(event_t event, int priority,
-		       event_callback_args_t *args);
 
 static u16 read_eeprom(kio_addr_t ioaddr, int index);
 static void tc589_reset(struct net_device *dev);
@@ -161,12 +159,7 @@ static void el3_tx_timeout(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
 static struct ethtool_ops netdev_ethtool_ops;
 
-static dev_info_t dev_info = "3c589_cs";
-
-static dev_link_t *tc589_attach(void);
-static void tc589_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void tc589_detach(struct pcmcia_device *p_dev);
 
 /*======================================================================
 
@@ -176,20 +169,18 @@ static dev_link_t *dev_list;
 
 ======================================================================*/
 
-static dev_link_t *tc589_attach(void)
+static int tc589_attach(struct pcmcia_device *p_dev)
 {
     struct el3_private *lp;
-    client_reg_t client_reg;
     dev_link_t *link;
     struct net_device *dev;
-    int ret;
 
     DEBUG(0, "3c589_attach()\n");
-    
+
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(struct el3_private));
     if (!dev)
-	 return NULL;
+	 return -ENOMEM;
     lp = netdev_priv(dev);
     link = &lp->link;
     link->priv = dev;
@@ -206,7 +197,7 @@ static dev_link_t *tc589_attach(void)
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
     link->conf.Present = PRESENT_OPTION;
-    
+
     /* The EL3-specific entries in the device structure. */
     SET_MODULE_OWNER(dev);
     dev->hard_start_xmit = &el3_start_xmit;
@@ -221,20 +212,13 @@ static dev_link_t *tc589_attach(void)
 #endif
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	tc589_detach(link);
-	return NULL;
-    }
-    
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    tc589_config(link);
+
+    return 0;
 } /* tc589_attach */
 
 /*======================================================================
@@ -246,30 +230,19 @@ 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;
-    
+
     DEBUG(0, "3c589_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 (link->dev)
 	unregister_netdev(dev);
 
     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);
 } /* tc589_detach */
 
@@ -421,58 +394,37 @@ static void tc589_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 }
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-    
-======================================================================*/
-
-static int tc589_event(event_t event, int priority,
-		       event_callback_args_t *args)
+static int tc589_suspend(struct pcmcia_device *p_dev)
 {
-    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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+	return 0;
+}
+
+static int tc589_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		tc589_reset(dev);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			tc589_reset(dev);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* tc589_event */
+
+	return 0;
+}
 
 /*====================================================================*/
 
@@ -1067,10 +1019,11 @@ static struct pcmcia_driver tc589_driver = {
 	.drv		= {
 		.name	= "3c589_cs",
 	},
-	.attach		= tc589_attach,
-	.event		= tc589_event,
-	.detach		= tc589_detach,
+	.probe		= tc589_attach,
+	.remove		= tc589_detach,
         .id_table       = tc589_ids,
+	.suspend	= tc589_suspend,
+	.resume		= tc589_resume,
 };
 
 static int __init init_tc589(void)
@@ -1081,7 +1034,6 @@ static int __init init_tc589(void)
 static void __exit exit_tc589(void)
 {
 	pcmcia_unregister_driver(&tc589_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_tc589);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 8bb4e85689ea..01ddfc8cce3f 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -87,8 +87,6 @@ static char *version =
 
 static void axnet_config(dev_link_t *link);
 static void axnet_release(dev_link_t *link);
-static int axnet_event(event_t event, int priority,
-		       event_callback_args_t *args);
 static int axnet_open(struct net_device *dev);
 static int axnet_close(struct net_device *dev);
 static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -107,11 +105,7 @@ static void block_input(struct net_device *dev, int count,
 static void block_output(struct net_device *dev, int count,
 			 const u_char *buf, const int start_page);
 
-static dev_link_t *axnet_attach(void);
-static void axnet_detach(dev_link_t *);
-
-static dev_info_t dev_info = "axnet_cs";
-static dev_link_t *dev_list;
+static void axnet_detach(struct pcmcia_device *p_dev);
 
 static void axdev_setup(struct net_device *dev);
 static void AX88190_init(struct net_device *dev, int startp);
@@ -147,13 +141,11 @@ static inline axnet_dev_t *PRIV(struct net_device *dev)
 
 ======================================================================*/
 
-static dev_link_t *axnet_attach(void)
+static int axnet_attach(struct pcmcia_device *p_dev)
 {
     axnet_dev_t *info;
     dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
 
     DEBUG(0, "axnet_attach()\n");
 
@@ -161,7 +153,7 @@ static dev_link_t *axnet_attach(void)
 			"eth%d", axdev_setup);
 
     if (!dev)
-	return NULL;
+	return -ENOMEM;
 
     info = PRIV(dev);
     link = &info->link;
@@ -176,20 +168,13 @@ static dev_link_t *axnet_attach(void)
     dev->do_ioctl = &axnet_ioctl;
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	axnet_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    axnet_config(link);
+
+    return 0;
 } /* axnet_attach */
 
 /*======================================================================
@@ -201,30 +186,19 @@ 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;
 
     DEBUG(0, "axnet_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 (link->dev)
 	unregister_netdev(dev);
 
     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);
 } /* axnet_detach */
 
@@ -490,59 +464,39 @@ static void axnet_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 }
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-======================================================================*/
-
-static int axnet_event(event_t event, int priority,
-		       event_callback_args_t *args)
+static int axnet_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+	return 0;
+}
+
+static int axnet_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		axnet_reset_8390(dev);
-		AX88190_init(dev, 1);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			axnet_reset_8390(dev);
+			AX88190_init(dev, 1);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* axnet_event */
+
+	return 0;
+}
+
 
 /*======================================================================
 
@@ -616,7 +570,7 @@ static int axnet_open(struct net_device *dev)
 
     link->open++;
 
-    request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev);
+    request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, "axnet_cs", dev);
 
     info->link_status = 0x00;
     init_timer(&info->watchdog);
@@ -877,10 +831,11 @@ static struct pcmcia_driver axnet_cs_driver = {
 	.drv		= {
 		.name	= "axnet_cs",
 	},
-	.attach		= axnet_attach,
-	.event		= axnet_event,
-	.detach		= axnet_detach,
+	.probe		= axnet_attach,
+	.remove		= axnet_detach,
 	.id_table       = axnet_ids,
+	.suspend	= axnet_suspend,
+	.resume		= axnet_resume,
 };
 
 static int __init init_axnet_cs(void)
@@ -891,7 +846,6 @@ static int __init init_axnet_cs(void)
 static void __exit exit_axnet_cs(void)
 {
 	pcmcia_unregister_driver(&axnet_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_axnet_cs);
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index b9355d9498a3..2827a48ea37c 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -120,15 +120,8 @@ MODULE_LICENSE("GPL");
 
 static void com20020_config(dev_link_t *link);
 static void com20020_release(dev_link_t *link);
-static int com20020_event(event_t event, int priority,
-                       event_callback_args_t *args);
 
-static dev_info_t dev_info = "com20020_cs";
-
-static dev_link_t *com20020_attach(void);
-static void com20020_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void com20020_detach(struct pcmcia_device *p_dev);
 
 /*====================================================================*/
 
@@ -145,21 +138,19 @@ typedef struct com20020_dev_t {
 
 ======================================================================*/
 
-static dev_link_t *com20020_attach(void)
+static int com20020_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     com20020_dev_t *info;
     struct net_device *dev;
-    int ret;
     struct arcnet_local *lp;
-    
+
     DEBUG(0, "com20020_attach()\n");
 
     /* Create new network device */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
     if (!link)
-	return NULL;
+	return -ENOMEM;
 
     info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
     if (!info)
@@ -191,30 +182,19 @@ static dev_link_t *com20020_attach(void)
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-
     link->irq.Instance = info->dev = dev;
     link->priv = info;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-        cs_error(link->handle, RegisterClient, ret);
-        com20020_detach(link);
-        return NULL;
-    }
+    link->state |= DEV_PRESENT;
+    com20020_config(link);
 
-    return link;
+    return 0;
 
 fail_alloc_dev:
     kfree(info);
 fail_alloc_info:
     kfree(link);
-    return NULL;
+    return -ENOMEM;
 } /* com20020_attach */
 
 /*======================================================================
@@ -226,29 +206,21 @@ 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; 
-    
+    struct net_device *dev = info->dev;
+
     DEBUG(1,"detach...\n");
 
     DEBUG(0, "com20020_detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-        if (*linkp == link) break;
-    if (*linkp == NULL)
-        return;
-
-    dev = info->dev;
-
     if (link->dev) {
 	DEBUG(1,"unregister...\n");
 
 	unregister_netdev(dev);
-	    
+
 	/*
 	 * this is necessary because we register our IRQ separately
 	 * from card services.
@@ -260,12 +232,8 @@ static void com20020_detach(dev_link_t *link)
     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;
     if (link->priv)
     {
 	dev = info->dev;
@@ -421,61 +389,41 @@ static void com20020_release(dev_link_t *link)
     link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
 }
 
-/*======================================================================
+static int com20020_suspend(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	com20020_dev_t *info = link->priv;
+	struct net_device *dev = info->dev;
 
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
+	link->state |= DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+		if (link->open) {
+			netif_device_detach(dev);
+		}
+		pcmcia_release_configuration(link->handle);
+        }
 
-======================================================================*/
+	return 0;
+}
 
-static int com20020_event(event_t event, int priority,
-			  event_callback_args_t *args)
+static int com20020_resume(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    com20020_dev_t *info = link->priv;
-    struct net_device *dev = info->dev;
+	dev_link_t *link = dev_to_instance(p_dev);
+	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); 
-	break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        if (link->state & DEV_CONFIG) {
-            if (link->open) {
-                netif_device_detach(dev);
-            }
-            pcmcia_release_configuration(link->handle);
-        }
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
+	link->state &= ~DEV_SUSPEND;
         if (link->state & DEV_CONFIG) {
-            pcmcia_request_configuration(link->handle, &link->conf);
-            if (link->open) {
-		int ioaddr = dev->base_addr;
-		struct arcnet_local *lp = dev->priv;
-		ARCRESET;
-            }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			int ioaddr = dev->base_addr;
+			struct arcnet_local *lp = dev->priv;
+			ARCRESET;
+		}
         }
-        break;
-    }
-    return 0;
-} /* com20020_event */
+
+	return 0;
+}
 
 static struct pcmcia_device_id com20020_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
@@ -488,10 +436,11 @@ static struct pcmcia_driver com20020_cs_driver = {
 	.drv		= {
 		.name	= "com20020_cs",
 	},
-	.attach		= com20020_attach,
-	.event		= com20020_event,
-	.detach		= com20020_detach,
+	.probe		= com20020_attach,
+	.remove		= com20020_detach,
 	.id_table	= com20020_ids,
+	.suspend	= com20020_suspend,
+	.resume		= com20020_resume,
 };
 
 static int __init init_com20020_cs(void)
@@ -502,7 +451,6 @@ static int __init init_com20020_cs(void)
 static void __exit exit_com20020_cs(void)
 {
 	pcmcia_unregister_driver(&com20020_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_com20020_cs);
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 356f50909222..28fe2fb4d6c0 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -88,10 +88,7 @@ static void fmvj18x_config(dev_link_t *link);
 static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);
 static int fmvj18x_setup_mfc(dev_link_t *link);
 static void fmvj18x_release(dev_link_t *link);
-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
@@ -108,9 +105,6 @@ static void set_rx_mode(struct net_device *dev);
 static void fjn_tx_timeout(struct net_device *dev);
 static struct ethtool_ops netdev_ethtool_ops;
 
-static dev_info_t dev_info = "fmvj18x_cs";
-static dev_link_t *dev_list;
-
 /*
     card type
  */
@@ -234,20 +228,18 @@ typedef struct local_info_t {
 #define BANK_1U              0x24 /* bank 1 (CONFIG_1) */
 #define BANK_2U              0x28 /* bank 2 (CONFIG_1) */
 
-static dev_link_t *fmvj18x_attach(void)
+static int fmvj18x_attach(struct pcmcia_device *p_dev)
 {
     local_info_t *lp;
     dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
-    
+
     DEBUG(0, "fmvj18x_attach()\n");
 
     /* Make up a FMVJ18x specific data structure */
     dev = alloc_etherdev(sizeof(local_info_t));
     if (!dev)
-	return NULL;
+	return -ENOMEM;
     lp = netdev_priv(dev);
     link = &lp->link;
     link->priv = dev;
@@ -262,7 +254,7 @@ static dev_link_t *fmvj18x_attach(void)
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &fjn_interrupt;
     link->irq.Instance = dev;
-    
+
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
@@ -281,37 +273,24 @@ static dev_link_t *fmvj18x_attach(void)
     dev->watchdog_timeo = TX_TIMEOUT;
 #endif
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	fmvj18x_detach(link);
-	return NULL;
-    }
 
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    fmvj18x_config(link);
+
+    return 0;
 } /* fmvj18x_attach */
 
 /*====================================================================*/
 
-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;
-    
+
     DEBUG(0, "fmvj18x_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 (link->dev)
 	unregister_netdev(dev);
@@ -319,12 +298,6 @@ static void fmvj18x_detach(dev_link_t *link)
     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);
 } /* fmvj18x_detach */
 
@@ -713,51 +686,40 @@ static void fmvj18x_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 }
 
-/*====================================================================*/
-
-static int fmvj18x_event(event_t event, int priority,
-			  event_callback_args_t *args)
+static int fmvj18x_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+
+	return 0;
+}
+
+static int fmvj18x_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		fjn_reset(dev);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			fjn_reset(dev);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* fmvj18x_event */
+
+	return 0;
+}
+
+/*====================================================================*/
 
 static struct pcmcia_device_id fmvj18x_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004),
@@ -789,10 +751,11 @@ static struct pcmcia_driver fmvj18x_cs_driver = {
 	.drv		= {
 		.name	= "fmvj18x_cs",
 	},
-	.attach		= fmvj18x_attach,
-	.event		= fmvj18x_event,
-	.detach		= fmvj18x_detach,
+	.probe		= fmvj18x_attach,
+	.remove		= fmvj18x_detach,
 	.id_table       = fmvj18x_ids,
+	.suspend	= fmvj18x_suspend,
+	.resume		= fmvj18x_resume,
 };
 
 static int __init init_fmvj18x_cs(void)
@@ -803,7 +766,6 @@ static int __init init_fmvj18x_cs(void)
 static void __exit exit_fmvj18x_cs(void)
 {
 	pcmcia_unregister_driver(&fmvj18x_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_fmvj18x_cs);
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index b6c140eb9799..b9c7e39576f5 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -108,15 +108,7 @@ MODULE_LICENSE("GPL");
 static void ibmtr_config(dev_link_t *link);
 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
 static void ibmtr_release(dev_link_t *link);
-static int ibmtr_event(event_t event, int priority,
-                       event_callback_args_t *args);
-
-static dev_info_t dev_info = "ibmtr_cs";
-
-static dev_link_t *ibmtr_attach(void);
-static void ibmtr_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void ibmtr_detach(struct pcmcia_device *p_dev);
 
 /*====================================================================*/
 
@@ -146,25 +138,23 @@ static struct ethtool_ops netdev_ethtool_ops = {
 
 ======================================================================*/
 
-static dev_link_t *ibmtr_attach(void)
+static int ibmtr_attach(struct pcmcia_device *p_dev)
 {
     ibmtr_dev_t *info;
     dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
     
     DEBUG(0, "ibmtr_attach()\n");
 
     /* Create new token-ring device */
     info = kmalloc(sizeof(*info), GFP_KERNEL); 
-    if (!info) return NULL;
+    if (!info) return -ENOMEM;
     memset(info,0,sizeof(*info));
     dev = alloc_trdev(sizeof(struct tok_info));
-    if (!dev) { 
-	kfree(info); 
-	return NULL;
-    } 
+    if (!dev) {
+	kfree(info);
+	return -ENOMEM;
+    }
 
     link = &info->link;
     link->priv = info;
@@ -185,25 +175,13 @@ static dev_link_t *ibmtr_attach(void)
     
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-        cs_error(link->handle, RegisterClient, ret);
-	goto out_detach;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-out:
-    return link;
+    link->state |= DEV_PRESENT;
+    ibmtr_config(link);
 
-out_detach:
-    ibmtr_detach(link);
-    link = NULL;
-    goto out;
+    return 0;
 } /* ibmtr_attach */
 
 /*======================================================================
@@ -215,22 +193,14 @@ 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;
+    struct net_device *dev = info->dev;
 
     DEBUG(0, "ibmtr_detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-        if (*linkp == link) break;
-    if (*linkp == NULL)
-        return;
-
-    dev = info->dev;
-
     if (link->dev)
 	unregister_netdev(dev);
 
@@ -241,13 +211,8 @@ static void ibmtr_detach(dev_link_t *link)
     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);
-    kfree(info); 
+    kfree(info);
 } /* ibmtr_detach */
 
 /*======================================================================
@@ -401,63 +366,40 @@ static void ibmtr_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 }
 
-/*======================================================================
+static int ibmtr_suspend(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	ibmtr_dev_t *info = link->priv;
+	struct net_device *dev = info->dev;
 
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
+	link->state |= DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
+        }
 
-======================================================================*/
+	return 0;
+}
 
-static int ibmtr_event(event_t event, int priority,
-                       event_callback_args_t *args)
+static int ibmtr_resume(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    ibmtr_dev_t *info = link->priv;
-    struct net_device *dev = info->dev;
+	dev_link_t *link = dev_to_instance(p_dev);
+	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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
+	link->state &= ~DEV_SUSPEND;
         if (link->state & DEV_CONFIG) {
-            if (link->open)
-		netif_device_detach(dev);
-            pcmcia_release_configuration(link->handle);
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			ibmtr_probe(dev);	/* really? */
+			netif_device_attach(dev);
+		}
         }
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG) {
-            pcmcia_request_configuration(link->handle, &link->conf);
-            if (link->open) {
-		ibmtr_probe(dev);	/* really? */
-		netif_device_attach(dev);
-            }
-        }
-        break;
-    }
-    return 0;
-} /* ibmtr_event */
+
+	return 0;
+}
+
 
 /*====================================================================*/
 
@@ -514,10 +456,11 @@ static struct pcmcia_driver ibmtr_cs_driver = {
 	.drv		= {
 		.name	= "ibmtr_cs",
 	},
-	.attach		= ibmtr_attach,
-	.event		= ibmtr_event,
-	.detach		= ibmtr_detach,
+	.probe		= ibmtr_attach,
+	.remove		= ibmtr_detach,
 	.id_table       = ibmtr_ids,
+	.suspend	= ibmtr_suspend,
+	.resume		= ibmtr_resume,
 };
 
 static int __init init_ibmtr_cs(void)
@@ -528,7 +471,6 @@ static int __init init_ibmtr_cs(void)
 static void __exit exit_ibmtr_cs(void)
 {
 	pcmcia_unregister_driver(&ibmtr_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_ibmtr_cs);
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 980d7e5d66cb..4a232254a497 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -388,9 +388,6 @@ static char *version =
 DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
 #endif
 
-static dev_info_t dev_info="nmclan_cs";
-static dev_link_t *dev_list;
-
 static char *if_names[]={
     "Auto", "10baseT", "BNC",
 };
@@ -422,8 +419,6 @@ Function Prototypes
 
 static void nmclan_config(dev_link_t *link);
 static void nmclan_release(dev_link_t *link);
-static int nmclan_event(event_t event, int priority,
-			event_callback_args_t *args);
 
 static void nmclan_reset(struct net_device *dev);
 static int mace_config(struct net_device *dev, struct ifmap *map);
@@ -439,8 +434,7 @@ static void set_multicast_list(struct net_device *dev);
 static struct ethtool_ops netdev_ethtool_ops;
 
 
-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
@@ -449,13 +443,11 @@ nmclan_attach
 	Services.
 ---------------------------------------------------------------------------- */
 
-static dev_link_t *nmclan_attach(void)
+static int nmclan_attach(struct pcmcia_device *p_dev)
 {
     mace_private *lp;
     dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
 
     DEBUG(0, "nmclan_attach()\n");
     DEBUG(1, "%s\n", rcsid);
@@ -463,7 +455,7 @@ static dev_link_t *nmclan_attach(void)
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(mace_private));
     if (!dev)
-	return NULL;
+	    return -ENOMEM;
     lp = netdev_priv(dev);
     link = &lp->link;
     link->priv = dev;
@@ -497,20 +489,13 @@ static dev_link_t *nmclan_attach(void)
     dev->watchdog_timeo = TX_TIMEOUT;
 #endif
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	nmclan_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    nmclan_config(link);
 
-    return link;
+    return 0;
 } /* nmclan_attach */
 
 /* ----------------------------------------------------------------------------
@@ -521,30 +506,19 @@ 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;
 
     DEBUG(0, "nmclan_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 (link->dev)
 	unregister_netdev(dev);
 
     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);
 } /* nmclan_detach */
 
@@ -801,59 +775,39 @@ static void nmclan_release(dev_link_t *link)
   link->state &= ~DEV_CONFIG;
 }
 
-/* ----------------------------------------------------------------------------
-nmclan_event
-	The card status event handler.  Mostly, this schedules other
-	stuff to run after an event is received.  A CARD_REMOVAL event
-	also sets some flags to discourage the net drivers from trying
-	to talk to the card any more.
----------------------------------------------------------------------------- */
-static int nmclan_event(event_t event, int priority,
-		       event_callback_args_t *args)
+static int nmclan_suspend(struct pcmcia_device *p_dev)
 {
-  dev_link_t *link = args->client_data;
-  struct net_device *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
+	}
 
-  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);
-      break;
-    case CS_EVENT_PM_SUSPEND:
-      link->state |= DEV_SUSPEND;
-      /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-      if (link->state & DEV_CONFIG) {
-	if (link->open)
-	  netif_device_detach(dev);
-	pcmcia_release_configuration(link->handle);
-      }
-      break;
-    case CS_EVENT_PM_RESUME:
-      link->state &= ~DEV_SUSPEND;
-      /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-      if (link->state & DEV_CONFIG) {
-	pcmcia_request_configuration(link->handle, &link->conf);
-	if (link->open) {
-	  nmclan_reset(dev);
-	  netif_device_attach(dev);
+	return 0;
+}
+
+static int nmclan_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			nmclan_reset(dev);
+			netif_device_attach(dev);
+		}
 	}
-      }
-      break;
-    case CS_EVENT_RESET_REQUEST:
-      return 1;
-      break;
-  }
-  return 0;
-} /* nmclan_event */
+
+	return 0;
+}
+
 
 /* ----------------------------------------------------------------------------
 nmclan_reset
@@ -1681,10 +1635,11 @@ static struct pcmcia_driver nmclan_cs_driver = {
 	.drv		= {
 		.name	= "nmclan_cs",
 	},
-	.attach		= nmclan_attach,
-	.event		= nmclan_event,
-	.detach		= nmclan_detach,
+	.probe		= nmclan_attach,
+	.remove		= nmclan_detach,
 	.id_table       = nmclan_ids,
+	.suspend	= nmclan_suspend,
+	.resume		= nmclan_resume,
 };
 
 static int __init init_nmclan_cs(void)
@@ -1695,7 +1650,6 @@ static int __init init_nmclan_cs(void)
 static void __exit exit_nmclan_cs(void)
 {
 	pcmcia_unregister_driver(&nmclan_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_nmclan_cs);
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 818c185d6438..d85b758f3efa 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -105,8 +105,6 @@ module_param_array(hw_addr, int, NULL, 0);
 static void mii_phy_probe(struct net_device *dev);
 static void pcnet_config(dev_link_t *link);
 static void pcnet_release(dev_link_t *link);
-static int pcnet_event(event_t event, int priority,
-		       event_callback_args_t *args);
 static int pcnet_open(struct net_device *dev);
 static int pcnet_close(struct net_device *dev);
 static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -120,11 +118,9 @@ static int setup_shmem_window(dev_link_t *link, int start_pg,
 static int setup_dma_config(dev_link_t *link, int start_pg,
 			    int stop_pg);
 
-static dev_link_t *pcnet_attach(void);
-static void pcnet_detach(dev_link_t *);
+static void pcnet_detach(struct pcmcia_device *p_dev);
 
 static dev_info_t dev_info = "pcnet_cs";
-static dev_link_t *dev_list;
 
 /*====================================================================*/
 
@@ -244,19 +240,17 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev)
 
 ======================================================================*/
 
-static dev_link_t *pcnet_attach(void)
+static int pcnet_probe(struct pcmcia_device *p_dev)
 {
     pcnet_dev_t *info;
     dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
 
     DEBUG(0, "pcnet_attach()\n");
 
     /* Create new ethernet device */
     dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
-    if (!dev) return NULL;
+    if (!dev) return -ENOMEM;
     info = PRIV(dev);
     link = &info->link;
     link->priv = dev;
@@ -271,20 +265,13 @@ static dev_link_t *pcnet_attach(void)
     dev->stop = &pcnet_close;
     dev->set_config = &set_config;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	pcnet_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    pcnet_config(link);
+
+    return 0;
 } /* pcnet_attach */
 
 /*======================================================================
@@ -296,31 +283,20 @@ static dev_link_t *pcnet_attach(void)
 
 ======================================================================*/
 
-static void pcnet_detach(dev_link_t *link)
+static void pcnet_detach(struct pcmcia_device *p_dev)
 {
-    struct net_device *dev = link->priv;
-    dev_link_t **linkp;
-
-    DEBUG(0, "pcnet_detach(0x%p)\n", link);
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
+	DEBUG(0, "pcnet_detach(0x%p)\n", link);
 
-    if (link->dev)
-	unregister_netdev(dev);
+	if (link->dev)
+		unregister_netdev(dev);
 
-    if (link->state & DEV_CONFIG)
-	pcnet_release(link);
-
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
+	if (link->state & DEV_CONFIG)
+		pcnet_release(link);
 
-    /* Unlink device structure, free bits */
-    *linkp = link->next;
-    free_netdev(dev);
+	free_netdev(dev);
 } /* pcnet_detach */
 
 /*======================================================================
@@ -780,50 +756,39 @@ static void pcnet_release(dev_link_t *link)
 
 ======================================================================*/
 
-static int pcnet_event(event_t event, int priority,
-		       event_callback_args_t *args)
+static int pcnet_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    DEBUG(2, "pcnet_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;
-	pcnet_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+	return 0;
+}
+
+static int pcnet_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		pcnet_reset_8390(dev);
-		NS8390_init(dev, 1);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			pcnet_reset_8390(dev);
+			NS8390_init(dev, 1);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* pcnet_event */
+
+	return 0;
+}
+
 
 /*======================================================================
 
@@ -1844,11 +1809,12 @@ static struct pcmcia_driver pcnet_driver = {
 	.drv		= {
 		.name	= "pcnet_cs",
 	},
-	.attach		= pcnet_attach,
-	.event		= pcnet_event,
-	.detach		= pcnet_detach,
+	.probe		= pcnet_probe,
+	.remove		= pcnet_detach,
 	.owner		= THIS_MODULE,
 	.id_table	= pcnet_ids,
+	.suspend	= pcnet_suspend,
+	.resume		= pcnet_resume,
 };
 
 static int __init init_pcnet_cs(void)
@@ -1860,7 +1826,6 @@ static void __exit exit_pcnet_cs(void)
 {
     DEBUG(0, "pcnet_cs: unloading\n");
     pcmcia_unregister_driver(&pcnet_driver);
-    BUG_ON(dev_list != NULL);
 }
 
 module_init(init_pcnet_cs);
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index c7cca842e5ee..0122415dfeef 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -102,10 +102,6 @@ static const char *version =
    currently have room for another Tx packet. */
 #define MEMORY_WAIT_TIME       	8
 
-static dev_info_t dev_info = "smc91c92_cs";
-
-static dev_link_t *dev_list;
-
 struct smc_private {
     dev_link_t			link;
     spinlock_t			lock;
@@ -281,12 +277,9 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002,
 
 /*====================================================================*/
 
-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,
-			  event_callback_args_t *args);
 
 static int smc_open(struct net_device *dev);
 static int smc_close(struct net_device *dev);
@@ -315,20 +308,18 @@ static struct ethtool_ops ethtool_ops;
 
 ======================================================================*/
 
-static dev_link_t *smc91c92_attach(void)
+static int smc91c92_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     struct smc_private *smc;
     dev_link_t *link;
     struct net_device *dev;
-    int ret;
 
     DEBUG(0, "smc91c92_attach()\n");
 
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(struct smc_private));
     if (!dev)
-	return NULL;
+	return -ENOMEM;
     smc = netdev_priv(dev);
     link = &smc->link;
     link->priv = dev;
@@ -366,20 +357,13 @@ static dev_link_t *smc91c92_attach(void)
     smc->mii_if.phy_id_mask = 0x1f;
     smc->mii_if.reg_num_mask = 0x1f;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	smc91c92_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    smc91c92_config(link);
 
-    return link;
+    return 0;
 } /* smc91c92_attach */
 
 /*======================================================================
@@ -391,30 +375,19 @@ 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;
 
     DEBUG(0, "smc91c92_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 (link->dev)
 	unregister_netdev(dev);
 
     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);
 } /* smc91c92_detach */
 
@@ -895,6 +868,62 @@ free_cfg_mem:
    return rc;
 }
 
+static int smc91c92_suspend(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
+	}
+
+	return 0;
+}
+
+static int smc91c92_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+	struct smc_private *smc = netdev_priv(dev);
+	int i;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		if ((smc->manfid == MANFID_MEGAHERTZ) &&
+		    (smc->cardid == PRODID_MEGAHERTZ_EM3288))
+			mhz_3288_power(link);
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (smc->manfid == MANFID_MOTOROLA)
+			mot_config(link);
+		if ((smc->manfid == MANFID_OSITECH) &&
+		    (smc->cardid != PRODID_OSITECH_SEVEN)) {
+			/* Power up the card and enable interrupts */
+			set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
+			set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
+		}
+		if (((smc->manfid == MANFID_OSITECH) &&
+		     (smc->cardid == PRODID_OSITECH_SEVEN)) ||
+		    ((smc->manfid == MANFID_PSION) &&
+		     (smc->cardid == PRODID_PSION_NET100))) {
+			/* Download the Seven of Diamonds firmware */
+			for (i = 0; i < sizeof(__Xilinx7OD); i++) {
+				outb(__Xilinx7OD[i], link->io.BasePort1+2);
+				udelay(50);
+			}
+		}
+		if (link->open) {
+			smc_reset(dev);
+			netif_device_attach(dev);
+		}
+	}
+
+	return 0;
+}
+
+
 /*======================================================================
 
     This verifies that the chip is some SMC91cXX variant, and returns
@@ -935,14 +964,12 @@ static int check_sig(dev_link_t *link)
     }
 
     if (width) {
-	event_callback_args_t args;
 	printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
-	args.client_data = link;
-	smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args);
+	smc91c92_suspend(link->handle);
 	pcmcia_release_io(link->handle, &link->io);
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	pcmcia_request_io(link->handle, &link->io);
-	smc91c92_event(CS_EVENT_CARD_RESET, 0, &args);
+	smc91c92_resume(link->handle);
 	return check_sig(link);
     }
     return -ENODEV;
@@ -1172,82 +1199,6 @@ static void smc91c92_release(dev_link_t *link)
 
 /*======================================================================
 
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-======================================================================*/
-
-static int smc91c92_event(event_t event, int priority,
-			  event_callback_args_t *args)
-{
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
-    struct smc_private *smc = netdev_priv(dev);
-    int i;
-
-    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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
-	}
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (link->state & DEV_CONFIG) {
-	    if ((smc->manfid == MANFID_MEGAHERTZ) &&
-		(smc->cardid == PRODID_MEGAHERTZ_EM3288))
-		mhz_3288_power(link);
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (smc->manfid == MANFID_MOTOROLA)
-		mot_config(link);
-	    if ((smc->manfid == MANFID_OSITECH) &&
-		(smc->cardid != PRODID_OSITECH_SEVEN)) {
-		/* Power up the card and enable interrupts */
-		set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
-		set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
-	    }
-	    if (((smc->manfid == MANFID_OSITECH) &&
-	 	(smc->cardid == PRODID_OSITECH_SEVEN)) ||
-		((smc->manfid == MANFID_PSION) &&
-	 	(smc->cardid == PRODID_PSION_NET100))) {
-		/* Download the Seven of Diamonds firmware */
-		for (i = 0; i < sizeof(__Xilinx7OD); i++) {
-	    	    outb(__Xilinx7OD[i], link->io.BasePort1+2);
-	   	    udelay(50);
-		}
-	    }
-	    if (link->open) {
-		smc_reset(dev);
-		netif_device_attach(dev);
-	    }
-	}
-	break;
-    }
-    return 0;
-} /* smc91c92_event */
-
-/*======================================================================
-
     MII interface support for SMC91cXX based cards
 ======================================================================*/
 
@@ -2360,10 +2311,11 @@ static struct pcmcia_driver smc91c92_cs_driver = {
 	.drv		= {
 		.name	= "smc91c92_cs",
 	},
-	.attach		= smc91c92_attach,
-	.event		= smc91c92_event,
-	.detach		= smc91c92_detach,
+	.probe		= smc91c92_attach,
+	.remove		= smc91c92_detach,
 	.id_table       = smc91c92_ids,
+	.suspend	= smc91c92_suspend,
+	.resume		= smc91c92_resume,
 };
 
 static int __init init_smc91c92_cs(void)
@@ -2374,7 +2326,6 @@ static int __init init_smc91c92_cs(void)
 static void __exit exit_smc91c92_cs(void)
 {
 	pcmcia_unregister_driver(&smc91c92_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_smc91c92_cs);
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index ce143f08638a..049c34b37067 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -292,8 +292,6 @@ static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg,
 static int has_ce2_string(dev_link_t * link);
 static void xirc2ps_config(dev_link_t * link);
 static void xirc2ps_release(dev_link_t * link);
-static int xirc2ps_event(event_t event, int priority,
-			 event_callback_args_t * args);
 
 /****************
  * The attach() and detach() entry points are used to create and destroy
@@ -301,8 +299,7 @@ static int xirc2ps_event(event_t event, int priority,
  * needed to manage one actual PCMCIA card.
  */
 
-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
@@ -313,14 +310,6 @@ static void xirc2ps_detach(dev_link_t *);
 
 static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card configuration
- * database.
- */
-
-static dev_info_t dev_info = "xirc2ps_cs";
-
 /****************
  * A linked list of "instances" of the device.  Each actual
  * PCMCIA card corresponds to one device instance, and is described
@@ -331,15 +320,7 @@ static dev_info_t dev_info = "xirc2ps_cs";
  * device numbers are used to derive the corresponding array index.
  */
 
-static dev_link_t *dev_list;
-
 /****************
- * A dev_link_t structure has fields for most things that are needed
- * to keep track of a socket, but there will usually be some device
- * specific information that also needs to be kept track of.  The
- * 'priv' pointer in a dev_link_t structure can be used to point to
- * a device-specific private data structure, like this.
- *
  * A driver needs to provide a dev_node_t structure for each device
  * on a card.  In some cases, there is only one device per card (for
  * example, ethernet cards, modems).  In other cases, there may be
@@ -571,21 +552,19 @@ mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len)
  * card insertion event.
  */
 
-static dev_link_t *
-xirc2ps_attach(void)
+static int
+xirc2ps_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     struct net_device *dev;
     local_info_t *local;
-    int err;
 
     DEBUG(0, "attach()\n");
 
     /* Allocate the device structure */
     dev = alloc_etherdev(sizeof(local_info_t));
     if (!dev)
-	    return NULL;
+	    return -ENOMEM;
     local = netdev_priv(dev);
     link = &local->link;
     link->priv = dev;
@@ -614,19 +593,13 @@ xirc2ps_attach(void)
     dev->watchdog_timeo = TX_TIMEOUT;
 #endif
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    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);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    xirc2ps_config(link);
 
-    return link;
+    return 0;
 } /* xirc2ps_attach */
 
 /****************
@@ -637,40 +610,19 @@ 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;
 
     DEBUG(0, "detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link)
-	    break;
-    if (!*linkp) {
-	DEBUG(0, "detach(0x%p): dev_link lost\n", link);
-	return;
-    }
-
     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);
 } /* xirc2ps_detach */
 
@@ -1157,67 +1109,41 @@ xirc2ps_release(dev_link_t *link)
 
 /*====================================================================*/
 
-/****************
- * The card status event handler.  Mostly, this schedules other
- * stuff to run after an event is received.  A CARD_REMOVAL event
- * also sets some flags to discourage the net drivers from trying
- * to talk to the card any more.
- *
- * When a CARD_REMOVAL event is received, we immediately set a flag
- * to block future accesses to this device.  All the functions that
- * actually access the device should check this flag to make sure
- * the card is still present.
- */
 
-static int
-xirc2ps_event(event_t event, int priority,
-	      event_callback_args_t * args)
+static int xirc2ps_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
-
-    DEBUG(0, "event(%d)\n", (int)event);
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open) {
-		netif_device_detach(dev);
-		do_powerdown(dev);
-	    }
-	    pcmcia_release_configuration(link->handle);
+		if (link->open) {
+			netif_device_detach(dev);
+			do_powerdown(dev);
+		}
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+	return 0;
+}
+
+static int xirc2ps_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		do_reset(dev,1);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			do_reset(dev,1);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* xirc2ps_event */
+
+	return 0;
+}
+
 
 /*====================================================================*/
 
@@ -2009,10 +1935,11 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
 	.drv		= {
 		.name	= "xirc2ps_cs",
 	},
-	.attach		= xirc2ps_attach,
-	.event		= xirc2ps_event,
-	.detach		= xirc2ps_detach,
+	.probe		= xirc2ps_attach,
+	.remove		= xirc2ps_detach,
 	.id_table       = xirc2ps_ids,
+	.suspend	= xirc2ps_suspend,
+	.resume		= xirc2ps_resume,
 };
 
 static int __init
@@ -2025,7 +1952,6 @@ static void __exit
 exit_xirc2ps_cs(void)
 {
 	pcmcia_unregister_driver(&xirc2ps_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_xirc2ps_cs);
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index e328547599dc..a496460ce224 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -82,8 +82,6 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
 
 static void airo_config(dev_link_t *link);
 static void airo_release(dev_link_t *link);
-static int airo_event(event_t event, int priority,
-		       event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -91,8 +89,7 @@ static int airo_event(event_t event, int priority,
    needed to manage one actual PCMCIA card.
 */
 
-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
@@ -102,14 +99,6 @@ static void airo_detach(dev_link_t *);
 */
 
 /*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "airo_cs";
-
-/*
    A linked list of "instances" of the  aironet device.  Each actual
    PCMCIA card corresponds to one device instance, and is described
    by one dev_link_t structure (defined in ds.h).
@@ -119,15 +108,7 @@ static dev_info_t dev_info = "airo_cs";
    device numbers are used to derive the corresponding array index.
 */
 
-static dev_link_t *dev_list = NULL;
-
 /*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -160,20 +141,18 @@ typedef struct local_info_t {
   
   ======================================================================*/
 
-static dev_link_t *airo_attach(void)
+static int airo_attach(struct pcmcia_device *p_dev)
 {
-	client_reg_t client_reg;
 	dev_link_t *link;
 	local_info_t *local;
-	int ret;
-	
+
 	DEBUG(0, "airo_attach()\n");
 
 	/* Initialize the dev_link_t structure */
 	link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
 	if (!link) {
 		printk(KERN_ERR "airo_cs: no memory for new device\n");
-		return NULL;
+		return -ENOMEM;
 	}
 	
 	/* Interrupt setup */
@@ -197,24 +176,17 @@ static dev_link_t *airo_attach(void)
 	if (!local) {
 		printk(KERN_ERR "airo_cs: no memory for new device\n");
 		kfree (link);
-		return NULL;
+		return -ENOMEM;
 	}
 	link->priv = local;
-	
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		airo_detach(link);
-		return NULL;
-	}
-	
-	return link;
+
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	airo_config(link);
+
+	return 0;
 } /* airo_attach */
 
 /*======================================================================
@@ -226,37 +198,22 @@ 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 **linkp;
-	
+	dev_link_t *link = dev_to_instance(p_dev);
+
 	DEBUG(0, "airo_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 (link->state & DEV_CONFIG)
 		airo_release(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);
-	
-	
-	
-	/* Unlink device structure, free pieces */
-	*linkp = link->next;
+	((local_info_t*)link->priv)->eth_dev = NULL;
+
 	kfree(link->priv);
 	kfree(link);
-	
 } /* airo_detach */
 
 /*======================================================================
@@ -492,60 +449,34 @@ static void airo_release(dev_link_t *link)
 	link->state &= ~DEV_CONFIG;
 }
 
-/*======================================================================
-  
-  The card status event handler.  Mostly, this schedules other
-  stuff to run after an event is received.
+static int airo_suspend(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *local = link->priv;
 
-  When a CARD_REMOVAL event is received, we immediately set a
-  private flag to block future accesses to this device.  All the
-  functions that actually access the device should check this flag
-  to make sure the card is still present.
-  
-  ======================================================================*/
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		netif_device_detach(local->eth_dev);
+		pcmcia_release_configuration(link->handle);
+	}
+
+	return 0;
+}
 
-static int airo_event(event_t event, int priority,
-		      event_callback_args_t *args)
+static int airo_resume(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	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);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG) {
-			netif_device_detach(local->eth_dev);
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-			reset_airo_card(local->eth_dev);
-			netif_device_attach(local->eth_dev);
-		}
-		break;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		reset_airo_card(local->eth_dev);
+		netif_device_attach(local->eth_dev);
 	}
+
 	return 0;
-} /* airo_event */
+}
 
 static struct pcmcia_device_id airo_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a),
@@ -561,10 +492,11 @@ static struct pcmcia_driver airo_driver = {
 	.drv		= {
 		.name	= "airo_cs",
 	},
-	.attach		= airo_attach,
-	.event		= airo_event,
-	.detach		= airo_detach,
+	.probe		= airo_attach,
+	.remove		= airo_detach,
 	.id_table       = airo_ids,
+	.suspend	= airo_suspend,
+	.resume		= airo_resume,
 };
 
 static int airo_cs_init(void)
@@ -575,7 +507,6 @@ static int airo_cs_init(void)
 static void airo_cs_cleanup(void)
 {
 	pcmcia_unregister_driver(&airo_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 /*
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 17d1fd90f832..d6f4a5a3e55a 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -93,8 +93,6 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
 
 static void atmel_config(dev_link_t *link);
 static void atmel_release(dev_link_t *link);
-static int atmel_event(event_t event, int priority,
-		       event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -102,8 +100,7 @@ static int atmel_event(event_t event, int priority,
    needed to manage one actual PCMCIA card.
 */
 
-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
@@ -113,14 +110,6 @@ static void atmel_detach(dev_link_t *);
 */
 
 /*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "atmel_cs";
-
-/*
    A linked list of "instances" of the  atmelnet device.  Each actual
    PCMCIA card corresponds to one device instance, and is described
    by one dev_link_t structure (defined in ds.h).
@@ -130,15 +119,7 @@ static dev_info_t dev_info = "atmel_cs";
    device numbers are used to derive the corresponding array index.
 */
 
-static dev_link_t *dev_list = NULL;
-
 /*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -171,27 +152,25 @@ typedef struct local_info_t {
   
   ======================================================================*/
 
-static dev_link_t *atmel_attach(void)
+static int atmel_attach(struct pcmcia_device *p_dev)
 {
-	client_reg_t client_reg;
 	dev_link_t *link;
 	local_info_t *local;
-	int ret;
-	
+
 	DEBUG(0, "atmel_attach()\n");
 
 	/* Initialize the dev_link_t structure */
 	link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
 	if (!link) {
 		printk(KERN_ERR "atmel_cs: no memory for new device\n");
-		return NULL;
+		return -ENOMEM;
 	}
-	
+
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
 	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = NULL;
-	
+
 	/*
 	  General socket configuration defaults can go here.  In this
 	  client, we assume very little, and rely on the CIS for almost
@@ -202,30 +181,23 @@ static dev_link_t *atmel_attach(void)
 	link->conf.Attributes = 0;
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
-	
+
 	/* Allocate space for private device-specific data */
 	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
 	if (!local) {
 		printk(KERN_ERR "atmel_cs: no memory for new device\n");
 		kfree (link);
-		return NULL;
+		return -ENOMEM;
 	}
 	link->priv = local;
-	
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		atmel_detach(link);
-		return NULL;
-	}
-	
-	return link;
+
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	atmel_config(link);
+
+	return 0;
 } /* atmel_attach */
 
 /*======================================================================
@@ -237,27 +209,15 @@ 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 **linkp;
-	
+	dev_link_t *link = dev_to_instance(p_dev);
+
 	DEBUG(0, "atmel_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 (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;
 	kfree(link->priv);
 	kfree(link);
 }
@@ -477,60 +437,34 @@ static void atmel_release(dev_link_t *link)
 	link->state &= ~DEV_CONFIG;
 }
 
-/*======================================================================
-  
-  The card status event handler.  Mostly, this schedules other
-  stuff to run after an event is received.
+static int atmel_suspend(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	local_info_t *local = link->priv;
 
-  When a CARD_REMOVAL event is received, we immediately set a
-  private flag to block future accesses to this device.  All the
-  functions that actually access the device should check this flag
-  to make sure the card is still present.
-  
-  ======================================================================*/
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		netif_device_detach(local->eth_dev);
+		pcmcia_release_configuration(link->handle);
+	}
+
+	return 0;
+}
 
-static int atmel_event(event_t event, int priority,
-		      event_callback_args_t *args)
+static int atmel_resume(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 	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);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG) {
-			netif_device_detach(local->eth_dev);
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-			atmel_open(local->eth_dev);
-			netif_device_attach(local->eth_dev);
-		}
-		break;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		atmel_open(local->eth_dev);
+		netif_device_attach(local->eth_dev);
 	}
+
 	return 0;
-} /* atmel_event */
+}
 
 /*====================================================================*/
 /* We use the driver_info field to store the correct firmware type for a card. */
@@ -581,10 +515,11 @@ static struct pcmcia_driver atmel_driver = {
 	.drv		= {
 		.name	= "atmel_cs",
         },
-	.attach         = atmel_attach,
-	.event		= atmel_event,
-	.detach		= atmel_detach,
+	.probe          = atmel_attach,
+	.remove		= atmel_detach,
 	.id_table	= atmel_ids,
+	.suspend	= atmel_suspend,
+	.resume		= atmel_resume,
 };
 
 static int atmel_cs_init(void)
@@ -595,7 +530,6 @@ static int atmel_cs_init(void)
 static void atmel_cs_cleanup(void)
 {
         pcmcia_unregister_driver(&atmel_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 /*
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 2643976a6677..8bc0b528548f 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -25,7 +25,6 @@
 
 static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
 static dev_info_t dev_info = "hostap_cs";
-static dev_link_t *dev_list = NULL;
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
@@ -203,10 +202,9 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
 
 
 
-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);
+static int prism2_config(dev_link_t *link);
 
 
 static int prism2_pccard_card_present(local_info_t *local)
@@ -503,15 +501,13 @@ static struct prism2_helper_functions prism2_pccard_funcs =
 
 /* allocate local data and register with CardServices
  * initialize dev_link structure, but do not configure the card yet */
-static dev_link_t *prism2_attach(void)
+static int prism2_attach(struct pcmcia_device *p_dev)
 {
 	dev_link_t *link;
-	client_reg_t client_reg;
-	int ret;
 
 	link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
 	if (link == NULL)
-		return NULL;
+		return -ENOMEM;
 
 	memset(link, 0, sizeof(dev_link_t));
 
@@ -519,50 +515,27 @@ static dev_link_t *prism2_attach(void)
 	link->conf.Vcc = 33;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* register with CardServices */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		prism2_detach(link);
-		return NULL;
-	}
-	return link;
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	if (prism2_config(link))
+		PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
+
+	return 0;
 }
 
 
-static void prism2_detach(dev_link_t *link)
+static void prism2_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	PDEBUG(DEBUG_FLOW, "prism2_detach\n");
 
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-	if (*linkp == NULL) {
-		printk(KERN_WARNING "%s: Attempt to detach non-existing "
-		       "PCMCIA client\n", dev_info);
-		return;
-	}
-
 	if (link->state & DEV_CONFIG) {
 		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) {
 		struct hostap_cs_priv *hw_priv;
@@ -846,84 +819,58 @@ static void prism2_release(u_long arg)
 	PDEBUG(DEBUG_FLOW, "release - done\n");
 }
 
-
-static int prism2_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int hostap_cs_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = (struct net_device *) link->priv;
 	int dev_open = 0;
 
+	PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
+
+	link->state |= DEV_SUSPEND;
+
 	if (link->state & DEV_CONFIG) {
 		struct hostap_interface *iface = netdev_priv(dev);
 		if (iface && iface->local)
 			dev_open = iface->local->num_dev_open > 0;
-	}
-
-	switch (event) {
-	case CS_EVENT_CARD_INSERTION:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		if (prism2_config(link)) {
-			PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
-		}
-		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) {
+		if (dev_open) {
 			netif_stop_queue(dev);
 			netif_device_detach(dev);
-			prism2_release((u_long) link);
 		}
-		break;
+		prism2_suspend(dev);
+		pcmcia_release_configuration(link->handle);
+	}
 
-	case CS_EVENT_PM_SUSPEND:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
-		link->state |= DEV_SUSPEND;
-		/* fall through */
-
-	case CS_EVENT_RESET_PHYSICAL:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
-		if (link->state & DEV_CONFIG) {
-			if (dev_open) {
-				netif_stop_queue(dev);
-				netif_device_detach(dev);
-			}
-			prism2_suspend(dev);
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
+	return 0;
+}
 
-	case CS_EVENT_PM_RESUME:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
-		link->state &= ~DEV_SUSPEND;
-		/* fall through */
-
-	case CS_EVENT_CARD_RESET:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle,
-						     &link->conf);
-			prism2_hw_shutdown(dev, 1);
-			prism2_hw_config(dev, dev_open ? 0 : 1);
-			if (dev_open) {
-				netif_device_attach(dev);
-				netif_start_queue(dev);
-			}
-		}
-		break;
+static int hostap_cs_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = (struct net_device *) link->priv;
+	int dev_open = 0;
 
-	default:
-		PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
-		       dev_info, event);
-		break;
+	PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		struct hostap_interface *iface = netdev_priv(dev);
+		if (iface && iface->local)
+			dev_open = iface->local->num_dev_open > 0;
+
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+		prism2_hw_shutdown(dev, 1);
+		prism2_hw_config(dev, dev_open ? 0 : 1);
+		if (dev_open) {
+			netif_device_attach(dev);
+			netif_start_queue(dev);
+		}
 	}
+
 	return 0;
 }
 
-
 static struct pcmcia_device_id hostap_cs_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100),
 	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
@@ -982,11 +929,12 @@ static struct pcmcia_driver hostap_driver = {
 	.drv		= {
 		.name	= "hostap_cs",
 	},
-	.attach		= prism2_attach,
-	.detach		= prism2_detach,
+	.probe		= prism2_attach,
+	.remove		= prism2_detach,
 	.owner		= THIS_MODULE,
-	.event		= prism2_event,
 	.id_table	= hostap_cs_ids,
+	.suspend	= hostap_cs_suspend,
+	.resume		= hostap_cs_resume,
 };
 
 static int __init init_prism2_pccard(void)
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 92793b958e32..bf6271ee387a 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -166,8 +166,6 @@ static char *version =
 #define DEBUG(n, args...)
 #endif
 
-static dev_info_t dev_info = "netwave_cs";
-
 /*====================================================================*/
 
 /* Parameters that can be set with 'insmod' */
@@ -195,12 +193,9 @@ module_param(mem_speed, int, 0);
 
 /* PCMCIA (Card Services) related functions */
 static void netwave_release(dev_link_t *link);     /* Card removal */
-static int  netwave_event(event_t event, int priority, 
-					      event_callback_args_t *args);
 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);
@@ -228,17 +223,6 @@ static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
 
 /*
-   A linked list of "instances" of the skeleton device.  Each actual
-   PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
-
-   You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of dev_link_t pointers, where minor
-   device numbers are used to derive the corresponding array index.
-*/
-static dev_link_t *dev_list;
-
-/*
    A dev_link_t structure has fields for most things that are needed
    to keep track of a socket, but there will usually be some device
    specific information that also needs to be kept track of.  The
@@ -394,20 +378,18 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
  *     configure the card at this point -- we wait until we receive a
  *     card insertion event.
  */
-static dev_link_t *netwave_attach(void)
+static int netwave_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     struct net_device *dev;
     netwave_private *priv;
-    int ret;
-    
+
     DEBUG(0, "netwave_attach()\n");
-    
+
     /* Initialize the dev_link_t structure */
     dev = alloc_etherdev(sizeof(netwave_private));
     if (!dev)
-	return NULL;
+	return -ENOMEM;
     priv = netdev_priv(dev);
     link = &priv->link;
     link->priv = dev;
@@ -449,21 +431,14 @@ static dev_link_t *netwave_attach(void)
     dev->open = &netwave_open;
     dev->stop = &netwave_close;
     link->irq.Instance = dev;
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	netwave_detach(link);
-	return NULL;
-    }
 
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    netwave_pcmcia_config( link);
+
+    return 0;
 } /* netwave_attach */
 
 /*
@@ -474,42 +449,20 @@ 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)
 {
-    struct net_device *dev = link->priv;
-    dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    DEBUG(0, "netwave_detach(0x%p)\n", link);
-  
-    /*
-	  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)
-	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;
-    if (*linkp == NULL)
-      {
-	DEBUG(1, "netwave_cs: detach fail, '%s' not in list\n",
-	      link->dev->dev_name);
-	return;
-      }
-
-    /* Unlink device structure, free pieces */
-    *linkp = link->next;
-    if (link->dev) 
-	unregister_netdev(dev);
-    free_netdev(dev);
-    
+	DEBUG(0, "netwave_detach(0x%p)\n", link);
+
+	if (link->state & DEV_CONFIG)
+		netwave_release(link);
+
+	if (link->dev)
+		unregister_netdev(dev);
+
+	free_netdev(dev);
 } /* netwave_detach */
 
 /*
@@ -935,69 +888,38 @@ static void netwave_release(dev_link_t *link)
     link->state &= ~DEV_CONFIG;
 }
 
-/*
- * Function netwave_event (event, priority, args)
- *
- *    The card status event handler.  Mostly, this schedules other
- *    stuff to run after an event is received.  A CARD_REMOVAL event
- *    also sets some flags to discourage the net drivers from trying
- *    to talk to the card any more.
- *
- *    When a CARD_REMOVAL event is received, we immediately set a flag
- *    to block future accesses to this device.  All the functions that
- *    actually access the device should check this flag to make sure
- *    the card is still present.
- *
- */
-static int netwave_event(event_t event, int priority,
-			 event_callback_args_t *args)
+static int netwave_suspend(struct pcmcia_device *p_dev)
 {
-    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;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	netwave_pcmcia_config( link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+	return 0;
+}
+
+static int netwave_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		netwave_reset(dev);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			netwave_reset(dev);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* netwave_event */
+
+	return 0;
+}
+
 
 /*
  * Function netwave_doreset (ioBase, ramBase)
@@ -1491,10 +1413,11 @@ static struct pcmcia_driver netwave_driver = {
 	.drv		= {
 		.name	= "netwave_cs",
 	},
-	.attach		= netwave_attach,
-	.event		= netwave_event,
-	.detach		= netwave_detach,
+	.probe		= netwave_attach,
+	.remove		= netwave_detach,
 	.id_table       = netwave_ids,
+	.suspend	= netwave_suspend,
+	.resume		= netwave_resume,
 };
 
 static int __init init_netwave_cs(void)
@@ -1505,7 +1428,6 @@ static int __init init_netwave_cs(void)
 static void __exit exit_netwave_cs(void)
 {
 	pcmcia_unregister_driver(&netwave_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_netwave_cs);
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index dc1128a00971..b664708481cc 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -43,17 +43,6 @@ module_param(ignore_cis_vcc, int, 0);
 MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
 
 /********************************************************************/
-/* Magic constants						    */
-/********************************************************************/
-
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card
- * configuration database.
- */
-static dev_info_t dev_info = DRIVER_NAME;
-
-/********************************************************************/
 /* Data structures						    */
 /********************************************************************/
 
@@ -69,19 +58,14 @@ struct orinoco_pccard {
 	unsigned long hard_reset_in_progress; 
 };
 
-/*
- * A linked list of "instances" of the device.  Each actual PCMCIA
- * card corresponds to one device instance, and is described by one
- * dev_link_t structure (defined in ds.h).
- */
-static dev_link_t *dev_list; /* = NULL */
 
 /********************************************************************/
 /* Function prototypes						    */
 /********************************************************************/
 
+static void orinoco_cs_config(dev_link_t *link);
 static void orinoco_cs_release(dev_link_t *link);
-static void orinoco_cs_detach(dev_link_t *link);
+static void orinoco_cs_detach(struct pcmcia_device *p_dev);
 
 /********************************************************************/
 /* Device methods     						    */
@@ -119,19 +103,17 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
  * The dev_link structure is initialized, but we don't actually
  * configure the card at this point -- we wait until we receive a card
  * insertion event.  */
-static dev_link_t *
-orinoco_cs_attach(void)
+static int
+orinoco_cs_attach(struct pcmcia_device *p_dev)
 {
 	struct net_device *dev;
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
 	dev_link_t *link;
-	client_reg_t client_reg;
-	int ret;
 
 	dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
 	if (! dev)
-		return NULL;
+		return -ENOMEM;
 	priv = netdev_priv(dev);
 	card = priv->card;
 
@@ -154,22 +136,15 @@ orinoco_cs_attach(void)
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
 	/* Register with Card Services */
-	/* FIXME: need a lock? */
-	link->next = dev_list;
-	dev_list = link;
-
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210; /* FIXME: what does this mean? */
-	client_reg.event_callback_args.client_data = link;
-
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		orinoco_cs_detach(link);
-		return NULL;
-	}
+	link->next = NULL;
+
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	orinoco_cs_config(link);
 
-	return link;
+	return 0;
 }				/* orinoco_cs_attach */
 
 /*
@@ -178,27 +153,14 @@ 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 **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-
-	BUG_ON(*linkp == NULL);
-
 	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);
 	if (link->dev) {
 		DEBUG(0, PFX "About to unregister net device %p\n",
@@ -465,106 +427,82 @@ orinoco_cs_release(dev_link_t *link)
 		ioport_unmap(priv->hw.iobase);
 }				/* orinoco_cs_release */
 
-/*
- * The card status event handler.  Mostly, this schedules other stuff
- * to run after an event is received.
- */
-static int
-orinoco_cs_event(event_t event, int priority,
-		       event_callback_args_t * args)
+static int orinoco_cs_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct orinoco_pccard *card = priv->card;
 	int err = 0;
 	unsigned long flags;
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			unsigned long flags;
-
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		/* This is probably racy, but I can't think of
+		   a better way, short of rewriting the PCMCIA
+		   layer to not suck :-( */
+		if (! test_bit(0, &card->hard_reset_in_progress)) {
 			spin_lock_irqsave(&priv->lock, flags);
+
+			err = __orinoco_down(dev);
+			if (err)
+				printk(KERN_WARNING "%s: Error %d downing interface\n",
+				       dev->name, err);
+
 			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;
+		pcmcia_release_configuration(link->handle);
+	}
 
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		/* Mark the device as stopped, to block IO until later */
-		if (link->state & DEV_CONFIG) {
-			/* This is probably racy, but I can't think of
-                           a better way, short of rewriting the PCMCIA
-                           layer to not suck :-( */
-			if (! test_bit(0, &card->hard_reset_in_progress)) {
-				spin_lock_irqsave(&priv->lock, flags);
-
-				err = __orinoco_down(dev);
-				if (err)
-					printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
-					       dev->name,
-					       event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
-					       err);
-				
-				netif_device_detach(dev);
-				priv->hw_unavailable++;
-
-				spin_unlock_irqrestore(&priv->lock, flags);
+	return 0;
+}
+
+static int orinoco_cs_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_pccard *card = priv->card;
+	int err = 0;
+	unsigned long flags;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		/* FIXME: should we double check that this is
+		 * the same card as we had before */
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+		if (! test_bit(0, &card->hard_reset_in_progress)) {
+			err = orinoco_reinit_firmware(dev);
+			if (err) {
+				printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
+				       dev->name, err);
+				return -EIO;
 			}
 
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
+			spin_lock_irqsave(&priv->lock, flags);
+
+			netif_device_attach(dev);
+			priv->hw_unavailable--;
 
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			/* FIXME: should we double check that this is
-			 * the same card as we had before */
-			pcmcia_request_configuration(link->handle, &link->conf);
-
-			if (! test_bit(0, &card->hard_reset_in_progress)) {
-				err = orinoco_reinit_firmware(dev);
-				if (err) {
-					printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
+			if (priv->open && ! priv->hw_unavailable) {
+				err = __orinoco_up(dev);
+				if (err)
+					printk(KERN_ERR "%s: Error %d restarting card\n",
 					       dev->name, err);
-					break;
-				}
-				
-				spin_lock_irqsave(&priv->lock, flags);
-				
-				netif_device_attach(dev);
-				priv->hw_unavailable--;
-				
-				if (priv->open && ! priv->hw_unavailable) {
-					err = __orinoco_up(dev);
-					if (err)
-						printk(KERN_ERR "%s: Error %d restarting card\n",
-						       dev->name, err);
-					
-				}
-
-				spin_unlock_irqrestore(&priv->lock, flags);
 			}
+
+			spin_unlock_irqrestore(&priv->lock, flags);
 		}
-		break;
 	}
 
-	return err;
-}				/* orinoco_cs_event */
+	return 0;
+}
+
 
 /********************************************************************/
 /* Module initialization					    */
@@ -665,10 +603,11 @@ static struct pcmcia_driver orinoco_driver = {
 	.drv		= {
 		.name	= DRIVER_NAME,
 	},
-	.attach		= orinoco_cs_attach,
-	.detach		= orinoco_cs_detach,
-	.event		= orinoco_cs_event,
+	.probe		= orinoco_cs_attach,
+	.remove		= orinoco_cs_detach,
 	.id_table       = orinoco_cs_ids,
+	.suspend	= orinoco_cs_suspend,
+	.resume		= orinoco_cs_resume,
 };
 
 static int __init
@@ -683,7 +622,6 @@ static void __exit
 exit_orinoco_cs(void)
 {
 	pcmcia_unregister_driver(&orinoco_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_orinoco_cs);
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 70fd6fd8feb9..319180ca7e71 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -92,9 +92,7 @@ module_param(pc_debug, int, 0);
 /** Prototypes based on PCMCIA skeleton driver *******************************/
 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);
@@ -192,12 +190,6 @@ static int bc;
 static char *phy_addr = NULL;
 
 
-/* The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-static dev_info_t dev_info = "ray_cs";
-
 /* A linked list of "instances" of the ray device.  Each actual
    PCMCIA card corresponds to one device instance, and is described
    by one dev_link_t structure (defined in ds.h).
@@ -314,12 +306,10 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.
     configure the card at this point -- we wait until we receive a
     card insertion event.
 =============================================================================*/
-static dev_link_t *ray_attach(void)
+static int ray_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     ray_dev_t *local;
-    int ret;
     struct net_device *dev;
     
     DEBUG(1, "ray_attach()\n");
@@ -328,7 +318,7 @@ static dev_link_t *ray_attach(void)
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
 
     if (!link)
-	    return NULL;
+	    return -ENOMEM;
 
     /* Allocate space for private device-specific data */
     dev = alloc_etherdev(sizeof(ray_dev_t));
@@ -387,30 +377,19 @@ static dev_link_t *ray_attach(void)
     dev->stop = &ray_dev_close;
     netif_stop_queue(dev);
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
+    init_timer(&local->timer);
 
-    DEBUG(2,"ray_cs ray_attach calling pcmcia_register_client(...)\n");
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    init_timer(&local->timer);
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    ray_config(link);
 
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-        printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");
-        cs_error(link->handle, RegisterClient, ret);
-        ray_detach(link);
-        return NULL;
-    }
-    DEBUG(2,"ray_cs ray_attach ending\n");
-    return link;
+    return 0;
 
 fail_alloc_dev:
     kfree(link);
-    return NULL;
+    return -ENOMEM;
 } /* ray_attach */
 /*=============================================================================
     This deletes a driver "instance".  The device is de-registered
@@ -418,9 +397,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 +412,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);
     }
@@ -891,65 +869,40 @@ static void ray_release(dev_link_t *link)
     DEBUG(2,"ray_release ending\n");
 }
 
-/*=============================================================================
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
-=============================================================================*/
-static int ray_event(event_t event, int priority,
-                     event_callback_args_t *args)
+static int ray_suspend(struct pcmcia_device *p_dev)
 {
-    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);
-        break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state |= DEV_SUSPEND;
         if (link->state & DEV_CONFIG) {
-            if (link->open)
-            	netif_device_detach(dev);
+		if (link->open)
+			netif_device_detach(dev);
 
-            pcmcia_release_configuration(link->handle);
+		pcmcia_release_configuration(link->handle);
         }
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
+
+
+	return 0;
+}
+
+static int ray_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
         if (link->state & DEV_CONFIG) {
-            pcmcia_request_configuration(link->handle, &link->conf);
-            if (link->open) {
-                ray_reset(dev);
-		netif_device_attach(dev);
-            }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			ray_reset(dev);
+			netif_device_attach(dev);
+		}
         }
-        break;
-    }
-    return 0;
-    DEBUG(2,"ray_event ending\n");
-} /* ray_event */
+
+	return 0;
+}
+
 /*===========================================================================*/
 int ray_dev_init(struct net_device *dev)
 {
@@ -2945,10 +2898,11 @@ static struct pcmcia_driver ray_driver = {
 	.drv		= {
 		.name	= "ray_cs",
 	},
-	.attach		= ray_attach,
-	.event		= ray_event,
-	.detach		= ray_detach,
+	.probe		= ray_attach,
+	.remove		= ray_detach,
 	.id_table       = ray_ids,
+	.suspend	= ray_suspend,
+	.resume		= ray_resume,
 };
 
 static int __init init_ray_cs(void)
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index b1bbc8e8e91f..fee4be1ce810 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -57,17 +57,6 @@ module_param(ignore_cis_vcc, int, 0);
 MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
 
 /********************************************************************/
-/* Magic constants						    */
-/********************************************************************/
-
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card
- * configuration database.
- */
-static dev_info_t dev_info = DRIVER_NAME;
-
-/********************************************************************/
 /* Data structures						    */
 /********************************************************************/
 
@@ -78,19 +67,12 @@ struct orinoco_pccard {
 	dev_node_t node;
 };
 
-/*
- * A linked list of "instances" of the device.  Each actual PCMCIA
- * card corresponds to one device instance, and is described by one
- * dev_link_t structure (defined in ds.h).
- */
-static dev_link_t *dev_list; /* = NULL */
-
 /********************************************************************/
 /* Function prototypes						    */
 /********************************************************************/
 
+static void spectrum_cs_config(dev_link_t *link);
 static void spectrum_cs_release(dev_link_t *link);
-static void spectrum_cs_detach(dev_link_t *link);
 
 /********************************************************************/
 /* Firmware downloader						    */
@@ -601,19 +583,17 @@ spectrum_cs_hard_reset(struct orinoco_private *priv)
  * The dev_link structure is initialized, but we don't actually
  * configure the card at this point -- we wait until we receive a card
  * insertion event.  */
-static dev_link_t *
-spectrum_cs_attach(void)
+static int
+spectrum_cs_attach(struct pcmcia_device *p_dev)
 {
 	struct net_device *dev;
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
 	dev_link_t *link;
-	client_reg_t client_reg;
-	int ret;
 
 	dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
 	if (! dev)
-		return NULL;
+		return -ENOMEM;
 	priv = netdev_priv(dev);
 	card = priv->card;
 
@@ -635,23 +615,13 @@ spectrum_cs_attach(void)
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	/* FIXME: need a lock? */
-	link->next = dev_list;
-	dev_list = link;
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210; /* FIXME: what does this mean? */
-	client_reg.event_callback_args.client_data = link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	spectrum_cs_config(link);
 
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		spectrum_cs_detach(link);
-		return NULL;
-	}
-
-	return link;
+	return 0;
 }				/* spectrum_cs_attach */
 
 /*
@@ -660,27 +630,14 @@ spectrum_cs_attach(void)
  * are freed.  Otherwise, the structures will be freed when the device
  * is released.
  */
-static void spectrum_cs_detach(dev_link_t *link)
+static void spectrum_cs_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-
-	BUG_ON(*linkp == NULL);
-
 	if (link->state & DEV_CONFIG)
 		spectrum_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);
 	if (link->dev) {
 		DEBUG(0, PFX "About to unregister net device %p\n",
@@ -948,82 +905,56 @@ spectrum_cs_release(dev_link_t *link)
 		ioport_unmap(priv->hw.iobase);
 }				/* spectrum_cs_release */
 
-/*
- * The card status event handler.  Mostly, this schedules other stuff
- * to run after an event is received.
- */
+
 static int
-spectrum_cs_event(event_t event, int priority,
-		       event_callback_args_t * args)
+spectrum_cs_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
 	unsigned long flags;
+	int err = 0;
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			unsigned long flags;
+	link->state |= DEV_SUSPEND;
+	/* Mark the device as stopped, to block IO until later */
+	if (link->state & DEV_CONFIG) {
+		spin_lock_irqsave(&priv->lock, flags);
 
-			spin_lock_irqsave(&priv->lock, flags);
-			netif_device_detach(dev);
-			priv->hw_unavailable++;
-			spin_unlock_irqrestore(&priv->lock, flags);
-		}
-		break;
+		err = __orinoco_down(dev);
+		if (err)
+			printk(KERN_WARNING "%s: Error %d downing interface\n",
+			       dev->name, err);
 
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		spectrum_cs_config(link);
-		break;
+		netif_device_detach(dev);
+		priv->hw_unavailable++;
 
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		/* Mark the device as stopped, to block IO until later */
-		if (link->state & DEV_CONFIG) {
-			/* This is probably racy, but I can't think of
-                           a better way, short of rewriting the PCMCIA
-                           layer to not suck :-( */
-			spin_lock_irqsave(&priv->lock, flags);
-
-			err = __orinoco_down(dev);
-			if (err)
-				printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
-				       dev->name,
-				       event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
-				       err);
-
-			netif_device_detach(dev);
-			priv->hw_unavailable++;
-
-			spin_unlock_irqrestore(&priv->lock, flags);
-
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
+		spin_unlock_irqrestore(&priv->lock, flags);
 
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			/* FIXME: should we double check that this is
-			 * the same card as we had before */
-			pcmcia_request_configuration(link->handle, &link->conf);
-			netif_device_attach(dev);
-			priv->hw_unavailable--;
-			schedule_work(&priv->reset_work);
-		}
-		break;
+		pcmcia_release_configuration(link->handle);
+	}
+
+	return 0;
+}
+
+static int
+spectrum_cs_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		/* FIXME: should we double check that this is
+		 * the same card as we had before */
+		pcmcia_request_configuration(link->handle, &link->conf);
+		netif_device_attach(dev);
+		priv->hw_unavailable--;
+		schedule_work(&priv->reset_work);
 	}
+	return 0;
+}
 
-	return err;
-}				/* spectrum_cs_event */
 
 /********************************************************************/
 /* Module initialization					    */
@@ -1048,9 +979,10 @@ static struct pcmcia_driver orinoco_driver = {
 	.drv		= {
 		.name	= DRIVER_NAME,
 	},
-	.attach		= spectrum_cs_attach,
-	.detach		= spectrum_cs_detach,
-	.event		= spectrum_cs_event,
+	.probe		= spectrum_cs_attach,
+	.remove		= spectrum_cs_detach,
+	.suspend	= spectrum_cs_suspend,
+	.resume		= spectrum_cs_resume,
 	.id_table       = spectrum_cs_ids,
 };
 
@@ -1066,7 +998,6 @@ static void __exit
 exit_spectrum_cs(void)
 {
 	pcmcia_unregister_driver(&orinoco_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_spectrum_cs);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index c822cad3333f..7e2039f52c49 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4594,14 +4594,12 @@ wavelan_close(struct net_device *	dev)
  * configure the card at this point -- we wait until we receive a
  * card insertion event.
  */
-static dev_link_t *
-wavelan_attach(void)
+static int
+wavelan_attach(struct pcmcia_device *p_dev)
 {
-  client_reg_t	client_reg;	/* Register with cardmgr */
   dev_link_t *	link;		/* Info for cardmgr */
   struct net_device *	dev;		/* Interface generic data */
   net_local *	lp;		/* Interface specific data */
-  int		ret;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "-> wavelan_attach()\n");
@@ -4609,7 +4607,7 @@ wavelan_attach(void)
 
   /* Initialize the dev_link_t structure */
   link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-  if (!link) return NULL;
+  if (!link) return -ENOMEM;
 
   /* The io structure describes IO port mapping */
   link->io.NumPorts1 = 8;
@@ -4627,14 +4625,13 @@ wavelan_attach(void)
   link->conf.IntType = INT_MEMORY_AND_IO;
 
   /* Chain drivers */
-  link->next = dev_list;
-  dev_list = link;
+  link->next = NULL;
 
   /* Allocate the generic data structure */
   dev = alloc_etherdev(sizeof(net_local));
   if (!dev) {
       kfree(link);
-      return NULL;
+      return -ENOMEM;
   }
   link->priv = link->irq.Instance = dev;
 
@@ -4679,28 +4676,21 @@ wavelan_attach(void)
   /* Other specific data */
   dev->mtu = WAVELAN_MTU;
 
-  /* Register with Card Services */
-  client_reg.dev_info = &dev_info;
-  client_reg.Version = 0x0210;
-  client_reg.event_callback_args.client_data = link;
+  link->handle = p_dev;
+  p_dev->instance = link;
 
-#ifdef DEBUG_CONFIG_INFO
-  printk(KERN_DEBUG "wavelan_attach(): almost done, calling pcmcia_register_client\n");
-#endif
-
-  ret = pcmcia_register_client(&link->handle, &client_reg);
-  if(ret != 0)
-    {
-      cs_error(link->handle, RegisterClient, ret);
-      wavelan_detach(link);
-      return NULL;
-    }
+  link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+  if(wv_pcmcia_config(link) &&
+     wv_hw_config(dev))
+	  wv_init_info(dev);
+  else
+	  dev->irq = 0;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "<- wavelan_attach()\n");
 #endif
 
-  return link;
+  return 0;
 }
 
 /*------------------------------------------------------------------*/
@@ -4711,8 +4701,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
@@ -4729,31 +4721,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;
-  else
-    {
-      dev_link_t *	prev = dev_list;
-
-      while((prev != (dev_link_t *) NULL) && (prev->next != link))
-	prev = prev->next;
-
-      if(prev == (dev_link_t *) NULL)
-	{
-#ifdef DEBUG_CONFIG_ERRORS
-	  printk(KERN_WARNING "wavelan_detach : Attempting to remove a nonexistent device.\n");
-#endif
-	  return;
-	}
-
-      prev->next = link->next;
-    }
-
   /* Free pieces */
   if(link->priv)
     {
@@ -4775,65 +4742,11 @@ wavelan_detach(dev_link_t *	link)
 #endif
 }
 
-/*------------------------------------------------------------------*/
-/*
- * The card status event handler. Mostly, this schedules other stuff
- * to run after an event is received. A CARD_REMOVAL event also sets
- * some flags to discourage the net drivers from trying to talk to the
- * card any more.
- */
-static int
-wavelan_event(event_t		event,		/* The event received */
-	      int		priority,
-	      event_callback_args_t *	args)
+static int wavelan_suspend(struct pcmcia_device *p_dev)
 {
-  dev_link_t *	link = (dev_link_t *) args->client_data;
-  struct net_device *	dev = (struct net_device *) link->priv;
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "->wavelan_event(): %s\n",
-	 ((event == CS_EVENT_REGISTRATION_COMPLETE)?"registration complete" :
-	  ((event == CS_EVENT_CARD_REMOVAL) ? "card removal" :
-	   ((event == CS_EVENT_CARD_INSERTION) ? "card insertion" :
-	    ((event == CS_EVENT_PM_SUSPEND) ? "pm suspend" :
-	     ((event == CS_EVENT_RESET_PHYSICAL) ? "physical reset" :
-	      ((event == CS_EVENT_PM_RESUME) ? "pm resume" :
-	       ((event == CS_EVENT_CARD_RESET) ? "card reset" :
-		"unknown"))))))));
-#endif
-
-    switch(event)
-      {
-      case CS_EVENT_REGISTRATION_COMPLETE:
-#ifdef DEBUG_CONFIG_INFO
-	printk(KERN_DEBUG "wavelan_cs: registration complete\n");
-#endif
-	break;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *	dev = (struct net_device *) link->priv;
 
-      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;
-	if(wv_pcmcia_config(link) &&
-	   wv_hw_config(dev))
-	  wv_init_info(dev);
-	else
-	  dev->irq = 0;
-	break;
-
-      case CS_EVENT_PM_SUSPEND:
 	/* NB: wavelan_close will be called, but too late, so we are
 	 * obliged to close nicely the wavelan here. David, could you
 	 * close the device before suspending them ? And, by the way,
@@ -4848,38 +4761,37 @@ wavelan_event(event_t		event,		/* The event received */
 
 	/* The card is now suspended */
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-      case CS_EVENT_RESET_PHYSICAL:
+
     	if(link->state & DEV_CONFIG)
-	  {
-      	    if(link->open)
-	      netif_device_detach(dev);
-      	    pcmcia_release_configuration(link->handle);
-	  }
-	break;
+	{
+		if(link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
+	}
+
+	return 0;
+}
+
+static int wavelan_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *	dev = (struct net_device *) link->priv;
 
-      case CS_EVENT_PM_RESUME:
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-      case CS_EVENT_CARD_RESET:
 	if(link->state & DEV_CONFIG)
-	  {
-      	    pcmcia_request_configuration(link->handle, &link->conf);
-      	    if(link->open)	/* If RESET -> True, If RESUME -> False ? */
-	      {
-		wv_hw_reset(dev);
-		netif_device_attach(dev);
-	      }
-	  }
-	break;
-    }
+	{
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if(link->open)	/* If RESET -> True, If RESUME -> False ? */
+		{
+			wv_hw_reset(dev);
+			netif_device_attach(dev);
+		}
+	}
 
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "<-wavelan_event()\n");
-#endif
-  return 0;
+	return 0;
 }
 
+
 static struct pcmcia_device_id wavelan_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),
 	PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06),
@@ -4894,10 +4806,11 @@ static struct pcmcia_driver wavelan_driver = {
 	.drv		= {
 		.name	= "wavelan_cs",
 	},
-	.attach		= wavelan_attach,
-	.event		= wavelan_event,
-	.detach		= wavelan_detach,
+	.probe		= wavelan_attach,
+	.remove		= wavelan_detach,
 	.id_table       = wavelan_ids,
+	.suspend	= wavelan_suspend,
+	.resume		= wavelan_resume,
 };
 
 static int __init
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 724a715089c9..f2d597568151 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -754,20 +754,11 @@ static void
 static int
 	wavelan_open(struct net_device *),		/* Open the device */
 	wavelan_close(struct net_device *);	/* Close the device */
-static dev_link_t *
-	wavelan_attach(void);		/* Create a new device */
 static void
-	wavelan_detach(dev_link_t *);	/* Destroy a removed device */
-static int
-	wavelan_event(event_t,		/* Manage pcmcia events */
-		      int,
-		      event_callback_args_t *);
+	wavelan_detach(struct pcmcia_device *p_dev);	/* Destroy a removed device */
 
 /**************************** VARIABLES ****************************/
 
-static dev_info_t dev_info = "wavelan_cs";
-static dev_link_t *dev_list = NULL;	/* Linked list of devices */
-
 /*
  * Parameters that can be set with 'insmod'
  * The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 978fdc606781..48e10b0c7e74 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -105,7 +105,6 @@ module_param(pc_debug, int, 0);
  */
 static void wl3501_config(dev_link_t *link);
 static void wl3501_release(dev_link_t *link);
-static int wl3501_event(event_t event, int pri, event_callback_args_t *args);
 
 /*
  * The dev_info variable is the "key" that is used to match up this
@@ -1498,9 +1497,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 +1515,12 @@ static void wl3501_detach(dev_link_t *link)
 	 * 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;
@@ -1956,18 +1953,16 @@ static const struct iw_handler_def wl3501_handler_def = {
  * The dev_link structure is initialized, but we don't actually configure the
  * card at this point -- we wait until we receive a card insertion event.
  */
-static dev_link_t *wl3501_attach(void)
+static int wl3501_attach(struct pcmcia_device *p_dev)
 {
-	client_reg_t client_reg;
 	dev_link_t *link;
 	struct net_device *dev;
 	struct wl3501_card *this;
-	int ret;
 
 	/* Initialize the dev_link_t structure */
 	link = kzalloc(sizeof(*link), GFP_KERNEL);
 	if (!link)
-		goto out;
+		return -ENOMEM;
 
 	/* The io structure describes IO port mapping */
 	link->io.NumPorts1	= 16;
@@ -2003,24 +1998,17 @@ static dev_link_t *wl3501_attach(void)
 	netif_stop_queue(dev);
 	link->priv = link->irq.Instance = dev;
 
-	/* Register with Card Services */
-	link->next		 = wl3501_dev_list;
-	wl3501_dev_list		 = link;
-	client_reg.dev_info	 = &wl3501_dev_info;
-	client_reg.Version	 = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret) {
-		cs_error(link->handle, RegisterClient, ret);
-		wl3501_detach(link);
-		link = NULL;
-	}
-out:
-	return link;
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	wl3501_config(link);
+
+	return 0;
 out_link:
 	kfree(link);
 	link = NULL;
-	goto out;
+	return -ENOMEM;
 }
 
 #define CS_CHECK(fn, ret) \
@@ -2173,67 +2161,41 @@ static void wl3501_release(dev_link_t *link)
 	link->state &= ~DEV_CONFIG;
 }
 
-/**
- * wl3501_event - The card status event handler
- * @event - event
- * @pri - priority
- * @args - arguments for this event
- *
- * The card status event handler. Mostly, this schedules other stuff to run
- * after an event is received. A CARD_REMOVAL event also sets some flags to
- * discourage the net drivers from trying to talk to the card any more.
- *
- * When a CARD_REMOVAL event is received, we immediately set a flag to block
- * future accesses to this device. All the functions that actually access the
- * device should check this flag to make sure the card is still present.
- */
-static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
+static int wl3501_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	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);
+	link->state |= DEV_SUSPEND;
+
+	wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
+	if (link->state & DEV_CONFIG) {
+		if (link->open)
 			netif_device_detach(dev);
-			wl3501_release(link);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		wl3501_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG) {
-			if (link->open)
-				netif_device_detach(dev);
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-			if (link->open) {
-				wl3501_reset(dev);
-				netif_device_attach(dev);
-			}
+		pcmcia_release_configuration(link->handle);
+	}
+
+	return 0;
+}
+
+static int wl3501_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			wl3501_reset(dev);
+			netif_device_attach(dev);
 		}
-		break;
 	}
+
 	return 0;
 }
 
+
 static struct pcmcia_device_id wl3501_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001),
 	PCMCIA_DEVICE_NULL
@@ -2245,10 +2207,11 @@ static struct pcmcia_driver wl3501_driver = {
 	.drv		= {
 		.name	= "wl3501_cs",
 	},
-	.attach		= wl3501_attach,
-	.event		= wl3501_event,
-	.detach		= wl3501_detach,
+	.probe		= wl3501_attach,
+	.remove		= wl3501_detach,
 	.id_table	= wl3501_ids,
+	.suspend	= wl3501_suspend,
+	.resume		= wl3501_resume,
 };
 
 static int __init wl3501_init_module(void)
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 24e6aacddb74..158d92563259 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -87,15 +87,9 @@ typedef struct parport_info_t {
     struct parport	*port;
 } 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,
-			 event_callback_args_t *args);
-
-static dev_info_t dev_info = "parport_cs";
-static dev_link_t *dev_list = NULL;
 
 /*======================================================================
 
@@ -105,18 +99,16 @@ static dev_link_t *dev_list = NULL;
 
 ======================================================================*/
 
-static dev_link_t *parport_attach(void)
+static int parport_attach(struct pcmcia_device *p_dev)
 {
     parport_info_t *info;
     dev_link_t *link;
-    client_reg_t client_reg;
-    int ret;
-    
+
     DEBUG(0, "parport_attach()\n");
 
     /* Create new parport device */
     info = kmalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
+    if (!info) return -ENOMEM;
     memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
 
@@ -127,21 +119,14 @@ static dev_link_t *parport_attach(void)
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	parport_detach(link);
-	return NULL;
-    }
-    
-    return link;
+
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    parport_config(link);
+
+    return 0;
 } /* parport_attach */
 
 /*======================================================================
@@ -153,32 +138,16 @@ 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 **linkp;
-    int ret;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "parport_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 (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 */
 
 /*======================================================================
@@ -325,47 +294,27 @@ void parport_cs_release(dev_link_t *link)
 
 } /* parport_cs_release */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.
-    
-======================================================================*/
-
-int parport_event(event_t event, int priority,
-		  event_callback_args_t *args)
+static int parport_suspend(struct pcmcia_device *dev)
 {
-    dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 
-    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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int parport_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (DEV_OK(link))
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	break;
-    }
-    return 0;
-} /* parport_event */
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
+}
 
 static struct pcmcia_device_id parport_ids[] = {
 	PCMCIA_DEVICE_FUNC_ID(3),
@@ -379,11 +328,11 @@ static struct pcmcia_driver parport_cs_driver = {
 	.drv		= {
 		.name	= "parport_cs",
 	},
-	.attach		= parport_attach,
-	.event		= parport_event,
-	.detach		= parport_detach,
+	.probe		= parport_attach,
+	.remove		= parport_detach,
 	.id_table	= parport_ids,
-
+	.suspend	= parport_suspend,
+	.resume		= parport_resume,
 };
 
 static int __init init_parport_cs(void)
@@ -394,7 +343,6 @@ static int __init init_parport_cs(void)
 static void __exit exit_parport_cs(void)
 {
 	pcmcia_unregister_driver(&parport_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_parport_cs);
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 309eb557f9a3..1f4ad0e7836e 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -116,6 +116,31 @@ config YENTA
 
 	  If unsure, say Y.
 
+config YENTA_O2
+	default y
+	bool "Special initialization for O2Micro bridges" if EMBEDDED
+	depends on YENTA
+
+config YENTA_RICOH
+	default y
+	bool "Special initialization for Ricoh bridges" if EMBEDDED
+	depends on YENTA
+
+config YENTA_TI
+	default y
+	bool "Special initialization for TI and EnE bridges" if EMBEDDED
+	depends on YENTA
+
+config YENTA_ENE_TUNE
+	default y
+	bool "Auto-tune EnE bridges for CB cards" if EMBEDDED
+	depends on YENTA_TI && CARDBUS
+
+config YENTA_TOSHIBA
+	default y
+	bool "Special initialization for Toshiba ToPIC bridges" if EMBEDDED
+	depends on YENTA
+
 config PD6729
 	tristate "Cirrus PD6729 compatible bridge support"
 	depends on PCMCIA && PCI
@@ -157,7 +182,7 @@ config TCIC
 config PCMCIA_M8XX
         tristate "MPC8xx PCMCIA support"
         depends on PCMCIA && PPC && 8xx 
-        select PCCARD_NONSTATIC
+        select PCCARD_IODYN
         help
         Say Y here to include support for PowerPC 8xx series PCMCIA
         controller.
@@ -200,7 +225,7 @@ config PCMCIA_PXA2XX
 
 config PCMCIA_PROBE
 	bool
-	default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X
+	default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
 
 config M32R_PCC
 	bool "M32R PCMCIA I/F"
@@ -241,6 +266,9 @@ config OMAP_CF
 config PCCARD_NONSTATIC
 	tristate
 
+config PCCARD_IODYN
+	bool
+
 endif	# PCCARD
 
 endmenu
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 87302c548c24..971a35281649 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -241,23 +241,6 @@ au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
 	return 0;
 }
 
-/* au1x00_pcmcia_get_socket()
- * Implements the get_socket() operation for the in-kernel PCMCIA
- * service (formerly SS_GetSocket in Card Services). Not a very
- * exciting routine.
- *
- * Returns: 0
- */
-static int
-au1x00_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-  struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
-
-  debug("for sock %u\n", skt->nr);
-  *state = skt->cs_state;
-  return 0;
-}
-
 /* au1x00_pcmcia_set_socket()
  * Implements the set_socket() operation for the in-kernel PCMCIA
  * service (formerly SS_SetSocket in Card Services). We more or
@@ -352,7 +335,6 @@ static struct pccard_operations au1x00_pcmcia_operations = {
 	.init			= au1x00_pcmcia_sock_init,
 	.suspend		= au1x00_pcmcia_suspend,
 	.get_status		= au1x00_pcmcia_get_status,
-	.get_socket		= au1x00_pcmcia_get_socket,
 	.set_socket		= au1x00_pcmcia_set_socket,
 	.set_io_map		= au1x00_pcmcia_set_io_map,
 	.set_mem_map		= au1x00_pcmcia_set_mem_map,
@@ -372,13 +354,12 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops,
 	struct skt_dev_info *sinfo;
 	int ret, i;
 
-	sinfo = kmalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
+	sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
 	if (!sinfo) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
-	memset(sinfo, 0, sizeof(struct skt_dev_info));
 	sinfo->nskt = nr;
 
 	/*
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 2dc3e611a9a3..120fa8da6392 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -60,9 +60,9 @@ static const u_int exponent[] = {
 
 /* Parameters that can be set with 'insmod' */
 
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
-
-INT_MODULE_PARM(cis_width,	0);		/* 16-bit CIS? */
+/* 16-bit CIS? */
+static int cis_width;
+module_param(cis_width, int, 0444);
 
 void release_cis_mem(struct pcmcia_socket *s)
 {
@@ -463,7 +463,7 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
 	/* Get indirect link from the MFC tuple */
 	read_cis_cache(s, LINK_SPACE(tuple->Flags),
 		       tuple->LinkOffset, 5, link);
-	ofs = le32_to_cpu(*(u_int *)(link+1));
+	ofs = le32_to_cpu(*(__le32 *)(link+1));
 	SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
 	/* Move to the next indirect link */
 	tuple->LinkOffset += 5;
@@ -671,8 +671,8 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
     if (tuple->TupleDataLen < 5)
 	return CS_BAD_TUPLE;
     p = (u_char *)tuple->TupleData;
-    csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(u_short *)p)-2;
-    csum->len = le16_to_cpu(*(u_short *)(p + 2));
+    csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(__le16 *)p)-2;
+    csum->len = le16_to_cpu(*(__le16 *)(p + 2));
     csum->sum = *(p+4);
     return CS_SUCCESS;
 }
@@ -683,7 +683,7 @@ static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
 {
     if (tuple->TupleDataLen < 4)
 	return CS_BAD_TUPLE;
-    link->addr = le32_to_cpu(*(u_int *)tuple->TupleData);
+    link->addr = le32_to_cpu(*(__le32 *)tuple->TupleData);
     return CS_SUCCESS;
 }
 
@@ -702,7 +702,7 @@ static int parse_longlink_mfc(tuple_t *tuple,
 	return CS_BAD_TUPLE;
     for (i = 0; i < link->nfn; i++) {
 	link->fn[i].space = *p; p++;
-	link->fn[i].addr = le32_to_cpu(*(u_int *)p); p += 4;
+	link->fn[i].addr = le32_to_cpu(*(__le32 *)p); p += 4;
     }
     return CS_SUCCESS;
 }
@@ -789,10 +789,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
 
 static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
 {
-    u_short *p;
+    __le16 *p;
     if (tuple->TupleDataLen < 4)
 	return CS_BAD_TUPLE;
-    p = (u_short *)tuple->TupleData;
+    p = (__le16 *)tuple->TupleData;
     m->manf = le16_to_cpu(p[0]);
     m->card = le16_to_cpu(p[1]);
     return CS_SUCCESS;
@@ -1093,7 +1093,7 @@ static int parse_cftable_entry(tuple_t *tuple,
 	break;
     case 0x20:
 	entry->mem.nwin = 1;
-	entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8;
+	entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
 	entry->mem.win[0].card_addr = 0;
 	entry->mem.win[0].host_addr = 0;
 	p += 2;
@@ -1101,9 +1101,9 @@ static int parse_cftable_entry(tuple_t *tuple,
 	break;
     case 0x40:
 	entry->mem.nwin = 1;
-	entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8;
+	entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
 	entry->mem.win[0].card_addr =
-	    le16_to_cpu(*(u_short *)(p+2)) << 8;
+	    le16_to_cpu(*(__le16 *)(p+2)) << 8;
 	entry->mem.win[0].host_addr = 0;
 	p += 4;
 	if (p > q) return CS_BAD_TUPLE;
@@ -1140,7 +1140,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
     p = (u_char *)tuple->TupleData;
     bar->attr = *p;
     p += 2;
-    bar->size = le32_to_cpu(*(u_int *)p);
+    bar->size = le32_to_cpu(*(__le32 *)p);
     return CS_SUCCESS;
 }
 
@@ -1153,7 +1153,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
 	return CS_BAD_TUPLE;
     config->last_idx = *(++p);
     p++;
-    config->base = le32_to_cpu(*(u_int *)p);
+    config->base = le32_to_cpu(*(__le32 *)p);
     config->subtuples = tuple->TupleDataLen - 6;
     return CS_SUCCESS;
 }
@@ -1269,7 +1269,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
 
     v2->vers = p[0];
     v2->comply = p[1];
-    v2->dindex = le16_to_cpu(*(u_short *)(p+2));
+    v2->dindex = le16_to_cpu(*(__le16 *)(p+2));
     v2->vspec8 = p[6];
     v2->vspec9 = p[7];
     v2->nhdr = p[8];
@@ -1310,8 +1310,8 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
 
     fmt->type = p[0];
     fmt->edc = p[1];
-    fmt->offset = le32_to_cpu(*(u_int *)(p+2));
-    fmt->length = le32_to_cpu(*(u_int *)(p+6));
+    fmt->offset = le32_to_cpu(*(__le32 *)(p+2));
+    fmt->length = le32_to_cpu(*(__le32 *)(p+6));
 
     return CS_SUCCESS;
 }
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 7cf09084ef61..613f2f1fbfdd 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -309,41 +309,6 @@ struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr)
 }
 EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
 
-
-/**
- * socket_setup() and shutdown_socket() are called by the main event
- * handler when card insertion and removal events are received.
- * socket_setup() turns on socket power and resets the socket, in two stages.
- * shutdown_socket() unconfigures a socket and turns off socket power.
- */
-static void shutdown_socket(struct pcmcia_socket *s)
-{
-	cs_dbg(s, 1, "shutdown_socket\n");
-
-	/* Blank out the socket state */
-	s->socket = dead_socket;
-	s->ops->init(s);
-	s->ops->set_socket(s, &s->socket);
-	s->irq.AssignedIRQ = s->irq.Config = 0;
-	s->lock_count = 0;
-	destroy_cis_cache(s);
-#ifdef CONFIG_CARDBUS
-	cb_free(s);
-#endif
-	s->functions = 0;
-	kfree(s->config);
-	s->config = NULL;
-
-	{
-		int status;
-		s->ops->get_status(s, &status);
-		if (status & SS_POWERON) {
-			printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
-		}
-	}
-} /* shutdown_socket */
-
-
 /**
  * The central event handler.  Send_event() sends an event to the
  * 16-bit subsystem, which then calls the relevant device drivers.
@@ -383,17 +348,6 @@ static void socket_remove_drivers(struct pcmcia_socket *skt)
 	send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
 }
 
-static void socket_shutdown(struct pcmcia_socket *skt)
-{
-	cs_dbg(skt, 4, "shutdown\n");
-
-	socket_remove_drivers(skt);
-	skt->state &= SOCKET_INUSE|SOCKET_PRESENT;
-	msleep(shutdown_delay * 10);
-	skt->state &= SOCKET_INUSE;
-	shutdown_socket(skt);
-}
-
 static int socket_reset(struct pcmcia_socket *skt)
 {
 	int status, i;
@@ -424,6 +378,45 @@ static int socket_reset(struct pcmcia_socket *skt)
 	return CS_GENERAL_FAILURE;
 }
 
+/**
+ * socket_setup() and socket_shutdown() are called by the main event handler
+ * when card insertion and removal events are received.
+ * socket_setup() turns on socket power and resets the socket, in two stages.
+ * socket_shutdown() unconfigures a socket and turns off socket power.
+ */
+static void socket_shutdown(struct pcmcia_socket *s)
+{
+	int status;
+
+	cs_dbg(s, 4, "shutdown\n");
+
+	socket_remove_drivers(s);
+	s->state &= SOCKET_INUSE | SOCKET_PRESENT;
+	msleep(shutdown_delay * 10);
+	s->state &= SOCKET_INUSE;
+
+	/* Blank out the socket state */
+	s->socket = dead_socket;
+	s->ops->init(s);
+	s->ops->set_socket(s, &s->socket);
+	s->irq.AssignedIRQ = s->irq.Config = 0;
+	s->lock_count = 0;
+	destroy_cis_cache(s);
+#ifdef CONFIG_CARDBUS
+	cb_free(s);
+#endif
+	s->functions = 0;
+	kfree(s->config);
+	s->config = NULL;
+
+	s->ops->get_status(s, &status);
+	if (status & SS_POWERON) {
+		printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
+	}
+
+	cs_socket_put(s);
+}
+
 static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
 {
 	int status, i;
@@ -529,7 +522,6 @@ static int socket_insert(struct pcmcia_socket *skt)
 		send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
 	} else {
 		socket_shutdown(skt);
-		cs_socket_put(skt);
 	}
 
 	return ret;
@@ -593,7 +585,6 @@ static int socket_resume(struct pcmcia_socket *skt)
 		}
 	} else {
 		socket_shutdown(skt);
-		cs_socket_put(skt);
 	}
 
 	skt->state &= ~SOCKET_SUSPEND;
@@ -605,7 +596,6 @@ static void socket_remove(struct pcmcia_socket *skt)
 {
 	printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);
 	socket_shutdown(skt);
-	cs_socket_put(skt);
 }
 
 /*
@@ -780,8 +770,13 @@ int pccard_reset_card(struct pcmcia_socket *skt)
 		ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
 		if (ret == 0) {
 			send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
-			if (socket_reset(skt) == CS_SUCCESS)
+			if (skt->callback)
+				skt->callback->suspend(skt);
+			if (socket_reset(skt) == CS_SUCCESS) {
 				send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
+				if (skt->callback)
+					skt->callback->resume(skt);
+			}
 		}
 
 		ret = CS_SUCCESS;
@@ -812,6 +807,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
 			ret = CS_UNSUPPORTED_FUNCTION;
 			break;
 		}
+		if (skt->callback) {
+			ret = skt->callback->suspend(skt);
+			if (ret)
+				break;
+		}
 		ret = socket_suspend(skt);
 	} while (0);
 	up(&skt->skt_sem);
@@ -838,6 +838,8 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
 			break;
 		}
 		ret = socket_resume(skt);
+		if (!ret && skt->callback)
+			skt->callback->resume(skt);
 	} while (0);
 	up(&skt->skt_sem);
 
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 55867bc7f199..7b37eba35bf1 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -117,7 +117,7 @@ int verify_cis_cache(struct pcmcia_socket *s);
 int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);
 
 /* In rsrc_mgr */
-void pcmcia_validate_mem(struct pcmcia_socket *s);
+int pcmcia_validate_mem(struct pcmcia_socket *s);
 struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,
 		   struct pcmcia_socket *s);
 int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
@@ -143,6 +143,8 @@ struct pcmcia_callback{
 	struct module	*owner;
 	int		(*event) (struct pcmcia_socket *s, event_t event, int priority);
 	void		(*requery) (struct pcmcia_socket *s);
+	int		(*suspend) (struct pcmcia_socket *s);
+	int		(*resume) (struct pcmcia_socket *s);
 };
 
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 6fb76399547e..0252582b91cd 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -57,8 +57,6 @@ module_param_named(pc_debug, ds_pc_debug, int, 0644);
 
 spinlock_t pcmcia_dev_list_lock;
 
-static int unbind_request(struct pcmcia_socket *s);
-
 /*====================================================================*/
 
 /* code which was in cs.c before */
@@ -205,7 +203,7 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
 	unsigned int i;
 	u32 hash;
 
-	if (!p_drv->attach || !p_drv->event || !p_drv->detach)
+	if (!p_drv->probe || !p_drv->remove)
 		printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback "
 		       "function\n", p_drv->drv.name);
 
@@ -266,12 +264,10 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
 		if (fw->size >= CISTPL_MAX_CIS_SIZE)
 			goto release;
 
-		cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL);
+		cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
 		if (!cis)
 			goto release;
 
-		memset(cis, 0, sizeof(cisdump_t));
-
 		cis->Length = fw->size + 1;
 		memcpy(cis->Data, fw->data, fw->size);
 
@@ -363,6 +359,7 @@ static int pcmcia_device_probe(struct device * dev)
 {
 	struct pcmcia_device *p_dev;
 	struct pcmcia_driver *p_drv;
+	struct pcmcia_socket *s;
 	int ret = 0;
 
 	dev = get_device(dev);
@@ -371,25 +368,38 @@ static int pcmcia_device_probe(struct device * dev)
 
 	p_dev = to_pcmcia_dev(dev);
 	p_drv = to_pcmcia_drv(dev->driver);
+	s = p_dev->socket;
 
-	if (!try_module_get(p_drv->owner)) {
+	if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) {
 		ret = -EINVAL;
 		goto put_dev;
 	}
 
-	if (p_drv->attach) {
-		p_dev->instance = p_drv->attach();
-		if ((!p_dev->instance) || (p_dev->state & CLIENT_UNBOUND)) {
-			printk(KERN_NOTICE "ds: unable to create instance "
-			       "of '%s'!\n", p_drv->drv.name);
-			ret = -EINVAL;
+	p_dev->state &= ~CLIENT_UNBOUND;
+
+	/* set up the device configuration, if it hasn't been done before */
+	if (!s->functions) {
+		cistpl_longlink_mfc_t mfc;
+		if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC,
+				      &mfc) == CS_SUCCESS)
+			s->functions = mfc.nfn;
+		else
+			s->functions = 1;
+		s->config = kzalloc(sizeof(config_t) * s->functions,
+				    GFP_KERNEL);
+		if (!s->config) {
+			ret = -ENOMEM;
+			goto put_module;
 		}
 	}
 
+	ret = p_drv->probe(p_dev);
+
+ put_module:
 	if (ret)
 		module_put(p_drv->owner);
  put_dev:
-	if ((ret) || !(p_drv->attach))
+	if (ret)
 		put_device(dev);
 	return (ret);
 }
@@ -399,24 +409,66 @@ static int pcmcia_device_remove(struct device * dev)
 {
 	struct pcmcia_device *p_dev;
 	struct pcmcia_driver *p_drv;
+	int i;
 
 	/* detach the "instance" */
 	p_dev = to_pcmcia_dev(dev);
 	p_drv = to_pcmcia_drv(dev->driver);
+	if (!p_drv)
+		return 0;
 
-	if (p_drv) {
-		if ((p_drv->detach) && (p_dev->instance)) {
-			p_drv->detach(p_dev->instance);
-			/* from pcmcia_probe_device */
-			put_device(&p_dev->dev);
-		}
-		module_put(p_drv->owner);
-	}
+	if (p_drv->remove)
+	       	p_drv->remove(p_dev);
+
+	/* check for proper unloading */
+	if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
+		printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
+		       p_drv->drv.name);
+
+	for (i = 0; i < MAX_WIN; i++)
+		if (p_dev->state & CLIENT_WIN_REQ(i))
+			printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
+			       p_drv->drv.name);
+
+	/* references from pcmcia_probe_device */
+	p_dev->state = CLIENT_UNBOUND;
+	pcmcia_put_dev(p_dev);
+	module_put(p_drv->owner);
 
 	return 0;
 }
 
 
+/*
+ * Removes a PCMCIA card from the device tree and socket list.
+ */
+static void pcmcia_card_remove(struct pcmcia_socket *s)
+{
+	struct pcmcia_device	*p_dev;
+	unsigned long		flags;
+
+	ds_dbg(2, "unbind_request(%d)\n", s->sock);
+
+	s->device_count = 0;
+
+	for (;;) {
+		/* unregister all pcmcia_devices registered with this socket*/
+		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+		if (list_empty(&s->devices_list)) {
+			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ 			return;
+		}
+		p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
+		list_del(&p_dev->socket_device_list);
+		p_dev->state |= CLIENT_STALE;
+		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+
+		device_unregister(&p_dev->dev);
+	}
+
+	return;
+} /* unbind_request */
+
 
 /*
  * pcmcia_device_query -- determine information about a pcmcia device
@@ -517,10 +569,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
 	if (s->device_count == 2)
 		goto err_put;
 
-	p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
+	p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
 	if (!p_dev)
 		goto err_put;
-	memset(p_dev, 0, sizeof(struct pcmcia_device));
 
 	p_dev->socket = s;
 	p_dev->device_no = (s->device_count++);
@@ -583,7 +634,9 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
 	if (!(s->resource_setup_done))
 		return -EAGAIN; /* try again, but later... */
 
-	pcmcia_validate_mem(s);
+	if (pcmcia_validate_mem(s))
+		return -EAGAIN; /* try again, but later... */
+
 	ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo);
 	if (ret || !cisinfo.Chains) {
 		ds_dbg(0, "invalid CIS or invalid resources\n");
@@ -918,55 +971,84 @@ static struct device_attribute pcmcia_dev_attrs[] = {
 	__ATTR_NULL,
 };
 
+/* PM support, also needed for reset */
 
-/*======================================================================
+static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
+{
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	struct pcmcia_driver *p_drv = NULL;
 
-    The card status event handler.
-    
-======================================================================*/
+	if (dev->driver)
+		p_drv = to_pcmcia_drv(dev->driver);
 
-struct send_event_data {
-	struct pcmcia_socket *skt;
-	event_t event;
-	int priority;
-};
+	if (p_drv && p_drv->suspend)
+		return p_drv->suspend(p_dev);
+
+	return 0;
+}
 
-static int send_event_callback(struct device *dev, void * _data)
+
+static int pcmcia_dev_resume(struct device * dev)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
-	struct pcmcia_driver *p_drv;
-	struct send_event_data *data = _data;
+        struct pcmcia_driver *p_drv = NULL;
 
-	/* we get called for all sockets, but may only pass the event
-	 * for drivers _on the affected socket_ */
-	if (p_dev->socket != data->skt)
-		return 0;
+	if (dev->driver)
+		p_drv = to_pcmcia_drv(dev->driver);
 
-	p_drv = to_pcmcia_drv(p_dev->dev.driver);
-	if (!p_drv)
+	if (p_drv && p_drv->resume)
+		return p_drv->resume(p_dev);
+
+	return 0;
+}
+
+
+static int pcmcia_bus_suspend_callback(struct device *dev, void * _data)
+{
+	struct pcmcia_socket *skt = _data;
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+
+	if (p_dev->socket != skt)
 		return 0;
 
-	if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
+	return dpm_runtime_suspend(dev, PMSG_SUSPEND);
+}
+
+static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
+{
+	struct pcmcia_socket *skt = _data;
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+
+	if (p_dev->socket != skt)
 		return 0;
 
-	if (p_drv->event)
-		return p_drv->event(data->event, data->priority,
-				    &p_dev->event_callback_args);
+	dpm_runtime_resume(dev);
 
 	return 0;
 }
 
-static int send_event(struct pcmcia_socket *s, event_t event, int priority)
+static int pcmcia_bus_resume(struct pcmcia_socket *skt)
 {
-	struct send_event_data private;
+	bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
+	return 0;
+}
+
+static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
+{
+	if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
+			     pcmcia_bus_suspend_callback)) {
+		pcmcia_bus_resume(skt);
+		return -EIO;
+	}
+	return 0;
+}
 
-	private.skt = s;
-	private.event = event;
-	private.priority = priority;
 
-	return bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback);
-} /* send_event */
+/*======================================================================
 
+    The card status event handler.
+    
+======================================================================*/
 
 /* Normally, the event is passed to individual drivers after
  * informing userspace. Only for CS_EVENT_CARD_REMOVAL this
@@ -976,20 +1058,17 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)
 static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
 {
 	struct pcmcia_socket *s = pcmcia_get_socket(skt);
-	int ret = 0;
 
 	ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
 	       event, priority, skt);
-    
-	switch (event) {
 
+	switch (event) {
 	case CS_EVENT_CARD_REMOVAL:
 		s->pcmcia_state.present = 0;
-	    	send_event(skt, event, priority);
-		unbind_request(skt);
+		pcmcia_card_remove(skt);
 		handle_event(skt, event);
 		break;
-	
+
 	case CS_EVENT_CARD_INSERTION:
 		s->pcmcia_state.present = 1;
 		pcmcia_card_add(skt);
@@ -997,12 +1076,14 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
 		break;
 
 	case CS_EVENT_EJECTION_REQUEST:
-		ret = send_event(skt, event, priority);
 		break;
 
+	case CS_EVENT_PM_SUSPEND:
+	case CS_EVENT_PM_RESUME:
+	case CS_EVENT_RESET_PHYSICAL:
+	case CS_EVENT_CARD_RESET:
 	default:
 		handle_event(skt, event);
-		send_event(skt, event, priority);
 		break;
     }
 
@@ -1012,152 +1093,12 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
 } /* ds_event */
 
 
-
-int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req)
-{
-	struct pcmcia_socket *s = NULL;
-	struct pcmcia_device *p_dev = NULL;
-	struct pcmcia_driver *p_drv = NULL;
-
-	/* Look for unbound client with matching dev_info */
-	down_read(&pcmcia_socket_list_rwsem);
-	list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
-		unsigned long flags;
-
-		if (s->state & SOCKET_CARDBUS)
-			continue;
-
-		s = pcmcia_get_socket(s);
-		if (!s)
-			continue;
-		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
-		list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
-			p_dev = pcmcia_get_dev(p_dev);
-			if (!p_dev)
-				continue;
-			if (!(p_dev->state & CLIENT_UNBOUND) ||
-			    (!p_dev->dev.driver)) {
-				pcmcia_put_dev(p_dev);
-				continue;
-			}
-			p_drv = to_pcmcia_drv(p_dev->dev.driver);
-			if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) {
-				spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-				goto found;
-			}
-			pcmcia_put_dev(p_dev);
-		}
-		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-		pcmcia_put_socket(s);
-	}
- found:
-	up_read(&pcmcia_socket_list_rwsem);
-	if (!p_dev)
-		return -ENODEV;
-
-	pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */
-
-	*handle = p_dev;
-	p_dev->state &= ~CLIENT_UNBOUND;
-	p_dev->event_callback_args = req->event_callback_args;
-	p_dev->event_callback_args.client_handle = p_dev;
-
-
-	if (!s->functions) {
-		cistpl_longlink_mfc_t mfc;
-		if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc)
-		    == CS_SUCCESS)
-			s->functions = mfc.nfn;
-		else
-			s->functions = 1;
-		s->config = kmalloc(sizeof(config_t) * s->functions,
-				    GFP_KERNEL);
-		if (!s->config)
-			goto out_no_resource;
-		memset(s->config, 0, sizeof(config_t) * s->functions);
-	}
-
-	ds_dbg(1, "register_client(): client 0x%p, dev %s\n",
-	       p_dev, p_dev->dev.bus_id);
-
-	if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) {
-		if (p_drv->event)
-			p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW,
-				     &p_dev->event_callback_args);
-
-	}
-
-	return CS_SUCCESS;
-
- out_no_resource:
-	pcmcia_put_dev(p_dev);
-	return CS_OUT_OF_RESOURCE;
-} /* register_client */
-EXPORT_SYMBOL(pcmcia_register_client);
-
-
-/* unbind _all_ devices attached to a given pcmcia_bus_socket. The
- * drivers have been called with EVENT_CARD_REMOVAL before.
- */
-static int unbind_request(struct pcmcia_socket *s)
-{
-	struct pcmcia_device	*p_dev;
-	unsigned long		flags;
-
-	ds_dbg(2, "unbind_request(%d)\n", s->sock);
-
-	s->device_count = 0;
-
-	for (;;) {
-		/* unregister all pcmcia_devices registered with this socket*/
-		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
-		if (list_empty(&s->devices_list)) {
-			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
- 			return 0;
-		}
-		p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
-		list_del(&p_dev->socket_device_list);
-		p_dev->state |= CLIENT_STALE;
-		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-
-		device_unregister(&p_dev->dev);
-	}
-
-	return 0;
-} /* unbind_request */
-
-int pcmcia_deregister_client(struct pcmcia_device *p_dev)
-{
-	struct pcmcia_socket *s;
-	int i;
-
-	s = p_dev->socket;
-	ds_dbg(1, "deregister_client(%p)\n", p_dev);
-
-	if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
-		goto warn_out;
-	for (i = 0; i < MAX_WIN; i++)
-		if (p_dev->state & CLIENT_WIN_REQ(i))
-			goto warn_out;
-
-	if (p_dev->state & CLIENT_STALE) {
-		p_dev->state &= ~CLIENT_STALE;
-		pcmcia_put_dev(p_dev);
-	} else {
-		p_dev->state = CLIENT_UNBOUND;
-	}
-
-	return CS_SUCCESS;
- warn_out:
-	printk(KERN_WARNING "ds: deregister_client was called too early.\n");
-	return CS_IN_USE;
-} /* deregister_client */
-EXPORT_SYMBOL(pcmcia_deregister_client);
-
 static struct pcmcia_callback pcmcia_bus_callback = {
 	.owner = THIS_MODULE,
 	.event = ds_event,
 	.requery = pcmcia_bus_rescan,
+	.suspend = pcmcia_bus_suspend,
+	.resume = pcmcia_bus_resume,
 };
 
 static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
@@ -1226,6 +1167,8 @@ struct bus_type pcmcia_bus_type = {
 	.uevent = pcmcia_bus_uevent,
 	.match = pcmcia_bus_match,
 	.dev_attrs = pcmcia_dev_attrs,
+	.suspend = pcmcia_dev_suspend,
+	.resume = pcmcia_dev_resume,
 };
 
 
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index 561706ba4499..b39435bbfaeb 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -417,18 +417,6 @@ static int hs_get_status(struct pcmcia_socket *s, u_int *value)
 
 /*============================================================*/
 
-static int hs_get_socket(struct pcmcia_socket *s, socket_state_t *state)
-{
-    	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
-
-    	DPRINTK("hs_get_socket(%d)\n", sock);
-	
-	*state = sp->state;
-	return 0;
-}
-
-/*============================================================*/
-
 static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
     	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
@@ -749,7 +737,6 @@ static irqreturn_t hs_interrupt(int irq, void *dev, struct pt_regs *regs)
 static struct pccard_operations hs_operations = {
 	.init			= hs_init,
 	.get_status		= hs_get_status,
-	.get_socket		= hs_get_socket,
 	.set_socket		= hs_set_socket,
 	.set_io_map		= hs_set_io_map,
 	.set_mem_map		= hs_set_mem_map,
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index f3fdc748659d..7979c85df3dc 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -66,7 +66,6 @@ static struct pci_driver i82092aa_pci_drv = {
 static struct pccard_operations i82092aa_operations = {
 	.init 		 	= i82092aa_init,
 	.get_status		= i82092aa_get_status,
-	.get_socket		= i82092aa_get_socket,
 	.set_socket		= i82092aa_set_socket,
 	.set_io_map		= i82092aa_set_io_map,
 	.set_mem_map		= i82092aa_set_mem_map,
@@ -482,78 +481,6 @@ static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value)
 }
 
 
-static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state) 
-{
-	unsigned int sock = container_of(socket, struct socket_info, socket)->number;
-	unsigned char reg,vcc,vpp;
-	
-	enter("i82092aa_get_socket");
-	state->flags    = 0;
-	state->Vcc      = 0;
-	state->Vpp      = 0;
-	state->io_irq   = 0;
-	state->csc_mask = 0;
-
-	/* First the power status of the socket */
-	reg = indirect_read(sock,I365_POWER); /* PCTRL - Power Control Register */
-
-	if (reg & I365_PWR_AUTO)
-		state->flags |= SS_PWR_AUTO;  /* Automatic Power Switch */
-		
-	if (reg & I365_PWR_OUT)
-		state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */
-		
-	vcc = reg & I365_VCC_MASK;    vpp = reg & I365_VPP1_MASK;
-	
-	if (reg & I365_VCC_5V) { /* Can still be 3.3V, in this case the Vcc value will be overwritten later */
-		state->Vcc = 50;
-		
-		if (vpp == I365_VPP1_5V)
-			state->Vpp = 50;
-		if (vpp == I365_VPP1_12V)
-			state->Vpp = 120;
-			
-	}
-	
-	if ((reg & I365_VCC_3V)==I365_VCC_3V)
-		state->Vcc = 33;
-	
-	
-	/* Now the IO card, RESET flags and IO interrupt */
-	
-	reg = indirect_read(sock, I365_INTCTL); /* IGENC, Interrupt and General Control */
-	
-	if ((reg & I365_PC_RESET)==0)
-		state->flags |= SS_RESET;
-	if (reg & I365_PC_IOCARD) 
-		state->flags |= SS_IOCARD; /* This is an IO card */
-	
-	/* Set the IRQ number */
-	if (sockets[sock].dev!=NULL)
-		state->io_irq = sockets[sock].dev->irq;
-	
-	/* Card status change */
-	reg = indirect_read(sock, I365_CSCINT); /* CSCICR, Card Status Change Interrupt Configuration */
-	
-	if (reg & I365_CSC_DETECT) 
-		state->csc_mask |= SS_DETECT; /* Card detect is enabled */
-	
-	if (state->flags & SS_IOCARD) {/* IO Cards behave different */
-		if (reg & I365_CSC_STSCHG)
-			state->csc_mask |= SS_STSCHG;
-	} else {
-		if (reg & I365_CSC_BVD1) 
-			state->csc_mask |= SS_BATDEAD;
-		if (reg & I365_CSC_BVD2) 
-			state->csc_mask |= SS_BATWARN;
-		if (reg & I365_CSC_READY) 
-			state->csc_mask |= SS_READY;
-	}
-		
-	leave("i82092aa_get_socket");
-	return 0;
-}
-
 static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state) 
 {
 	unsigned int sock = container_of(socket, struct socket_info, socket)->number;
diff --git a/drivers/pcmcia/i82092aa.h b/drivers/pcmcia/i82092aa.h
index b98cac7bda9f..9c14599d0673 100644
--- a/drivers/pcmcia/i82092aa.h
+++ b/drivers/pcmcia/i82092aa.h
@@ -29,7 +29,6 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs);
 
 
 static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value);
-static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state);
 static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state);
 static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io);
 static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 4d56bc9926d6..35a92d1e4945 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -940,78 +940,6 @@ static int i365_get_status(u_short sock, u_int *value)
 
 /*====================================================================*/
 
-static int i365_get_socket(u_short sock, socket_state_t *state)
-{
-    struct i82365_socket *t = &socket[sock];
-    u_char reg, vcc, vpp;
-    
-    reg = i365_get(sock, I365_POWER);
-    state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
-    state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
-    vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;
-    state->Vcc = state->Vpp = 0;
-    if (t->flags & IS_CIRRUS) {
-	if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) {
-	    if (reg & I365_VCC_5V) state->Vcc = 33;
-	    if (vpp == I365_VPP1_5V) state->Vpp = 33;
-	} else {
-	    if (reg & I365_VCC_5V) state->Vcc = 50;
-	    if (vpp == I365_VPP1_5V) state->Vpp = 50;
-	}
-	if (vpp == I365_VPP1_12V) state->Vpp = 120;
-    } else if (t->flags & IS_VG_PWR) {
-	if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) {
-	    if (reg & I365_VCC_5V) state->Vcc = 33;
-	    if (vpp == I365_VPP1_5V) state->Vpp = 33;
-	} else {
-	    if (reg & I365_VCC_5V) state->Vcc = 50;
-	    if (vpp == I365_VPP1_5V) state->Vpp = 50;
-	}
-	if (vpp == I365_VPP1_12V) state->Vpp = 120;
-    } else if (t->flags & IS_DF_PWR) {
-	if (vcc == I365_VCC_3V) state->Vcc = 33;
-	if (vcc == I365_VCC_5V) state->Vcc = 50;
-	if (vpp == I365_VPP1_5V) state->Vpp = 50;
-	if (vpp == I365_VPP1_12V) state->Vpp = 120;
-    } else {
-	if (reg & I365_VCC_5V) {
-	    state->Vcc = 50;
-	    if (vpp == I365_VPP1_5V) state->Vpp = 50;
-	    if (vpp == I365_VPP1_12V) state->Vpp = 120;
-	}
-    }
-
-    /* IO card, RESET flags, IO interrupt */
-    reg = i365_get(sock, I365_INTCTL);
-    state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
-    if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD;
-    state->io_irq = reg & I365_IRQ_MASK;
-    
-    /* speaker control */
-    if (t->flags & IS_CIRRUS) {
-	if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA)
-	    state->flags |= SS_SPKR_ENA;
-    }
-    
-    /* Card status change mask */
-    reg = i365_get(sock, I365_CSCINT);
-    state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
-    if (state->flags & SS_IOCARD)
-	state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
-    else {
-	state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-	state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
-	state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
-    }
-    
-    debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
-	  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
-	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-    return 0;
-} /* i365_get_socket */
-
-/*====================================================================*/
-
 static int i365_set_socket(u_short sock, socket_state_t *state)
 {
     struct i82365_socket *t = &socket[sock];
@@ -1265,16 +1193,6 @@ static int pcic_get_status(struct pcmcia_socket *s, u_int *value)
 	LOCKED(i365_get_status(sock, value));
 }
 
-static int pcic_get_socket(struct pcmcia_socket *s, socket_state_t *state)
-{
-	unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
-
-	if (socket[sock].flags & IS_ALIVE)
-		return -EINVAL;
-
-	LOCKED(i365_get_socket(sock, state));
-}
-
 static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
 	unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
@@ -1324,7 +1242,6 @@ static int pcic_init(struct pcmcia_socket *s)
 static struct pccard_operations pcic_operations = {
 	.init			= pcic_init,
 	.get_status		= pcic_get_status,
-	.get_socket		= pcic_get_socket,
 	.set_socket		= pcic_set_socket,
 	.set_io_map		= pcic_set_io_map,
 	.set_mem_map		= pcic_set_mem_map,
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 078579ae6359..071cf485e1a3 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -480,25 +480,6 @@ static int _pcc_get_status(u_short sock, u_int *value)
 
 /*====================================================================*/
 
-static int _pcc_get_socket(u_short sock, socket_state_t *state)
-{
-//	pcc_socket_t *t = &socket[sock];
-
-	state->flags = 0;
-	state->csc_mask = SS_DETECT;
-	state->csc_mask |= SS_READY;
-	state->io_irq = 0;
-	state->Vcc = 33;	/* 3.3V fixed */
-	state->Vpp = 33;
-
-	debug(3, "m32r_cfc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
-		  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
-		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-	return 0;
-} /* _get_socket */
-
-/*====================================================================*/
-
 static int _pcc_set_socket(u_short sock, socket_state_t *state)
 {
 	debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
@@ -667,18 +648,6 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
 	LOCKED(_pcc_get_status(sock, value));
 }
 
-static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state)
-{
-	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
-
-	if (socket[sock].flags & IS_ALIVE) {
-		debug(3, "m32r_cfc: pcc_get_socket: sock(%d) -EINVAL\n", sock);
-		return -EINVAL;
-	}
-	debug(3, "m32r_cfc: pcc_get_socket: sock(%d)\n", sock);
-	LOCKED(_pcc_get_socket(sock, state));
-}
-
 static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
@@ -724,7 +693,6 @@ static int pcc_init(struct pcmcia_socket *s)
 static struct pccard_operations pcc_operations = {
 	.init			= pcc_init,
 	.get_status		= pcc_get_status,
-	.get_socket		= pcc_get_socket,
 	.set_socket		= pcc_set_socket,
 	.set_io_map		= pcc_set_io_map,
 	.set_mem_map		= pcc_set_mem_map,
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 356a6fb416a1..70d5f0748d55 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -429,16 +429,6 @@ static int _pcc_get_status(u_short sock, u_int *value)
 
 /*====================================================================*/
 
-static int _pcc_get_socket(u_short sock, socket_state_t *state)
-{
-	debug(3, "m32r-pcc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
-		  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
-		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-	return 0;
-} /* _get_socket */
-
-/*====================================================================*/
-
 static int _pcc_set_socket(u_short sock, socket_state_t *state)
 {
 	u_long reg = 0;
@@ -641,15 +631,6 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
 	LOCKED(_pcc_get_status(sock, value));
 }
 
-static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state)
-{
-	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
-
-	if (socket[sock].flags & IS_ALIVE)
-		return -EINVAL;
-	LOCKED(_pcc_get_socket(sock, state));
-}
-
 static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
@@ -687,7 +668,6 @@ static int pcc_init(struct pcmcia_socket *s)
 static struct pccard_operations pcc_operations = {
 	.init			= pcc_init,
 	.get_status		= pcc_get_status,
-	.get_socket		= pcc_get_socket,
 	.set_socket		= pcc_set_socket,
 	.set_io_map		= pcc_set_io_map,
 	.set_mem_map		= pcc_set_mem_map,
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 6d9f71cfcb34..0e07d9535116 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -9,6 +9,9 @@
  *     <oliver.kurth@cyclades.de>
  * Further fixes, v2.6 kernel port
  *     <marcelo.tosatti@cyclades.com>
+ * 
+ * Some fixes, additions (C) 2005 Montavista Software, Inc. 
+ *     <vbordug@ru.mvista.com>
  *
  * "The ExCA standard specifies that socket controllers should provide
  * two IO and five memory windows per socket, which can be independently
@@ -97,6 +100,11 @@ MODULE_LICENSE("Dual MPL/GPL");
 #endif
 #endif
 
+#if defined(CONFIG_MPC885ADS)
+#define CONFIG_PCMCIA_SLOT_A
+#define PCMCIA_GLITCHY_CD
+#endif
+
 /* Cyclades ACS uses both slots */
 #ifdef CONFIG_PRxK
 #define CONFIG_PCMCIA_SLOT_A
@@ -374,10 +382,10 @@ static int voltage_set(int slot, int vcc, int vpp)
 	}
 
 	/* first, turn off all power */
-	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
+	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
 
 	/* enable new powersettings */
-	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | reg);
+	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | reg);
 
 	return 0;
 }
@@ -386,12 +394,89 @@ static int voltage_set(int slot, int vcc, int vpp)
 
 static void hardware_enable(int slot)
 {
-	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~BCSR1_PCCEN);
+	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~BCSR1_PCCEN);
 }
 
 static void hardware_disable(int slot)
 {
-	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) |  BCSR1_PCCEN);
+	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) |  BCSR1_PCCEN);
+}
+
+#endif
+
+/* MPC885ADS Boards */
+
+#if defined(CONFIG_MPC885ADS)
+
+#define PCMCIA_BOARD_MSG "MPC885ADS"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	u32 reg = 0;
+	unsigned *bcsr_io;
+
+	bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+	switch(vcc) {
+		case 0:
+			break;
+		case 33:
+			reg |= BCSR1_PCCVCC0;
+			break;
+		case 50:
+			reg |= BCSR1_PCCVCC1;
+			break;
+		default:
+			return 1;
+	}
+
+	switch(vpp) {
+		case 0:
+			break;
+		case 33:
+		case 50:
+			if(vcc == vpp)
+				reg |= BCSR1_PCCVPP1;
+			else
+				return 1;
+			break;
+		case 120:
+			if ((vcc == 33) || (vcc == 50))
+				reg |= BCSR1_PCCVPP0;
+			else
+				return 1;
+		default:
+			return 1;
+	}
+
+	/* first, turn off all power */
+	out_be32(bcsr_io, in_be32(bcsr_io) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
+
+	/* enable new powersettings */
+	out_be32(bcsr_io, in_be32(bcsr_io) | reg);
+
+	iounmap(bcsr_io);
+	return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+
+static void hardware_enable(int slot)
+{
+	unsigned *bcsr_io;
+
+	bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+	out_be32(bcsr_io, in_be32(bcsr_io) & ~BCSR1_PCCEN);
+	iounmap(bcsr_io);
+}
+
+static void hardware_disable(int slot)
+{
+	unsigned *bcsr_io;
+
+	bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+	out_be32(bcsr_io, in_be32(bcsr_io) |  BCSR1_PCCEN);
+	iounmap(bcsr_io);
 }
 
 #endif
@@ -440,10 +525,10 @@ static int voltage_set(int slot, int vcc, int vpp)
 	}
 
 	/* first, turn off all power */
-	out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
+	out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
 
 	/* enable new powersettings */
-	out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) | reg);
+	out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) | reg);
 
 	return 0;
 }
@@ -823,17 +908,6 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
 	return 0;
 }
 
-static int m8xx_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	int lsock = container_of(sock, struct socket_info, socket)->slot;
-	*state = socket[lsock].state; /* copy the whole structure */
-
-	dprintk("GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
-	      "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
-	      state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-	return 0;
-}
-
 static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
 {
 	int lsock = container_of(sock, struct socket_info, socket)->slot;
@@ -1023,8 +1097,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
 		if(io->flags & MAP_WRPROT)
 			reg |= M8XX_PCMCIA_POR_WRPROT;
 
-		/*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
-		if(io->flags & MAP_16BIT)
+		if(io->flags & (MAP_16BIT | MAP_AUTOSZ))
 			reg |= M8XX_PCMCIA_POR_16BIT;
 
 		if(io->flags & MAP_ACTIVE)
@@ -1169,7 +1242,6 @@ static struct pccard_operations m8xx_services = {
 	.init	= m8xx_sock_init,
 	.suspend = m8xx_suspend,
 	.get_status = m8xx_get_status,
-	.get_socket = m8xx_get_socket,
 	.set_socket = m8xx_set_socket,
 	.set_io_map = m8xx_set_io_map,
 	.set_mem_map = m8xx_set_mem_map,
@@ -1244,7 +1316,7 @@ static int __init m8xx_init(void)
 		socket[i].socket.io_offset = 0;
 		socket[i].socket.pci_irq = i  ? 7 : 9;
 		socket[i].socket.ops = &m8xx_services;
-		socket[i].socket.resource_ops = &pccard_nonstatic_ops;
+		socket[i].socket.resource_ops = &pccard_iodyn_ops;
 		socket[i].socket.cb_dev = NULL;
 		socket[i].socket.dev.dev = &m8xx_device.dev;
 	}
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index 20642f0e7bfe..f2789afb22b2 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -304,75 +304,6 @@ static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value)
 }
 
 
-static int pd6729_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	struct pd6729_socket *socket
-			= container_of(sock, struct pd6729_socket, socket);
-	unsigned char reg, vcc, vpp;
-
-	state->flags    = 0;
-	state->Vcc      = 0;
-	state->Vpp      = 0;
-	state->io_irq   = 0;
-	state->csc_mask = 0;
-
-	/* First the power status of the socket */
-	reg = indirect_read(socket, I365_POWER);
-
-	if (reg & I365_PWR_AUTO)
-		state->flags |= SS_PWR_AUTO;  /* Automatic Power Switch */
-
-	if (reg & I365_PWR_OUT)
-		state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */
-
-	vcc = reg & I365_VCC_MASK;    vpp = reg & I365_VPP1_MASK;
-
-	if (reg & I365_VCC_5V) {
-		state->Vcc = (indirect_read(socket, PD67_MISC_CTL_1) &
-			PD67_MC1_VCC_3V) ? 33 : 50;
-
-		if (vpp == I365_VPP1_5V) {
-			if (state->Vcc == 50)
-				state->Vpp = 50;
-			else
-				state->Vpp = 33;
-		}
-		if (vpp == I365_VPP1_12V)
-			state->Vpp = 120;
-	}
-
-	/* Now the IO card, RESET flags and IO interrupt */
-	reg = indirect_read(socket, I365_INTCTL);
-
-	if ((reg & I365_PC_RESET) == 0)
-		state->flags |= SS_RESET;
-	if (reg & I365_PC_IOCARD)
-		state->flags |= SS_IOCARD; /* This is an IO card */
-
-	/* Set the IRQ number */
-	state->io_irq = socket->card_irq;
-
-	/* Card status change */
-	reg = indirect_read(socket, I365_CSCINT);
-
-	if (reg & I365_CSC_DETECT)
-		state->csc_mask |= SS_DETECT; /* Card detect is enabled */
-
-	if (state->flags & SS_IOCARD) {/* IO Cards behave different */
-		if (reg & I365_CSC_STSCHG)
-			state->csc_mask |= SS_STSCHG;
-	} else {
-		if (reg & I365_CSC_BVD1)
-			state->csc_mask |= SS_BATDEAD;
-		if (reg & I365_CSC_BVD2)
-			state->csc_mask |= SS_BATWARN;
-		if (reg & I365_CSC_READY)
-			state->csc_mask |= SS_READY;
-	}
-
-	return 0;
-}
-
 static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
 {
 	struct pd6729_socket *socket
@@ -640,7 +571,6 @@ static int pd6729_init(struct pcmcia_socket *sock)
 static struct pccard_operations pd6729_operations = {
 	.init 			= pd6729_init,
 	.get_status		= pd6729_get_status,
-	.get_socket		= pd6729_get_socket,
 	.set_socket		= pd6729_set_socket,
 	.set_io_map		= pd6729_set_io_map,
 	.set_mem_map		= pd6729_set_mem_map,
@@ -704,13 +634,11 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
 	char configbyte;
 	struct pd6729_socket *socket;
 
-	socket = kmalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,
+	socket = kzalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,
 			 GFP_KERNEL);
 	if (!socket)
 		return -ENOMEM;
 
-	memset(socket, 0, sizeof(struct pd6729_socket) * MAX_SOCKETS);
-
 	if ((ret = pci_enable_device(dev)))
 		goto err_out_free_mem;
 
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 5209d8c7764f..5d957dfe23d9 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -171,10 +171,9 @@ static int __init mst_pcmcia_init(void)
 {
 	int ret;
 
-	mst_pcmcia_device = kmalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL);
+	mst_pcmcia_device = kzalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL);
 	if (!mst_pcmcia_device)
 		return -ENOMEM;
-	memset(mst_pcmcia_device, 0, sizeof(*mst_pcmcia_device));
 	mst_pcmcia_device->name = "pxa2xx-pcmcia";
 	mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops;
 
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 56c58831e80e..b5fdeec20b15 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -264,11 +264,10 @@ static int __init sharpsl_pcmcia_init(void)
 	int ret;
 
 	sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
-	sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
+	sharpsl_pcmcia_device = kzalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
 	if (!sharpsl_pcmcia_device)
 		return -ENOMEM;
 
-	memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
 	sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
 	sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
 	sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index 0668384ebc8b..514609369836 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -98,10 +98,12 @@ int pcmcia_adjust_resource_info(adjust_t *adj)
 }
 EXPORT_SYMBOL(pcmcia_adjust_resource_info);
 
-void pcmcia_validate_mem(struct pcmcia_socket *s)
+int pcmcia_validate_mem(struct pcmcia_socket *s)
 {
 	if (s->resource_ops->validate_mem)
-		s->resource_ops->validate_mem(s);
+		return s->resource_ops->validate_mem(s);
+	/* if there is no callback, we can assume that everything is OK */
+	return 0;
 }
 EXPORT_SYMBOL(pcmcia_validate_mem);
 
@@ -164,3 +166,105 @@ struct pccard_resource_ops pccard_static_ops = {
 	.exit = NULL,
 };
 EXPORT_SYMBOL(pccard_static_ops);
+
+
+#ifdef CONFIG_PCCARD_IODYN
+
+static struct resource *
+make_resource(unsigned long b, unsigned long n, int flags, char *name)
+{
+	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
+
+	if (res) {
+		res->name = name;
+		res->start = b;
+		res->end = b + n - 1;
+		res->flags = flags;
+	}
+	return res;
+}
+
+struct pcmcia_align_data {
+	unsigned long	mask;
+	unsigned long	offset;
+};
+
+static void pcmcia_align(void *align_data, struct resource *res,
+			unsigned long size, unsigned long align)
+{
+	struct pcmcia_align_data *data = align_data;
+	unsigned long start;
+
+	start = (res->start & ~data->mask) + data->offset;
+	if (start < res->start)
+		start += data->mask + 1;
+	res->start = start;
+
+#ifdef CONFIG_X86
+        if (res->flags & IORESOURCE_IO) {
+                if (start & 0x300) {
+                        start = (start + 0x3ff) & ~0x3ff;
+                        res->start = start;
+                }
+        }
+#endif
+
+#ifdef CONFIG_M68K
+        if (res->flags & IORESOURCE_IO) {
+		if ((res->start + size - 1) >= 1024)
+			res->start = res->end;
+	}
+#endif
+}
+
+
+static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start,
+				      unsigned long r_end, struct pcmcia_socket *s)
+{
+	return adjust_resource(res, r_start, r_end - r_start + 1);
+}
+
+
+static struct resource *iodyn_find_io_region(unsigned long base, int num,
+		unsigned long align, struct pcmcia_socket *s)
+{
+	struct resource *res = make_resource(0, num, IORESOURCE_IO,
+					     s->dev.class_id);
+	struct pcmcia_align_data data;
+	unsigned long min = base;
+	int ret;
+
+	if (align == 0)
+		align = 0x10000;
+
+	data.mask = align - 1;
+	data.offset = base & data.mask;
+
+#ifdef CONFIG_PCI
+	if (s->cb_dev) {
+		ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
+					     min, 0, pcmcia_align, &data);
+	} else
+#endif
+		ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
+					1, pcmcia_align, &data);
+
+	if (ret != 0) {
+		kfree(res);
+		res = NULL;
+	}
+	return res;
+}
+
+struct pccard_resource_ops pccard_iodyn_ops = {
+	.validate_mem = NULL,
+	.adjust_io_region = iodyn_adjust_io_region,
+	.find_io = iodyn_find_io_region,
+	.find_mem = NULL,
+	.adjust_resource = NULL,
+	.init = static_init,
+	.exit = NULL,
+};
+EXPORT_SYMBOL(pccard_iodyn_ops);
+
+#endif /* CONFIG_PCCARD_IODYN */
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 00960a379b9c..5301ac60358f 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -75,10 +75,9 @@ static DECLARE_MUTEX(rsrc_sem);
 static struct resource *
 make_resource(unsigned long b, unsigned long n, int flags, char *name)
 {
-	struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
+	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
 	if (res) {
-		memset(res, 0, sizeof(*res));
 		res->name = name;
 		res->start = b;
 		res->end = b + n - 1;
@@ -200,12 +199,11 @@ static void do_io_probe(struct pcmcia_socket *s, kio_addr_t base, kio_addr_t num
 	   base, base+num-1);
 
     /* First, what does a floating port look like? */
-    b = kmalloc(256, GFP_KERNEL);
+    b = kzalloc(256, GFP_KERNEL);
     if (!b) {
             printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
             return;
     }
-    memset(b, 0, 256);
     for (i = base, most = 0; i < base+num; i += 8) {
 	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
 	if (!res)
@@ -407,69 +405,79 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
 
 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
 {
-    struct socket_data *s_data = s->resource_data;
-    u_long ok;
-    if (m == &s_data->mem_db)
-	return 0;
-    ok = inv_probe(m->next, s);
-    if (ok) {
-	if (m->base >= 0x100000)
-	    sub_interval(&s_data->mem_db, m->base, m->num);
-	return ok;
-    }
-    if (m->base < 0x100000)
-	return 0;
-    return do_mem_probe(m->base, m->num, s);
+	struct socket_data *s_data = s->resource_data;
+	u_long ok;
+	if (m == &s_data->mem_db)
+		return 0;
+	ok = inv_probe(m->next, s);
+	if (ok) {
+		if (m->base >= 0x100000)
+			sub_interval(&s_data->mem_db, m->base, m->num);
+		return ok;
+	}
+	if (m->base < 0x100000)
+		return 0;
+	return do_mem_probe(m->base, m->num, s);
 }
 
-static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
+static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 {
-    struct resource_map *m, mm;
-    static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
-    u_long b, i, ok = 0;
-    struct socket_data *s_data = s->resource_data;
+	struct resource_map *m, mm;
+	static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
+	unsigned long b, i, ok = 0;
+	struct socket_data *s_data = s->resource_data;
 
-    /* We do up to four passes through the list */
-    if (probe_mask & MEM_PROBE_HIGH) {
-	if (inv_probe(s_data->mem_db.next, s) > 0)
-	    return;
-	printk(KERN_NOTICE "cs: warning: no high memory space "
-	       "available!\n");
-    }
-    if ((probe_mask & MEM_PROBE_LOW) == 0)
-	return;
-    for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
-	mm = *m;
-	/* Only probe < 1 MB */
-	if (mm.base >= 0x100000) continue;
-	if ((mm.base | mm.num) & 0xffff) {
-	    ok += do_mem_probe(mm.base, mm.num, s);
-	    continue;
+	/* We do up to four passes through the list */
+	if (probe_mask & MEM_PROBE_HIGH) {
+		if (inv_probe(s_data->mem_db.next, s) > 0)
+			return 0;
+		printk(KERN_NOTICE "cs: warning: no high memory space "
+		       "available!\n");
+		return -ENODEV;
 	}
-	/* Special probe for 64K-aligned block */
-	for (i = 0; i < 4; i++) {
-	    b = order[i] << 12;
-	    if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
-		if (ok >= mem_limit)
-		    sub_interval(&s_data->mem_db, b, 0x10000);
-		else
-		    ok += do_mem_probe(b, 0x10000, s);
-	    }
+
+	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
+		mm = *m;
+		/* Only probe < 1 MB */
+		if (mm.base >= 0x100000)
+			continue;
+		if ((mm.base | mm.num) & 0xffff) {
+			ok += do_mem_probe(mm.base, mm.num, s);
+			continue;
+		}
+		/* Special probe for 64K-aligned block */
+		for (i = 0; i < 4; i++) {
+			b = order[i] << 12;
+			if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
+				if (ok >= mem_limit)
+					sub_interval(&s_data->mem_db, b, 0x10000);
+				else
+					ok += do_mem_probe(b, 0x10000, s);
+			}
+		}
 	}
-    }
+
+	if (ok > 0)
+		return 0;
+
+	return -ENODEV;
 }
 
 #else /* CONFIG_PCMCIA_PROBE */
 
-static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
+static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 {
 	struct resource_map *m, mm;
 	struct socket_data *s_data = s->resource_data;
+	unsigned long ok = 0;
 
 	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
 		mm = *m;
-		do_mem_probe(mm.base, mm.num, s);
+		ok += do_mem_probe(mm.base, mm.num, s);
 	}
+	if (ok > 0)
+		return 0;
+	return -ENODEV;
 }
 
 #endif /* CONFIG_PCMCIA_PROBE */
@@ -478,27 +486,30 @@ static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 /*
  * Locking note: Must be called with skt_sem held!
  */
-static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
+static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
 {
 	struct socket_data *s_data = s->resource_data;
-	if (probe_mem) {
-		unsigned int probe_mask;
+	unsigned int probe_mask = MEM_PROBE_LOW;
+	int ret = 0;
 
-		down(&rsrc_sem);
+	if (!probe_mem)
+		return 0;
 
-		probe_mask = MEM_PROBE_LOW;
-		if (s->features & SS_CAP_PAGE_REGS)
-			probe_mask = MEM_PROBE_HIGH;
+	down(&rsrc_sem);
 
-		if (probe_mask & ~s_data->rsrc_mem_probe) {
+	if (s->features & SS_CAP_PAGE_REGS)
+		probe_mask = MEM_PROBE_HIGH;
+
+	if (probe_mask & ~s_data->rsrc_mem_probe) {
+		if (s->state & SOCKET_PRESENT)
+			ret = validate_mem(s, probe_mask);
+		if (!ret)
 			s_data->rsrc_mem_probe |= probe_mask;
+	}
 
-			if (s->state & SOCKET_PRESENT)
-				validate_mem(s, probe_mask);
-		}
+	up(&rsrc_sem);
 
-		up(&rsrc_sem);
-	}
+	return ret;
 }
 
 struct pcmcia_align_data {
@@ -837,10 +848,9 @@ static int nonstatic_init(struct pcmcia_socket *s)
 {
 	struct socket_data *data;
 
-	data = kmalloc(sizeof(struct socket_data), GFP_KERNEL);
+	data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
-	memset(data, 0, sizeof(struct socket_data));
 
 	data->mem_db.next = &data->mem_db;
 	data->io_db.next = &data->io_db;
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 9e7ccd8a4321..ea7d9ca160b2 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -297,25 +297,6 @@ soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
 
 
 /*
- * Implements the get_socket() operation for the in-kernel PCMCIA
- * service (formerly SS_GetSocket in Card Services). Not a very
- * exciting routine.
- *
- * Returns: 0
- */
-static int
-soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
-
-	debug(skt, 2, "\n");
-
-	*state = skt->cs_state;
-
-	return 0;
-}
-
-/*
  * Implements the set_socket() operation for the in-kernel PCMCIA
  * service (formerly SS_SetSocket in Card Services). We more or
  * less punt all of this work and let the kernel handle the details
@@ -528,7 +509,6 @@ static struct pccard_operations soc_common_pcmcia_operations = {
 	.init			= soc_common_pcmcia_sock_init,
 	.suspend		= soc_common_pcmcia_suspend,
 	.get_status		= soc_common_pcmcia_get_status,
-	.get_socket		= soc_common_pcmcia_get_socket,
 	.set_socket		= soc_common_pcmcia_set_socket,
 	.set_io_map		= soc_common_pcmcia_set_io_map,
 	.set_mem_map		= soc_common_pcmcia_set_mem_map,
@@ -665,13 +645,12 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
 
 	down(&soc_pcmcia_sockets_lock);
 
-	sinfo = kmalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
+	sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
 	if (!sinfo) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
-	memset(sinfo, 0, SKT_DEV_INFO_SIZE(nr));
 	sinfo->nskt = nr;
 
 	/*
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 4a3150a7854c..7a7744662d54 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -42,35 +42,28 @@
 
 static ssize_t pccard_show_type(struct class_device *dev, char *buf)
 {
-	int val;
 	struct pcmcia_socket *s = to_socket(dev);
 
 	if (!(s->state & SOCKET_PRESENT))
 		return -ENODEV;
-	s->ops->get_status(s, &val);
-	if (val & SS_CARDBUS)
+	if (s->state & SOCKET_CARDBUS)
 		return sprintf(buf, "32-bit\n");
-	if (val & SS_DETECT)
-		return sprintf(buf, "16-bit\n");
-	return sprintf(buf, "invalid\n");
+	return sprintf(buf, "16-bit\n");
 }
-static CLASS_DEVICE_ATTR(card_type, 0400, pccard_show_type, NULL);
+static CLASS_DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL);
 
 static ssize_t pccard_show_voltage(struct class_device *dev, char *buf)
 {
-	int val;
 	struct pcmcia_socket *s = to_socket(dev);
 
 	if (!(s->state & SOCKET_PRESENT))
 		return -ENODEV;
-	s->ops->get_status(s, &val);
-	if (val & SS_3VCARD)
-		return sprintf(buf, "3.3V\n");
-	if (val & SS_XVCARD)
-		return sprintf(buf, "X.XV\n");
-	return sprintf(buf, "5.0V\n");
+	if (s->socket.Vcc)
+		return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10,
+			       s->socket.Vcc % 10);
+	return sprintf(buf, "X.XV\n");
 }
-static CLASS_DEVICE_ATTR(card_voltage, 0400, pccard_show_voltage, NULL);
+static CLASS_DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL);
 
 static ssize_t pccard_show_vpp(struct class_device *dev, char *buf)
 {
@@ -79,7 +72,7 @@ static ssize_t pccard_show_vpp(struct class_device *dev, char *buf)
 		return -ENODEV;
 	return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10);
 }
-static CLASS_DEVICE_ATTR(card_vpp, 0400, pccard_show_vpp, NULL);
+static CLASS_DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL);
 
 static ssize_t pccard_show_vcc(struct class_device *dev, char *buf)
 {
@@ -88,7 +81,7 @@ static ssize_t pccard_show_vcc(struct class_device *dev, char *buf)
 		return -ENODEV;
 	return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10);
 }
-static CLASS_DEVICE_ATTR(card_vcc, 0400, pccard_show_vcc, NULL);
+static CLASS_DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);
 
 
 static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count)
@@ -292,10 +285,9 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
 	if (!(s->state & SOCKET_PRESENT))
 		return -ENODEV;
 
-	cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL);
+	cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
 	if (!cis)
 		return -ENOMEM;
-	memset(cis, 0, sizeof(cisdump_t));
 
 	cis->Length = count + 1;
 	memcpy(cis->Data, buf, count);
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index e31263864377..73bad1d5cb23 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -181,13 +181,6 @@ static void tcic_setl(u_char reg, u_int data)
     outw(data >> 16, tcic_base+reg+2);
 }
 
-static u_char tcic_aux_getb(u_short reg)
-{
-    u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
-    tcic_setb(TCIC_MODE, mode);
-    return tcic_getb(TCIC_AUX);
-}
-
 static void tcic_aux_setb(u_short reg, u_char data)
 {
     u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
@@ -641,59 +634,6 @@ static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
     debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
     return 0;
 } /* tcic_get_status */
-  
-/*====================================================================*/
-
-static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-    u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
-    u_char reg;
-    u_short scf1, scf2;
-    
-    tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
-	      | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
-    scf1 = tcic_getw(TCIC_DATA);
-    state->flags = (scf1 & TCIC_SCF1_IOSTS) ? SS_IOCARD : 0;
-    state->flags |= (scf1 & TCIC_SCF1_DMA_MASK) ? SS_DMA_MODE : 0;
-    state->flags |= (scf1 & TCIC_SCF1_SPKR) ? SS_SPKR_ENA : 0;
-    if (tcic_getb(TCIC_SCTRL) & TCIC_SCTRL_ENA)
-	state->flags |= SS_OUTPUT_ENA;
-    state->io_irq = scf1 & TCIC_SCF1_IRQ_MASK;
-    if (state->io_irq == 1) state->io_irq = 11;
-
-    reg = tcic_getb(TCIC_PWR);
-    state->Vcc = state->Vpp = 0;
-    if (reg & TCIC_PWR_VCC(psock)) {
-	if (reg & TCIC_PWR_VPP(psock))
-	    state->Vcc = 50;
-	else
-	    state->Vcc = state->Vpp = 50;
-    } else {
-	if (reg & TCIC_PWR_VPP(psock)) {
-	    state->Vcc = 50;
-	    state->Vpp = 120;
-	}
-    }
-    reg = tcic_aux_getb(TCIC_AUX_ILOCK);
-    state->flags |= (reg & TCIC_ILOCK_CRESET) ? SS_RESET : 0;
-
-    /* Card status change interrupt mask */
-    tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
-    scf2 = tcic_getw(TCIC_DATA);
-    state->csc_mask = (scf2 & TCIC_SCF2_MCD) ? 0 : SS_DETECT;
-    if (state->flags & SS_IOCARD) {
-	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_STSCHG;
-    } else {
-	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_BATDEAD;
-	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT2) ? 0 : SS_BATWARN;
-	state->csc_mask |= (scf2 & TCIC_SCF2_MRDY) ? 0 : SS_READY;
-    }
-
-    debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
-	  "io_irq %d, csc_mask %#2.2x\n", psock, state->flags,
-	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-    return 0;
-} /* tcic_get_socket */
 
 /*====================================================================*/
 
@@ -874,7 +814,6 @@ static int tcic_init(struct pcmcia_socket *s)
 static struct pccard_operations tcic_operations = {
 	.init		   = tcic_init,
 	.get_status	   = tcic_get_status,
-	.get_socket	   = tcic_get_socket,
 	.set_socket	   = tcic_set_socket,
 	.set_io_map	   = tcic_set_io_map,
 	.set_mem_map	   = tcic_set_mem_map,
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index 539b5cd1a598..d5b4ff74462e 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -873,7 +873,7 @@ static int ti1250_override(struct yenta_socket *socket)
  * Some fixup code to make everybody happy (TM).
  */
 
-#ifdef CONFIG_CARDBUS
+#ifdef CONFIG_YENTA_ENE_TUNE
 /**
  * set/clear various test bits:
  * Defaults to clear the bit.
@@ -937,7 +937,7 @@ static int ene_override(struct yenta_socket *socket)
 }
 #else
 #  define ene_override ti1250_override
-#endif
+#endif /* !CONFIG_YENTA_ENE_TUNE */
 
 #endif /* _LINUX_TI113X_H */
 
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 38a028c725d4..24c547ef512b 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -301,75 +301,6 @@ static int pccard_get_status(struct pcmcia_socket *sock, u_int *value)
 	return 0;
 }
 
-static inline u_char get_Vcc_value(uint8_t voltage)
-{
-	switch (voltage) {
-	case VCC_STATUS_3V:
-		return 33;
-	case VCC_STATUS_5V:
-		return 50;
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-static inline u_char get_Vpp_value(uint8_t power, u_char Vcc)
-{
-	if ((power & 0x03) == 0x01 || (power & 0x03) == 0x02)
-		return Vcc;
-
-	return 0;
-}
-
-static int pccard_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	unsigned int slot;
-	uint8_t power, voltage, control, cscint;
-
-	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || state == NULL)
-		return -EINVAL;
-
-	slot = sock->sock;
-
-	power = exca_read_byte(slot, I365_POWER);
-	voltage = exca_read_byte(slot, CARD_VOLTAGE_SELECT);
-
-	state->Vcc = get_Vcc_value(voltage);
-	state->Vpp = get_Vpp_value(power, state->Vcc);
-
-	state->flags = 0;
-	if (power & POWER_ENABLE)
-		state->flags |= SS_PWR_AUTO;
-	if (power & I365_PWR_OUT)
-		state->flags |= SS_OUTPUT_ENA;
-
-	control = exca_read_byte(slot, I365_INTCTL);
-	if (control & I365_PC_IOCARD)
-		state->flags |= SS_IOCARD;
-	if (!(control & I365_PC_RESET))
-		state->flags |= SS_RESET;
-
-        cscint = exca_read_byte(slot, I365_CSCINT);
-	state->csc_mask = 0;
-	if (state->flags & SS_IOCARD) {
-		if (cscint & I365_CSC_STSCHG)
-			state->flags |= SS_STSCHG;
-	} else {
-		if (cscint & I365_CSC_BVD1)
-			state->csc_mask |= SS_BATDEAD;
-		if (cscint & I365_CSC_BVD2)
-			state->csc_mask |= SS_BATWARN;
-	}
-	if (cscint & I365_CSC_READY)
-		state->csc_mask |= SS_READY;
-	if (cscint & I365_CSC_DETECT)
-		state->csc_mask |= SS_DETECT;
-
-	return 0;
-}
-
 static inline uint8_t set_Vcc_value(u_char Vcc)
 {
 	switch (Vcc) {
@@ -551,7 +482,6 @@ static int pccard_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map
 static struct pccard_operations vrc4171_pccard_operations = {
 	.init			= pccard_init,
 	.get_status		= pccard_get_status,
-	.get_socket		= pccard_get_socket,
 	.set_socket		= pccard_set_socket,
 	.set_io_map		= pccard_set_io_map,
 	.set_mem_map		= pccard_set_mem_map,
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c
index db91259dc50e..1b277d2c1c96 100644
--- a/drivers/pcmcia/vrc4173_cardu.c
+++ b/drivers/pcmcia/vrc4173_cardu.c
@@ -198,48 +198,6 @@ static int cardu_get_status(unsigned int sock, u_int *value)
 	return 0;
 }
 
-static inline u_char get_Vcc_value(uint8_t val)
-{
-	switch (val & VCC_MASK) {
-	case VCC_3V:
-		return 33;
-	case VCC_5V:
-		return 50;
-	}
-
-	return 0;
-}
-
-static inline u_char get_Vpp_value(uint8_t val)
-{
-	switch (val & VPP_MASK) {
-	case VPP_12V:
-		return 120;
-	case VPP_VCC:
-		return get_Vcc_value(val);
-	}
-
-	return 0;
-}
-
-static int cardu_get_socket(unsigned int sock, socket_state_t *state)
-{
-	vrc4173_socket_t *socket = &cardu_sockets[sock];
-	uint8_t val;
-
-	val = exca_readb(socket, PWR_CNT);
-	state->Vcc = get_Vcc_value(val);
-	state->Vpp = get_Vpp_value(val);
-	state->flags = 0;
-	if (val & CARD_OUT_EN) state->flags |= SS_OUTPUT_ENA;
-
-	val = exca_readb(socket, INT_GEN_CNT);
-	if (!(val & CARD_REST0)) state->flags |= SS_RESET;
-	if (val & CARD_TYPE_IO) state->flags |= SS_IOCARD;
-
-	return 0;
-}
-
 static inline uint8_t set_Vcc_value(u_char Vcc)
 {
 	switch (Vcc) {
@@ -431,7 +389,6 @@ static struct pccard_operations cardu_operations = {
 	.register_callback	= cardu_register_callback,
 	.inquire_socket		= cardu_inquire_socket,
 	.get_status		= cardu_get_status,
-	.get_socket		= cardu_get_socket,
 	.set_socket		= cardu_set_socket,
 	.get_io_map		= cardu_get_io_map,
 	.set_io_map		= cardu_set_io_map,
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index ec6ab65f0872..4145eb83b9b6 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -49,7 +49,13 @@ MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only
 #define to_cycles(ns)	((ns)/120)
 #define to_ns(cycles)	((cycles)*120)
 
+/**
+ * yenta PCI irq probing.
+ * currently only used in the TI/EnE initialization code
+ */
+#ifdef CONFIG_YENTA_TI
 static int yenta_probe_cb_irq(struct yenta_socket *socket);
+#endif
 
 
 static unsigned int override_bios;
@@ -224,95 +230,6 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
 	return 0;
 }
 
-static void yenta_get_power(struct yenta_socket *socket, socket_state_t *state)
-{
-	if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) &&
-	    (socket->flags & YENTA_16BIT_POWER_EXCA)) {
-		u8 reg, vcc, vpp;
-
-		reg = exca_readb(socket, I365_POWER);
-		vcc = reg & I365_VCC_MASK;
-		vpp = reg & I365_VPP1_MASK;
-		state->Vcc = state->Vpp = 0;
-
-		if (socket->flags & YENTA_16BIT_POWER_DF) {
-			if (vcc == I365_VCC_3V)
-				state->Vcc = 33;
-			if (vcc == I365_VCC_5V)
-				state->Vcc = 50;
-			if (vpp == I365_VPP1_5V)
-				state->Vpp = state->Vcc;
-			if (vpp == I365_VPP1_12V)
-				state->Vpp = 120;
-		} else {
-			if (reg & I365_VCC_5V) {
-				state->Vcc = 50;
-				if (vpp == I365_VPP1_5V)
-					state->Vpp = 50;
-				if (vpp == I365_VPP1_12V)
-					state->Vpp = 120;
-			}
-		}
-	} else {
-		u32 control;
-
-		control = cb_readl(socket, CB_SOCKET_CONTROL);
-
-		switch (control & CB_SC_VCC_MASK) {
-		case CB_SC_VCC_5V: state->Vcc = 50; break;
-		case CB_SC_VCC_3V: state->Vcc = 33; break;
-		default: state->Vcc = 0;
-		}
-
-		switch (control & CB_SC_VPP_MASK) {
-		case CB_SC_VPP_12V: state->Vpp = 120; break;
-		case CB_SC_VPP_5V: state->Vpp = 50; break;
-		case CB_SC_VPP_3V: state->Vpp = 33; break;
-		default: state->Vpp = 0;
-		}
-	}
-}
-
-static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	u8 reg;
-	u32 control;
-
-	control = cb_readl(socket, CB_SOCKET_CONTROL);
-
-	yenta_get_power(socket, state);
-	state->io_irq = socket->io_irq;
-
-	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
-		u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL);
-		if (bridge & CB_BRIDGE_CRST)
-			state->flags |= SS_RESET;
-		return 0;
-	}
-
-	/* 16-bit card state.. */
-	reg = exca_readb(socket, I365_POWER);
-	state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
-	state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
-
-	reg = exca_readb(socket, I365_INTCTL);
-	state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
-	state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0;
-
-	reg = exca_readb(socket, I365_CSCINT);
-	state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
-	if (state->flags & SS_IOCARD) {
-		state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
-	} else {
-		state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-		state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
-		state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
-	}
-
-	return 0;
-}
-
 static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state)
 {
 	/* some birdges require to use the ExCA registers to power 16bit cards */
@@ -531,6 +448,9 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 	csc = exca_readb(socket, I365_CSC);
 
+	if (!(cb_event || csc))
+		return IRQ_NONE;
+
 	events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ;
 	events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
 	if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
@@ -544,10 +464,7 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 	if (events)
 		pcmcia_parse_events(&socket->socket, events);
 
-	if (cb_event || csc)
-		return IRQ_HANDLED;
-
-	return IRQ_NONE;
+	return IRQ_HANDLED;
 }
 
 static void yenta_interrupt_wrapper(unsigned long data)
@@ -828,17 +745,24 @@ static struct pccard_operations yenta_socket_operations = {
 	.init			= yenta_sock_init,
 	.suspend		= yenta_sock_suspend,
 	.get_status		= yenta_get_status,
-	.get_socket		= yenta_get_socket,
 	.set_socket		= yenta_set_socket,
 	.set_io_map		= yenta_set_io_map,
 	.set_mem_map		= yenta_set_mem_map,
 };
 
 
+#ifdef CONFIG_YENTA_TI
 #include "ti113x.h"
+#endif
+#ifdef CONFIG_YENTA_RICOH
 #include "ricoh.h"
+#endif
+#ifdef CONFIG_YENTA_TOSHIBA
 #include "topic.h"
+#endif
+#ifdef CONFIG_YENTA_O2
 #include "o2micro.h"
+#endif
 
 enum {
 	CARDBUS_TYPE_DEFAULT = -1,
@@ -858,6 +782,7 @@ enum {
  * initialization sequences etc details. List them here..
  */
 static struct cardbus_type cardbus_type[] = {
+#ifdef CONFIG_YENTA_TI
 	[CARDBUS_TYPE_TI]	= {
 		.override	= ti_override,
 		.save_state	= ti_save_state,
@@ -882,27 +807,36 @@ static struct cardbus_type cardbus_type[] = {
 		.restore_state	= ti_restore_state,
 		.sock_init	= ti_init,
 	},
+#endif
+#ifdef CONFIG_YENTA_RICOH
 	[CARDBUS_TYPE_RICOH]	= {
 		.override	= ricoh_override,
 		.save_state	= ricoh_save_state,
 		.restore_state	= ricoh_restore_state,
 	},
+#endif
+#ifdef CONFIG_YENTA_TOSHIBA
 	[CARDBUS_TYPE_TOPIC95]	= {
 		.override	= topic95_override,
 	},
 	[CARDBUS_TYPE_TOPIC97]	= {
 		.override	= topic97_override,
 	},
+#endif
+#ifdef CONFIG_YENTA_O2
 	[CARDBUS_TYPE_O2MICRO]	= {
 		.override	= o2micro_override,
 		.restore_state	= o2micro_restore_state,
 	},
+#endif
+#ifdef CONFIG_YENTA_TI
 	[CARDBUS_TYPE_ENE]	= {
 		.override	= ene_override,
 		.save_state	= ti_save_state,
 		.restore_state	= ti_restore_state,
 		.sock_init	= ti_init,
 	},
+#endif
 };
 
 
@@ -948,6 +882,12 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
 }
 
 
+/**
+ * yenta PCI irq probing.
+ * currently only used in the TI/EnE initialization code
+ */
+#ifdef CONFIG_YENTA_TI
+
 /* interrupt handler, only used during probing */
 static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -1000,6 +940,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
 	return (int) socket->probe_status;
 }
 
+#endif /* CONFIG_YENTA_TI */
 
 
 /*
@@ -1078,10 +1019,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
 		return -ENODEV;
 	}
 
-	socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
+	socket = kzalloc(sizeof(struct yenta_socket), GFP_KERNEL);
 	if (!socket)
 		return -ENOMEM;
-	memset(socket, 0, sizeof(*socket));
 
 	/* prepare pcmcia_socket */
 	socket->socket.ops = &yenta_socket_operations;
@@ -1263,6 +1203,7 @@ static struct pci_device_id yenta_table [] = {
 	 * advanced overrides instead.  (I can't get the
 	 * data sheets for these devices. --rmk)
 	 */
+#ifdef CONFIG_YENTA_TI
 	CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI),
 
 	CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X),
@@ -1305,18 +1246,25 @@ static struct pci_device_id yenta_table [] = {
 	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE),
 	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE),
 	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE),
+#endif /* CONFIG_YENTA_TI */
 
+#ifdef CONFIG_YENTA_RICOH
 	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH),
 	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH),
 	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH),
 	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH),
 	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH),
+#endif
 
+#ifdef CONFIG_YENTA_TOSHIBA
 	CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95),
 	CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97),
 	CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97),
+#endif
 
+#ifdef CONFIG_YENTA_O2
 	CB_ID(PCI_VENDOR_ID_O2, PCI_ANY_ID, O2MICRO),
+#endif
 
 	/* match any cardbus bridge */
 	CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 7c5306499832..0c9edb7051f4 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -95,27 +95,21 @@ typedef struct scsi_info_t {
 } scsi_info_t;
 
 static void aha152x_release_cs(dev_link_t *link);
-static int aha152x_event(event_t event, int priority,
-			 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 void aha152x_config_cs(dev_link_t *link);
 
 static dev_link_t *dev_list;
-static dev_info_t dev_info = "aha152x_cs";
 
-static dev_link_t *aha152x_attach(void)
+static int aha152x_attach(struct pcmcia_device *p_dev)
 {
     scsi_info_t *info;
-    client_reg_t client_reg;
     dev_link_t *link;
-    int ret;
     
     DEBUG(0, "aha152x_attach()\n");
 
     /* Create new SCSI device */
     info = kmalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
+    if (!info) return -ENOMEM;
     memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
 
@@ -129,26 +123,20 @@ static dev_link_t *aha152x_attach(void)
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	aha152x_detach(link);
-	return NULL;
-    }
-    
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    aha152x_config_cs(link);
+
+    return 0;
 } /* aha152x_attach */
 
 /*====================================================================*/
 
-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 +150,6 @@ static void aha152x_detach(dev_link_t *link)
     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);
@@ -272,44 +257,31 @@ static void aha152x_release_cs(dev_link_t *link)
 	link->state &= ~DEV_CONFIG;
 }
 
-static int aha152x_event(event_t event, int priority,
-			 event_callback_args_t *args)
+static int aha152x_suspend(struct pcmcia_device *dev)
 {
-    dev_link_t *link = args->client_data;
-    scsi_info_t *info = link->priv;
-    
-    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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
+	dev_link_t *link = dev_to_instance(dev);
+
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int aha152x_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	scsi_info_t *info = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    Scsi_Cmnd tmp;
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    tmp.device->host = info->host;
-	    aha152x_host_reset(&tmp);
+		Scsi_Cmnd tmp;
+		pcmcia_request_configuration(link->handle, &link->conf);
+		tmp.device->host = info->host;
+		aha152x_host_reset(&tmp);
 	}
-	break;
-    }
-    return 0;
+
+	return 0;
 }
 
 static struct pcmcia_device_id aha152x_ids[] = {
@@ -327,10 +299,11 @@ static struct pcmcia_driver aha152x_cs_driver = {
 	.drv		= {
 		.name	= "aha152x_cs",
 	},
-	.attach		= aha152x_attach,
-	.event		= aha152x_event,
-	.detach		= aha152x_detach,
+	.probe		= aha152x_attach,
+	.remove		= aha152x_detach,
 	.id_table       = aha152x_ids,
+	.suspend	= aha152x_suspend,
+	.resume		= aha152x_resume,
 };
 
 static int __init init_aha152x_cs(void)
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index db8f5cd85ffe..788c58d805f3 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -80,29 +80,19 @@ typedef struct scsi_info_t {
 
 
 static void fdomain_release(dev_link_t *link);
-static int fdomain_event(event_t event, int priority,
-			event_callback_args_t *args);
+static void fdomain_detach(struct pcmcia_device *p_dev);
+static void fdomain_config(dev_link_t *link);
 
-static dev_link_t *fdomain_attach(void);
-static void fdomain_detach(dev_link_t *);
-
-
-static dev_link_t *dev_list = NULL;
-
-static dev_info_t dev_info = "fdomain_cs";
-
-static dev_link_t *fdomain_attach(void)
+static int fdomain_attach(struct pcmcia_device *p_dev)
 {
     scsi_info_t *info;
-    client_reg_t client_reg;
     dev_link_t *link;
-    int ret;
-    
+
     DEBUG(0, "fdomain_attach()\n");
 
     /* Create new SCSI device */
     info = kmalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
+    if (!info) return -ENOMEM;
     memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
     link->io.NumPorts1 = 0x10;
@@ -115,46 +105,27 @@ static dev_link_t *fdomain_attach(void)
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	fdomain_detach(link);
-	return NULL;
-    }
-    
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    fdomain_config(link);
+
+    return 0;
 } /* fdomain_attach */
 
 /*====================================================================*/
 
-static void fdomain_detach(dev_link_t *link)
+static void fdomain_detach(struct pcmcia_device *p_dev)
 {
-    dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
-    DEBUG(0, "fdomain_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
+	DEBUG(0, "fdomain_detach(0x%p)\n", link);
 
-    if (link->state & DEV_CONFIG)
-	fdomain_release(link);
+	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);
-    
+	kfree(link->priv);
 } /* fdomain_detach */
 
 /*====================================================================*/
@@ -256,43 +227,29 @@ static void fdomain_release(dev_link_t *link)
 
 /*====================================================================*/
 
-static int fdomain_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int fdomain_suspend(struct pcmcia_device *dev)
 {
-    dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 
-    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);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int fdomain_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    fdomain_16x0_bus_reset(NULL);
+		pcmcia_request_configuration(link->handle, &link->conf);
+		fdomain_16x0_bus_reset(NULL);
 	}
-	break;
-    }
-    return 0;
-} /* fdomain_event */
 
+	return 0;
+}
 
 static struct pcmcia_device_id fdomain_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20),
@@ -307,10 +264,11 @@ static struct pcmcia_driver fdomain_cs_driver = {
 	.drv		= {
 		.name	= "fdomain_cs",
 	},
-	.attach		= fdomain_attach,
-	.event		= fdomain_event,
-	.detach		= fdomain_detach,
+	.probe		= fdomain_attach,
+	.remove		= fdomain_detach,
 	.id_table       = fdomain_ids,
+	.suspend	= fdomain_suspend,
+	.resume		= fdomain_resume,
 };
 
 static int __init init_fdomain_cs(void)
@@ -321,7 +279,6 @@ static int __init init_fdomain_cs(void)
 static void __exit exit_fdomain_cs(void)
 {
 	pcmcia_unregister_driver(&fdomain_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_fdomain_cs);
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 050ea13ff80b..9e3ab3fd5355 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -104,9 +104,6 @@ static struct scsi_host_template nsp_driver_template = {
 #endif
 };
 
-static dev_link_t *dev_list = NULL;
-static dev_info_t dev_info  = {"nsp_cs"};
-
 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
 
 
@@ -1596,19 +1593,17 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
     configure the card at this point -- we wait until we receive a
     card insertion event.
 ======================================================================*/
-static dev_link_t *nsp_cs_attach(void)
+static int nsp_cs_attach(struct pcmcia_device *p_dev)
 {
 	scsi_info_t  *info;
-	client_reg_t  client_reg;
 	dev_link_t   *link;
-	int	      ret;
 	nsp_hw_data  *data = &nsp_data_base;
 
 	nsp_dbg(NSP_DEBUG_INIT, "in");
 
 	/* Create new SCSI device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
-	if (info == NULL) { return NULL; }
+	if (info == NULL) { return -ENOMEM; }
 	memset(info, 0, sizeof(*info));
 	link = &info->link;
 	link->priv = info;
@@ -1636,23 +1631,14 @@ static dev_link_t *nsp_cs_attach(void)
 	link->conf.IntType	 = INT_MEMORY_AND_IO;
 	link->conf.Present	 = PRESENT_OPTION;
 
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	/* Register with Card Services */
-	link->next               = dev_list;
-	dev_list                 = link;
-	client_reg.dev_info	 = &dev_info;
-	client_reg.Version	 = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		nsp_cs_detach(link);
-		return NULL;
-	}
-
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	nsp_cs_config(link);
 
 	nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
-	return link;
+	return 0;
 } /* nsp_cs_attach */
 
 
@@ -1662,35 +1648,19 @@ 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 **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
-		if (*linkp == link) {
-			break;
-		}
-	}
-	if (*linkp == NULL) {
-		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 */
-	*linkp = link->next;
 	kfree(link->priv);
 	link->priv = NULL;
-
 } /* nsp_cs_detach */
 
 
@@ -2021,99 +1991,58 @@ static void nsp_cs_release(dev_link_t *link)
 #endif
 } /* nsp_cs_release */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
-
-======================================================================*/
-static int nsp_cs_event(event_t		       event,
-			int		       priority,
-			event_callback_args_t *args)
+static int nsp_cs_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t  *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 	scsi_info_t *info = link->priv;
 	nsp_hw_data *data;
 
-	nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
+	link->state |= DEV_SUSPEND;
 
-	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;
+	nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
 
-	case CS_EVENT_CARD_INSERTION:
-		nsp_dbg(NSP_DEBUG_INIT, "event: insert");
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
-		info->bus    =  args->bus;
-#endif
-		nsp_cs_config(link);
-		break;
+	if (info->host != NULL) {
+		nsp_msg(KERN_INFO, "clear SDTR status");
 
-	case CS_EVENT_PM_SUSPEND:
-		nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		/* Mark the device as stopped, to block IO until later */
-		nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
+		data = (nsp_hw_data *)info->host->hostdata;
 
-		if (info->host != NULL) {
-			nsp_msg(KERN_INFO, "clear SDTR status");
+		nsphw_init_sync(data);
+	}
 
-			data = (nsp_hw_data *)info->host->hostdata;
+	info->stop = 1;
 
-			nsphw_init_sync(data);
-		}
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-		info->stop = 1;
-		if (link->state & DEV_CONFIG) {
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
+	return 0;
+}
 
-	case CS_EVENT_PM_RESUME:
-		nsp_dbg(NSP_DEBUG_INIT, "event: resume");
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		nsp_dbg(NSP_DEBUG_INIT, "event: reset");
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-		}
-		info->stop = 0;
+static int nsp_cs_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	scsi_info_t *info = link->priv;
+	nsp_hw_data *data;
 
-		if (info->host != NULL) {
-			nsp_msg(KERN_INFO, "reset host and bus");
+	nsp_dbg(NSP_DEBUG_INIT, "event: resume");
 
-			data = (nsp_hw_data *)info->host->hostdata;
+	link->state &= ~DEV_SUSPEND;
 
-			nsphw_init   (data);
-			nsp_bus_reset(data);
-		}
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
 
-		break;
+	info->stop = 0;
 
-	default:
-		nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
-		break;
+	if (info->host != NULL) {
+		nsp_msg(KERN_INFO, "reset host and bus");
+
+		data = (nsp_hw_data *)info->host->hostdata;
+
+		nsphw_init   (data);
+		nsp_bus_reset(data);
 	}
-	nsp_dbg(NSP_DEBUG_INIT, "end");
+
 	return 0;
-} /* nsp_cs_event */
+}
 
 /*======================================================================*
  *	module entry point
@@ -2136,10 +2065,11 @@ static struct pcmcia_driver nsp_driver = {
 	.drv		= {
 		.name	= "nsp_cs",
 	},
-	.attach		= nsp_cs_attach,
-	.event		= nsp_cs_event,
-	.detach		= nsp_cs_detach,
+	.probe		= nsp_cs_attach,
+	.remove		= nsp_cs_detach,
 	.id_table	= nsp_cs_ids,
+	.suspend	= nsp_cs_suspend,
+	.resume		= nsp_cs_resume,
 };
 #endif
 
@@ -2171,7 +2101,6 @@ static void __exit nsp_cs_exit(void)
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
 	pcmcia_unregister_driver(&nsp_driver);
-	BUG_ON(dev_list != NULL);
 #else
 	unregister_pcmcia_driver(&dev_info);
 	/* XXX: this really needs to move into generic code.. */
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index f8b943082717..b66b140a745e 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -296,11 +296,9 @@ 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);
 
 /* Linux SCSI subsystem specific functions */
 static struct Scsi_Host *nsp_detect     (struct scsi_host_template *sht);
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index bb091a45a880..dce7e687fd4a 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -98,15 +98,8 @@ typedef struct scsi_info_t {
 } scsi_info_t;
 
 static void qlogic_release(dev_link_t *link);
-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 dev_link_t *dev_list = NULL;
-
-static dev_info_t dev_info = "qlogic_cs";
+static void qlogic_detach(struct pcmcia_device *p_dev);
+static void qlogic_config(dev_link_t * link);
 
 static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host,
 				dev_link_t *link, int qbase, int qlirq)
@@ -163,19 +156,17 @@ free_scsi_host:
 err:
 	return NULL;
 }
-static dev_link_t *qlogic_attach(void)
+static int qlogic_attach(struct pcmcia_device *p_dev)
 {
 	scsi_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	DEBUG(0, "qlogic_attach()\n");
 
 	/* Create new SCSI device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 	memset(info, 0, sizeof(*info));
 	link = &info->link;
 	link->priv = info;
@@ -189,45 +180,26 @@ static dev_link_t *qlogic_attach(void)
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->conf.Present = PRESENT_OPTION;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		qlogic_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	qlogic_config(link);
+
+	return 0;
 }				/* qlogic_attach */
 
 /*====================================================================*/
 
-static void qlogic_detach(dev_link_t * link)
+static void qlogic_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	DEBUG(0, "qlogic_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 (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);
 
 }				/* qlogic_detach */
@@ -349,48 +321,39 @@ static void qlogic_release(dev_link_t *link)
 
 /*====================================================================*/
 
-static int qlogic_event(event_t event, int priority, event_callback_args_t * args)
+static int qlogic_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-
-	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);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			scsi_info_t *info = link->priv;
-			pcmcia_request_configuration(link->handle, &link->conf);
-			if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
-				outb(0x80, link->io.BasePort1 + 0xd);
-				outb(0x24, link->io.BasePort1 + 0x9);
-				outb(0x04, link->io.BasePort1 + 0xd);
-			}
-			/* Ugggglllyyyy!!! */
-			qlogicfas408_bus_reset(NULL);
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int qlogic_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		scsi_info_t *info = link->priv;
+
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if ((info->manf_id == MANFID_MACNICA) ||
+		    (info->manf_id == MANFID_PIONEER) ||
+		    (info->manf_id == 0x0098)) {
+			outb(0x80, link->io.BasePort1 + 0xd);
+			outb(0x24, link->io.BasePort1 + 0x9);
+			outb(0x04, link->io.BasePort1 + 0xd);
 		}
-		break;
+		/* Ugggglllyyyy!!! */
+		qlogicfas408_bus_reset(NULL);
 	}
+
 	return 0;
-}				/* qlogic_event */
+}
 
 static struct pcmcia_device_id qlogic_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6),
@@ -419,10 +382,11 @@ static struct pcmcia_driver qlogic_cs_driver = {
 	.drv		= {
 	.name		= "qlogic_cs",
 	},
-	.attach		= qlogic_attach,
-	.event		= qlogic_event,
-	.detach		= qlogic_detach,
+	.probe		= qlogic_attach,
+	.remove		= qlogic_detach,
 	.id_table       = qlogic_ids,
+	.suspend	= qlogic_suspend,
+	.resume		= qlogic_resume,
 };
 
 static int __init init_qlogic_cs(void)
@@ -433,7 +397,6 @@ static int __init init_qlogic_cs(void)
 static void __exit exit_qlogic_cs(void)
 {
 	pcmcia_unregister_driver(&qlogic_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 MODULE_AUTHOR("Tom Zerucha, Michael Griffith");
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 98b64b2aa8ee..3a4dd6f5b81f 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -228,15 +228,6 @@ enum Phase {
 
 /* ================================================================== */
 
-/*
-*  Global (within this module) variables other than
-*  sym53c500_driver_template (the scsi_host_template).
-*/
-static dev_link_t *dev_list;
-static dev_info_t dev_info = "sym53c500_cs";
-
-/* ================================================================== */
-
 static void
 chip_init(int io_port)
 {
@@ -872,96 +863,70 @@ cs_failed:
 	return;
 } /* SYM53C500_config */
 
-static int
-SYM53C500_event(event_t event, int priority, event_callback_args_t *args)
+static int sym53c500_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-	struct scsi_info_t *info = link->priv;
+	dev_link_t *link = dev_to_instance(dev);
 
-	DEBUG(1, "SYM53C500_event(0x%06x)\n", event);
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-	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);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-			/* See earlier comment about manufacturer IDs. */
-			if ((info->manf_id == MANFID_MACNICA) ||
-			    (info->manf_id == MANFID_PIONEER) ||
-			    (info->manf_id == 0x0098)) {
-				outb(0x80, link->io.BasePort1 + 0xd);
-				outb(0x24, link->io.BasePort1 + 0x9);
-				outb(0x04, link->io.BasePort1 + 0xd);
-			}
-			/*
-			*  If things don't work after a "resume",
-			*  this is a good place to start looking.
-			*/
-			SYM53C500_int_host_reset(link->io.BasePort1);
+	return 0;
+}
+
+static int sym53c500_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	struct scsi_info_t *info = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+		/* See earlier comment about manufacturer IDs. */
+		if ((info->manf_id == MANFID_MACNICA) ||
+		    (info->manf_id == MANFID_PIONEER) ||
+		    (info->manf_id == 0x0098)) {
+			outb(0x80, link->io.BasePort1 + 0xd);
+			outb(0x24, link->io.BasePort1 + 0x9);
+			outb(0x04, link->io.BasePort1 + 0xd);
 		}
-		break;
+		/*
+		 *  If things don't work after a "resume",
+		 *  this is a good place to start looking.
+		 */
+		SYM53C500_int_host_reset(link->io.BasePort1);
 	}
+
 	return 0;
-} /* SYM53C500_event */
+}
 
 static void
-SYM53C500_detach(dev_link_t *link)
+SYM53C500_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	DEBUG(0, "SYM53C500_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 (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);
 	link->priv = NULL;
 } /* SYM53C500_detach */
 
-static dev_link_t *
-SYM53C500_attach(void)
+static int
+SYM53C500_attach(struct pcmcia_device *p_dev)
 {
 	struct scsi_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	DEBUG(0, "SYM53C500_attach()\n");
 
 	/* Create new SCSI device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 	memset(info, 0, sizeof(*info));
 	link = &info->link;
 	link->priv = info;
@@ -975,20 +940,13 @@ SYM53C500_attach(void)
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->conf.Present = PRESENT_OPTION;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		SYM53C500_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	SYM53C500_config(link);
 
-	return link;
+	return 0;
 } /* SYM53C500_attach */
 
 MODULE_AUTHOR("Bob Tracy <rct@frus.com>");
@@ -1008,10 +966,11 @@ static struct pcmcia_driver sym53c500_cs_driver = {
 	.drv		= {
 		.name	= "sym53c500_cs",
 	},
-	.attach		= SYM53C500_attach,
-	.event		= SYM53C500_event,
-	.detach		= SYM53C500_detach,
+	.probe		= SYM53C500_attach,
+	.remove		= SYM53C500_detach,
 	.id_table       = sym53c500_ids,
+	.suspend	= sym53c500_suspend,
+	.resume		= sym53c500_resume,
 };
 
 static int __init
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 7ce0c7e66d37..96969cb960a9 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -114,15 +114,7 @@ struct serial_cfg_mem {
 
 
 static void serial_config(dev_link_t * link);
-static int serial_event(event_t event, int priority,
-			event_callback_args_t * args);
 
-static dev_info_t dev_info = "serial_cs";
-
-static dev_link_t *serial_attach(void);
-static void serial_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
 
 /*======================================================================
 
@@ -159,8 +151,9 @@ static void serial_remove(dev_link_t *link)
 	}
 }
 
-static void serial_suspend(dev_link_t *link)
+static int serial_suspend(struct pcmcia_device *dev)
 {
+	dev_link_t *link = dev_to_instance(dev);
 	link->state |= DEV_SUSPEND;
 
 	if (link->state & DEV_CONFIG) {
@@ -173,10 +166,13 @@ static void serial_suspend(dev_link_t *link)
 		if (!info->slave)
 			pcmcia_release_configuration(link->handle);
 	}
+
+	return 0;
 }
 
-static void serial_resume(dev_link_t *link)
+static int serial_resume(struct pcmcia_device *dev)
 {
+	dev_link_t *link = dev_to_instance(dev);
 	link->state &= ~DEV_SUSPEND;
 
 	if (DEV_OK(link)) {
@@ -189,6 +185,8 @@ static void serial_resume(dev_link_t *link)
 		for (i = 0; i < info->ndev; i++)
 			serial8250_resume_port(info->line[i]);
 	}
+
+	return 0;
 }
 
 /*======================================================================
@@ -199,19 +197,17 @@ static void serial_resume(dev_link_t *link)
 
 ======================================================================*/
 
-static dev_link_t *serial_attach(void)
+static int serial_probe(struct pcmcia_device *p_dev)
 {
 	struct serial_info *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	DEBUG(0, "serial_attach()\n");
 
 	/* Create new serial device */
 	info = kmalloc(sizeof (*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 	memset(info, 0, sizeof (*info));
 	link = &info->link;
 	link->priv = info;
@@ -227,20 +223,12 @@ static dev_link_t *serial_attach(void)
 	}
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		serial_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	serial_config(link);
 
-	return link;
+	return 0;
 }
 
 /*======================================================================
@@ -252,21 +240,13 @@ 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);
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-	if (*linkp == NULL)
-		return;
-
 	/*
 	 * Ensure any outstanding scheduled tasks are completed.
 	 */
@@ -277,14 +257,7 @@ static void serial_detach(dev_link_t * link)
 	 */
 	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;
+	/* free bits */
 	kfree(info);
 }
 
@@ -718,54 +691,6 @@ void serial_config(dev_link_t * link)
 	kfree(cfg_mem);
 }
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the serial drivers from
-    talking to the ports.
-    
-======================================================================*/
-
-static int
-serial_event(event_t event, int priority, event_callback_args_t * args)
-{
-	dev_link_t *link = args->client_data;
-	struct serial_info *info = link->priv;
-
-	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;
-		serial_config(link);
-		break;
-
-	case CS_EVENT_PM_SUSPEND:
-		serial_suspend(link);
-		break;
-
-	case CS_EVENT_RESET_PHYSICAL:
-		if ((link->state & DEV_CONFIG) && !info->slave)
-			pcmcia_release_configuration(link->handle);
-		break;
-
-	case CS_EVENT_PM_RESUME:
-		serial_resume(link);
-		break;
-
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link) && !info->slave)
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
-	return 0;
-}
-
 static struct pcmcia_device_id serial_ids[] = {
 	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
 	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
@@ -877,10 +802,11 @@ static struct pcmcia_driver serial_cs_driver = {
 	.drv		= {
 		.name	= "serial_cs",
 	},
-	.attach		= serial_attach,
-	.event		= serial_event,
-	.detach		= serial_detach,
+	.probe		= serial_probe,
+	.remove		= serial_detach,
 	.id_table	= serial_ids,
+	.suspend	= serial_suspend,
+	.resume		= serial_resume,
 };
 
 static int __init init_serial_cs(void)
@@ -891,7 +817,6 @@ static int __init init_serial_cs(void)
 static void __exit exit_serial_cs(void)
 {
 	pcmcia_unregister_driver(&serial_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_serial_cs);
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index 57c0c6e3fbed..d3a7b0c3d38b 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -34,24 +34,19 @@ typedef struct ixj_info_t {
 	struct ixj *port;
 } 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);
-static dev_info_t dev_info = "ixj_cs";
-static dev_link_t *dev_list = NULL;
 
-static dev_link_t *ixj_attach(void)
+static int ixj_attach(struct pcmcia_device *p_dev)
 {
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
+
 	DEBUG(0, "ixj_attach()\n");
 	/* Create new ixj device */
 	link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
 	if (!link)
-		return NULL;
+		return -ENOMEM;
 	memset(link, 0, sizeof(struct dev_link_t));
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
@@ -61,44 +56,29 @@ static dev_link_t *ixj_attach(void)
 	link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
 	if (!link->priv) {
 		kfree(link);
-		return NULL;
+		return -ENOMEM;
 	}
 	memset(link->priv, 0, sizeof(struct ixj_info_t));
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		ixj_detach(link);
-		return NULL;
-	}
-	return link;
+
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	ixj_config(link);
+
+	return 0;
 }
 
-static void ixj_detach(dev_link_t * link)
+static void ixj_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
-	int ret;
+	dev_link_t *link = dev_to_instance(p_dev);
+
 	DEBUG(0, "ixj_detach(0x%p)\n", link);
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-	if (*linkp == NULL)
-		return;
+
 	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);
         kfree(link);
 }
@@ -255,37 +235,25 @@ static void ixj_cs_release(dev_link_t *link)
 	link->state &= ~DEV_CONFIG;
 }
 
-static int ixj_event(event_t event, int priority, event_callback_args_t * args)
+static int ixj_suspend(struct pcmcia_device *dev)
 {
-	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);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link))
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int ixj_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
+
 	return 0;
 }
 
@@ -300,10 +268,11 @@ static struct pcmcia_driver ixj_driver = {
 	.drv		= {
 		.name	= "ixj_cs",
 	},
-	.attach		= ixj_attach,
-	.event		= ixj_event,
-	.detach		= ixj_detach,
+	.probe		= ixj_attach,
+	.remove		= ixj_detach,
 	.id_table	= ixj_ids,
+	.suspend	= ixj_suspend,
+	.resume		= ixj_resume,
 };
 
 static int __init ixj_pcmcia_init(void)
@@ -314,7 +283,6 @@ static int __init ixj_pcmcia_init(void)
 static void ixj_pcmcia_exit(void)
 {
 	pcmcia_unregister_driver(&ixj_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(ixj_pcmcia_init);
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 5056b7459994..466384d7c79f 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -66,13 +66,13 @@ module_param(pc_debug, int, 0644);
 
 static const char driver_name[DEV_NAME_LEN]  = "sl811_cs";
 
-static dev_link_t *dev_list = NULL;
-
 typedef struct local_info_t {
 	dev_link_t		link;
 	dev_node_t		node;
 } local_info_t;
 
+static void sl811_cs_release(dev_link_t * link);
+
 /*====================================================================*/
 
 static void release_platform_dev(struct device * dev)
@@ -138,26 +138,16 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)
 
 /*====================================================================*/
 
-static void sl811_cs_detach(dev_link_t *link)
+static void sl811_cs_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	DBG(0, "sl811_cs_detach(0x%p)\n", link);
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
-		if (*linkp == link)
-			break;
-	}
-	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;
 	/* This points to the parent local_info_t struct */
 	kfree(link->priv);
 }
@@ -167,13 +157,6 @@ static void sl811_cs_release(dev_link_t * link)
 
 	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;
 
@@ -184,9 +167,6 @@ static void sl811_cs_release(dev_link_t * link)
 	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)
@@ -323,55 +303,36 @@ cs_failed:
 	}
 }
 
-static int
-sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
+static int sl811_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 
-	DBG(1, "sl811_cs_event(0x%06x)\n", event);
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
-			sl811_cs_release(link);
-		break;
+	return 0;
+}
 
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		sl811_cs_config(link);
-		break;
+static int sl811_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
 
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
 
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG)
-			pcmcia_request_configuration(link->handle, &link->conf);
-		DBG(0, "reset sl811-hcd here?\n");
-		break;
-	}
 	return 0;
 }
 
-static dev_link_t *sl811_cs_attach(void)
+static int sl811_cs_attach(struct pcmcia_device *p_dev)
 {
 	local_info_t *local;
 	dev_link_t *link;
-	client_reg_t client_reg;
-	int ret;
 
 	local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
 	if (!local)
-		return NULL;
+		return -ENOMEM;
 	memset(local, 0, sizeof(local_info_t));
 	link = &local->link;
 	link->priv = local;
@@ -385,21 +346,13 @@ static dev_link_t *sl811_cs_attach(void)
 	link->conf.Vcc = 33;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = (dev_info_t *) &driver_name;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		sl811_cs_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	sl811_cs_config(link);
+
+	return 0;
 }
 
 static struct pcmcia_device_id sl811_ids[] = {
@@ -413,10 +366,11 @@ static struct pcmcia_driver sl811_cs_driver = {
 	.drv		= {
 		.name	= (char *)driver_name,
 	},
-	.attach		= sl811_cs_attach,
-	.event		= sl811_cs_event,
-	.detach		= sl811_cs_detach,
+	.probe		= sl811_cs_attach,
+	.remove		= sl811_cs_detach,
 	.id_table	= sl811_ids,
+	.suspend	= sl811_suspend,
+	.resume		= sl811_resume,
 };
 
 /*====================================================================*/
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 08edbfcfca58..3fefdb0cbf07 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -403,7 +403,7 @@ static struct {
 	{ PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL },
 	{ PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL },
 	{ PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL },
-	{ PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 230, 83, 63, ATI_CHIP_264XL },
+	{ PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 235, 83, 63, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
 	{ PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL },
 	{ PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL },