[PATCH] pcmcia: embed dev_link_t into struct pcmcia_device

Embed dev_link_t into struct pcmcia_device(), as they basically address the
same entity. The actual contents of dev_link_t will be cleaned up step by step.
This patch includes a bugfix from and signed-off-by Andrew Morton.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>

diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 8e23f9a..b461411 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -65,7 +65,7 @@
 
 
 typedef struct bluecard_info_t {
-	dev_link_t link;
+	struct pcmcia_device *p_dev;
 	dev_node_t node;
 
 	struct hci_dev *hdev;
@@ -162,7 +162,7 @@
 static void bluecard_activity_led_timeout(u_long arg)
 {
 	bluecard_info_t *info = (bluecard_info_t *)arg;
-	unsigned int iobase = info->link.io.BasePort1;
+	unsigned int iobase = info->p_dev->io.BasePort1;
 
 	if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
 		return;
@@ -179,7 +179,7 @@
 
 static void bluecard_enable_activity_led(bluecard_info_t *info)
 {
-	unsigned int iobase = info->link.io.BasePort1;
+	unsigned int iobase = info->p_dev->io.BasePort1;
 
 	if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
 		return;
@@ -235,7 +235,7 @@
 	}
 
 	do {
-		register unsigned int iobase = info->link.io.BasePort1;
+		register unsigned int iobase = info->p_dev->io.BasePort1;
 		register unsigned int offset;
 		register unsigned char command;
 		register unsigned long ready_bit;
@@ -244,7 +244,7 @@
 
 		clear_bit(XMIT_WAKEUP, &(info->tx_state));
 
-		if (!(info->link.state & DEV_PRESENT))
+		if (!(info->p_dev->state & DEV_PRESENT))
 			return;
 
 		if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
@@ -382,7 +382,7 @@
 		return;
 	}
 
-	iobase = info->link.io.BasePort1;
+	iobase = info->p_dev->io.BasePort1;
 
 	if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
 		bluecard_enable_activity_led(info);
@@ -512,7 +512,7 @@
 	if (!test_bit(CARD_READY, &(info->hw_state)))
 		return IRQ_HANDLED;
 
-	iobase = info->link.io.BasePort1;
+	iobase = info->p_dev->io.BasePort1;
 
 	spin_lock(&(info->lock));
 
@@ -626,7 +626,7 @@
 static int bluecard_hci_open(struct hci_dev *hdev)
 {
 	bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-	unsigned int iobase = info->link.io.BasePort1;
+	unsigned int iobase = info->p_dev->io.BasePort1;
 
 	if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
 		bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
@@ -646,7 +646,7 @@
 static int bluecard_hci_close(struct hci_dev *hdev)
 {
 	bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-	unsigned int iobase = info->link.io.BasePort1;
+	unsigned int iobase = info->p_dev->io.BasePort1;
 
 	if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
 		return 0;
@@ -713,7 +713,7 @@
 
 static int bluecard_open(bluecard_info_t *info)
 {
-	unsigned int iobase = info->link.io.BasePort1;
+	unsigned int iobase = info->p_dev->io.BasePort1;
 	struct hci_dev *hdev;
 	unsigned char id;
 
@@ -831,7 +831,7 @@
 
 static int bluecard_close(bluecard_info_t *info)
 {
-	unsigned int iobase = info->link.io.BasePort1;
+	unsigned int iobase = info->p_dev->io.BasePort1;
 	struct hci_dev *hdev = info->hdev;
 
 	if (!hdev)
@@ -859,14 +859,14 @@
 static int bluecard_attach(struct pcmcia_device *p_dev)
 {
 	bluecard_info_t *info;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
-	link = &info->link;
+	info->p_dev = p_dev;
 	link->priv = info;
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@@ -880,9 +880,6 @@
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	bluecard_config(link);
 
@@ -976,7 +973,7 @@
 		goto failed;
 
 	strcpy(info->node.dev_name, info->hdev->name);
-	link->dev = &info->node;
+	link->dev_node = &info->node;
 	link->state &= ~DEV_CONFIG_PENDING;
 
 	return;
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 0b848050..9192a75 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -72,7 +72,7 @@
 
 
 typedef struct bt3c_info_t {
-	dev_link_t link;
+	struct pcmcia_device *p_dev;
 	dev_node_t node;
 
 	struct hci_dev *hdev;
@@ -191,11 +191,11 @@
 		return;
 
 	do {
-		register unsigned int iobase = info->link.io.BasePort1;
+		register unsigned int iobase = info->p_dev->io.BasePort1;
 		register struct sk_buff *skb;
 		register int len;
 
-		if (!(info->link.state & DEV_PRESENT))
+		if (!(info->p_dev->state & DEV_PRESENT))
 			break;
 
 
@@ -229,7 +229,7 @@
 		return;
 	}
 
-	iobase = info->link.io.BasePort1;
+	iobase = info->p_dev->io.BasePort1;
 
 	avail = bt3c_read(iobase, 0x7006);
 	//printk("bt3c_cs: receiving %d bytes\n", avail);
@@ -350,7 +350,7 @@
 		return IRQ_NONE;
 	}
 
-	iobase = info->link.io.BasePort1;
+	iobase = info->p_dev->io.BasePort1;
 
 	spin_lock(&(info->lock));
 
@@ -481,7 +481,7 @@
 	unsigned int iobase, size, addr, fcs, tmp;
 	int i, err = 0;
 
-	iobase = info->link.io.BasePort1;
+	iobase = info->p_dev->io.BasePort1;
 
 	/* Reset */
 	bt3c_io_write(iobase, 0x8040, 0x0404);
@@ -562,7 +562,6 @@
 {
 	const struct firmware *firmware;
 	struct hci_dev *hdev;
-	client_handle_t handle;
 	int err;
 
 	spin_lock_init(&(info->lock));
@@ -594,10 +593,8 @@
 
 	hdev->owner = THIS_MODULE;
 
-	handle = info->link.handle;
-
 	/* Load firmware */
-	err = request_firmware(&firmware, "BT3CPCC.bin", &handle_to_dev(handle));
+	err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
 	if (err < 0) {
 		BT_ERR("Firmware request failed");
 		goto error;
@@ -651,14 +648,14 @@
 static int bt3c_attach(struct pcmcia_device *p_dev)
 {
 	bt3c_info_t *info;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
-	link = &info->link;
+	info->p_dev = p_dev;
 	link->priv = info;
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@@ -672,9 +669,6 @@
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	bt3c_config(link);
 
@@ -815,7 +809,7 @@
 		goto failed;
 
 	strcpy(info->node.dev_name, info->hdev->name);
-	link->dev = &info->node;
+	link->dev_node = &info->node;
 	link->state &= ~DEV_CONFIG_PENDING;
 
 	return;
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index ec19a57..cfe1d74 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -68,7 +68,7 @@
 
 
 typedef struct btuart_info_t {
-	dev_link_t link;
+	struct pcmcia_device *p_dev;
 	dev_node_t node;
 
 	struct hci_dev *hdev;
@@ -146,13 +146,13 @@
 	}
 
 	do {
-		register unsigned int iobase = info->link.io.BasePort1;
+		register unsigned int iobase = info->p_dev->io.BasePort1;
 		register struct sk_buff *skb;
 		register int len;
 
 		clear_bit(XMIT_WAKEUP, &(info->tx_state));
 
-		if (!(info->link.state & DEV_PRESENT))
+		if (!(info->p_dev->state & DEV_PRESENT))
 			return;
 
 		if (!(skb = skb_dequeue(&(info->txq))))
@@ -187,7 +187,7 @@
 		return;
 	}
 
-	iobase = info->link.io.BasePort1;
+	iobase = info->p_dev->io.BasePort1;
 
 	do {
 		info->hdev->stat.byte_rx++;
@@ -301,7 +301,7 @@
 		return IRQ_NONE;
 	}
 
-	iobase = info->link.io.BasePort1;
+	iobase = info->p_dev->io.BasePort1;
 
 	spin_lock(&(info->lock));
 
@@ -357,7 +357,7 @@
 		return;
 	}
 
-	iobase = info->link.io.BasePort1;
+	iobase = info->p_dev->io.BasePort1;
 
 	spin_lock_irqsave(&(info->lock), flags);
 
@@ -481,7 +481,7 @@
 static int btuart_open(btuart_info_t *info)
 {
 	unsigned long flags;
-	unsigned int iobase = info->link.io.BasePort1;
+	unsigned int iobase = info->p_dev->io.BasePort1;
 	struct hci_dev *hdev;
 
 	spin_lock_init(&(info->lock));
@@ -550,7 +550,7 @@
 static int btuart_close(btuart_info_t *info)
 {
 	unsigned long flags;
-	unsigned int iobase = info->link.io.BasePort1;
+	unsigned int iobase = info->p_dev->io.BasePort1;
 	struct hci_dev *hdev = info->hdev;
 
 	if (!hdev)
@@ -579,14 +579,14 @@
 static int btuart_attach(struct pcmcia_device *p_dev)
 {
 	btuart_info_t *info;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
-	link = &info->link;
+	info->p_dev = p_dev;
 	link->priv = info;
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@@ -600,9 +600,6 @@
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	btuart_config(link);
 
@@ -744,7 +741,7 @@
 		goto failed;
 
 	strcpy(info->node.dev_name, info->hdev->name);
-	link->dev = &info->node;
+	link->dev_node = &info->node;
 	link->state &= ~DEV_CONFIG_PENDING;
 
 	return;
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 86617ee..389a682 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -68,7 +68,7 @@
 
 
 typedef struct dtl1_info_t {
-	dev_link_t link;
+	struct pcmcia_device *p_dev;
 	dev_node_t node;
 
 	struct hci_dev *hdev;
@@ -153,13 +153,13 @@
 	}
 
 	do {
-		register unsigned int iobase = info->link.io.BasePort1;
+		register unsigned int iobase = info->p_dev->io.BasePort1;
 		register struct sk_buff *skb;
 		register int len;
 
 		clear_bit(XMIT_WAKEUP, &(info->tx_state));
 
-		if (!(info->link.state & DEV_PRESENT))
+		if (!(info->p_dev->state & DEV_PRESENT))
 			return;
 
 		if (!(skb = skb_dequeue(&(info->txq))))
@@ -218,7 +218,7 @@
 		return;
 	}
 
-	iobase = info->link.io.BasePort1;
+	iobase = info->p_dev->io.BasePort1;
 
 	do {
 		info->hdev->stat.byte_rx++;
@@ -305,7 +305,7 @@
 		return IRQ_NONE;
 	}
 
-	iobase = info->link.io.BasePort1;
+	iobase = info->p_dev->io.BasePort1;
 
 	spin_lock(&(info->lock));
 
@@ -458,7 +458,7 @@
 static int dtl1_open(dtl1_info_t *info)
 {
 	unsigned long flags;
-	unsigned int iobase = info->link.io.BasePort1;
+	unsigned int iobase = info->p_dev->io.BasePort1;
 	struct hci_dev *hdev;
 
 	spin_lock_init(&(info->lock));
@@ -504,7 +504,7 @@
 	outb(UART_LCR_WLEN8, iobase + UART_LCR);	/* Reset DLAB */
 	outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
 
-	info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI;
+	info->ri_latch = inb(info->p_dev->io.BasePort1 + UART_MSR) & UART_MSR_RI;
 
 	/* Turn on interrupts */
 	outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
@@ -529,7 +529,7 @@
 static int dtl1_close(dtl1_info_t *info)
 {
 	unsigned long flags;
-	unsigned int iobase = info->link.io.BasePort1;
+	unsigned int iobase = info->p_dev->io.BasePort1;
 	struct hci_dev *hdev = info->hdev;
 
 	if (!hdev)
@@ -558,14 +558,14 @@
 static int dtl1_attach(struct pcmcia_device *p_dev)
 {
 	dtl1_info_t *info;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
-	link = &info->link;
+	info->p_dev = p_dev;
 	link->priv = info;
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@@ -579,9 +579,6 @@
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	dtl1_config(link);
 
@@ -696,7 +693,7 @@
 		goto failed;
 
 	strcpy(info->node.dev_name, info->hdev->name);
-	link->dev = &info->node;
+	link->dev_node = &info->node;
 	link->state &= ~DEV_CONFIG_PENDING;
 
 	return;
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index c996ae1..3e6d6e0 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -46,7 +46,7 @@
 /* #define ATR_CSUM */
 
 #ifdef PCMCIA_DEBUG
-#define reader_to_dev(x)	(&handle_to_dev(x->link.handle))
+#define reader_to_dev(x)	(&handle_to_dev(x->p_dev->handle))
 static int pc_debug = PCMCIA_DEBUG;
 module_param(pc_debug, int, 0600);
 #define DEBUGP(n, rdr, x, args...) do { 				\
@@ -106,7 +106,7 @@
 #define REG_STOPBITS(x)		(x + 7)
 
 struct cm4000_dev {
-	dev_link_t link;		/* pcmcia link */
+	struct pcmcia_device *p_dev;
 	dev_node_t node;		/* OS node (major,minor) */
 
 	unsigned char atr[MAX_ATR];
@@ -454,7 +454,7 @@
 static void set_cardparameter(struct cm4000_dev *dev)
 {
 	int i;
-	ioaddr_t iobase = dev->link.io.BasePort1;
+	ioaddr_t iobase = dev->p_dev->io.BasePort1;
 	u_int8_t stopbits = 0x02; /* ISO default */
 
 	DEBUGP(3, dev, "-> set_cardparameter\n");
@@ -487,7 +487,7 @@
 	unsigned short num_bytes_read;
 	unsigned char pts_reply[4];
 	ssize_t rc;
-	ioaddr_t iobase = dev->link.io.BasePort1;
+	ioaddr_t iobase = dev->p_dev->io.BasePort1;
 
 	rc = 0;
 
@@ -699,7 +699,7 @@
 static void monitor_card(unsigned long p)
 {
 	struct cm4000_dev *dev = (struct cm4000_dev *) p;
-	ioaddr_t iobase = dev->link.io.BasePort1;
+	ioaddr_t iobase = dev->p_dev->io.BasePort1;
 	unsigned short s;
 	struct ptsreq ptsreq;
 	int i, atrc;
@@ -962,7 +962,7 @@
 			loff_t *ppos)
 {
 	struct cm4000_dev *dev = filp->private_data;
-	ioaddr_t iobase = dev->link.io.BasePort1;
+	ioaddr_t iobase = dev->p_dev->io.BasePort1;
 	ssize_t rc;
 	int i, j, k;
 
@@ -971,7 +971,7 @@
 	if (count == 0)		/* according to manpage */
 		return 0;
 
-	if ((dev->link.state & DEV_PRESENT) == 0 ||	/* socket removed */
+	if ((dev->p_dev->state & DEV_PRESENT) == 0 ||	/* socket removed */
 	    test_bit(IS_CMM_ABSENT, &dev->flags))
 		return -ENODEV;
 
@@ -1083,7 +1083,7 @@
 			 size_t count, loff_t *ppos)
 {
 	struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data;
-	ioaddr_t iobase = dev->link.io.BasePort1;
+	ioaddr_t iobase = dev->p_dev->io.BasePort1;
 	unsigned short s;
 	unsigned char tmp;
 	unsigned char infolen;
@@ -1108,7 +1108,7 @@
 
 	sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0;
 
-	if ((dev->link.state & DEV_PRESENT) == 0 ||	/* socket removed */
+	if ((dev->p_dev->state & DEV_PRESENT) == 0 ||	/* socket removed */
 	    test_bit(IS_CMM_ABSENT, &dev->flags))
 		return -ENODEV;
 
@@ -1440,7 +1440,7 @@
 		     unsigned long arg)
 {
 	struct cm4000_dev *dev = filp->private_data;
-	ioaddr_t iobase = dev->link.io.BasePort1;
+	ioaddr_t iobase = dev->p_dev->io.BasePort1;
 	dev_link_t *link;
 	int size;
 	int rc;
@@ -1844,7 +1844,7 @@
 	dev->node.major = major;
 	dev->node.minor = devno;
 	dev->node.next = NULL;
-	link->dev = &dev->node;
+	link->dev_node = &dev->node;
 	link->state &= ~DEV_CONFIG_PENDING;
 
 	return;
@@ -1889,8 +1889,8 @@
 static int cm4000_attach(struct pcmcia_device *p_dev)
 {
 	struct cm4000_dev *dev;
-	dev_link_t *link;
 	int i;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	for (i = 0; i < CM4000_MAX_DEV; i++)
 		if (dev_table[i] == NULL)
@@ -1906,7 +1906,7 @@
 	if (dev == NULL)
 		return -ENOMEM;
 
-	link = &dev->link;
+	dev->p_dev = p_dev;
 	link->priv = dev;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	dev_table[i] = link;
@@ -1916,9 +1916,6 @@
 	init_waitqueue_head(&dev->atrq);
 	init_waitqueue_head(&dev->readq);
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	cm4000_config(link, i);
 
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 94ecd03..97e32e7 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -41,7 +41,7 @@
 
 
 #ifdef PCMCIA_DEBUG
-#define reader_to_dev(x)	(&handle_to_dev(x->link.handle))
+#define reader_to_dev(x)	(&handle_to_dev(x->p_dev->handle))
 static int pc_debug = PCMCIA_DEBUG;
 module_param(pc_debug, int, 0600);
 #define DEBUGP(n, rdr, x, args...) do { 				\
@@ -74,7 +74,7 @@
 #define		BS_WRITABLE	0x02
 
 struct reader_dev {
-	dev_link_t		link;
+	struct pcmcia_device	*p_dev;
 	dev_node_t		node;
 	wait_queue_head_t	devq;
 	wait_queue_head_t	poll_wait;
@@ -116,7 +116,7 @@
 static void cm4040_do_poll(unsigned long dummy)
 {
 	struct reader_dev *dev = (struct reader_dev *) dummy;
-	unsigned int obs = xinb(dev->link.io.BasePort1
+	unsigned int obs = xinb(dev->p_dev->io.BasePort1
 				+ REG_OFFSET_BUFFER_STATUS);
 
 	if ((obs & BSR_BULK_IN_FULL)) {
@@ -147,7 +147,7 @@
 static int wait_for_bulk_out_ready(struct reader_dev *dev)
 {
 	int i, rc;
-	int iobase = dev->link.io.BasePort1;
+	int iobase = dev->p_dev->io.BasePort1;
 
 	for (i = 0; i < POLL_LOOP_COUNT; i++) {
 		if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
@@ -177,7 +177,7 @@
 /* Write to Sync Control Register */
 static int write_sync_reg(unsigned char val, struct reader_dev *dev)
 {
-	int iobase = dev->link.io.BasePort1;
+	int iobase = dev->p_dev->io.BasePort1;
 	int rc;
 
 	rc = wait_for_bulk_out_ready(dev);
@@ -195,7 +195,7 @@
 static int wait_for_bulk_in_ready(struct reader_dev *dev)
 {
 	int i, rc;
-	int iobase = dev->link.io.BasePort1;
+	int iobase = dev->p_dev->io.BasePort1;
 
 	for (i = 0; i < POLL_LOOP_COUNT; i++) {
 		if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
@@ -225,7 +225,7 @@
 			size_t count, loff_t *ppos)
 {
 	struct reader_dev *dev = filp->private_data;
-	int iobase = dev->link.io.BasePort1;
+	int iobase = dev->p_dev->io.BasePort1;
 	size_t bytes_to_read;
 	unsigned long i;
 	size_t min_bytes_to_read;
@@ -246,7 +246,7 @@
 		return -EAGAIN;
 	}
 
-	if ((dev->link.state & DEV_PRESENT)==0)
+	if ((dev->p_dev->state & DEV_PRESENT)==0)
 		return -ENODEV;
 
 	for (i = 0; i < 5; i++) {
@@ -328,7 +328,7 @@
 			 size_t count, loff_t *ppos)
 {
 	struct reader_dev *dev = filp->private_data;
-	int iobase = dev->link.io.BasePort1;
+	int iobase = dev->p_dev->io.BasePort1;
 	ssize_t rc;
 	int i;
 	unsigned int bytes_to_write;
@@ -351,7 +351,7 @@
 		return -EAGAIN;
 	}
 
-	if ((dev->link.state & DEV_PRESENT) == 0)
+	if ((dev->p_dev->state & DEV_PRESENT) == 0)
 		return -ENODEV;
 
 	bytes_to_write = count;
@@ -606,7 +606,7 @@
 	dev->node.major = major;
 	dev->node.minor = devno;
 	dev->node.next = NULL;
-	link->dev = &dev->node;
+	link->dev_node = &dev->node;
 	link->state &= ~DEV_CONFIG_PENDING;
 
 	DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno,
@@ -631,8 +631,8 @@
 static int reader_attach(struct pcmcia_device *p_dev)
 {
 	struct reader_dev *dev;
-	dev_link_t *link;
 	int i;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	for (i = 0; i < CM_MAX_DEV; i++) {
 		if (dev_table[i] == NULL)
@@ -649,8 +649,8 @@
 	dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
 	dev->buffer_status = 0;
 
-	link = &dev->link;
 	link->priv = dev;
+	dev->p_dev = p_dev;
 
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	dev_table[i] = link;
@@ -662,9 +662,6 @@
 	init_timer(&dev->poll_timer);
 	dev->poll_timer.function = &cm4040_do_poll;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	reader_config(link, i);
 
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index a6cbd32..7b1e055 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -228,7 +228,7 @@
 	struct	_input_signal_events	input_signal_events;
 
 	/* PCMCIA support */
-	dev_link_t	      link;
+	struct pcmcia_device	*p_dev;
 	dev_node_t	      node;
 	int		      stop;
 
@@ -536,11 +536,11 @@
 static int mgslpc_attach(struct pcmcia_device *p_dev)
 {
     MGSLPC_INFO *info;
-    dev_link_t *link;
-    
+    dev_link_t *link = dev_to_instance(p_dev);
+
     if (debug_level >= DEBUG_LEVEL_INFO)
 	    printk("mgslpc_attach\n");
-	
+
     info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
     if (!info) {
 	    printk("Error can't allocate device instance data\n");
@@ -565,22 +565,19 @@
     info->imrb_value = 0xffff;
     info->pim_value = 0xff;
 
-    link = &info->link;
+    info->p_dev = p_dev;
     link->priv = info;
-    
+
     /* Initialize the dev_link_t structure */
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.IRQInfo1   = IRQ_LEVEL_ID;
     link->irq.Handler = NULL;
-    
+
     link->conf.Attributes = 0;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     mgslpc_config(link);
 
@@ -673,7 +670,7 @@
     /* add to linked list of devices */
     sprintf(info->node.dev_name, "mgslpc0");
     info->node.major = info->node.minor = 0;
-    link->dev = &info->node;
+    link->dev_node = &info->node;
 
     printk(KERN_INFO "%s: index 0x%02x:",
 	   info->node.dev_name, link->conf.ConfigIndex);
@@ -1259,7 +1256,7 @@
 	if (!info)
 		return IRQ_NONE;
 		
-	if (!(info->link.state & DEV_CONFIG))
+	if (!(info->p_dev->state & DEV_CONFIG))
 		return IRQ_HANDLED;
 
 	spin_lock(&info->lock);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 3b5b55f..70bb1b8 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -81,7 +81,7 @@
 };
 
 typedef struct ide_info_t {
-    dev_link_t	link;
+	struct pcmcia_device	*p_dev;
     int		ndev;
     dev_node_t	node;
     int		hd;
@@ -106,7 +106,7 @@
 static int ide_attach(struct pcmcia_device *p_dev)
 {
     ide_info_t *info;
-    dev_link_t *link;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "ide_attach()\n");
 
@@ -114,7 +114,9 @@
     info = kzalloc(sizeof(*info), GFP_KERNEL);
     if (!info)
 	return -ENOMEM;
-    link = &info->link; link->priv = info;
+
+    info->p_dev = p_dev;
+    link->priv = info;
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
@@ -124,9 +126,6 @@
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     ide_config(link);
 
@@ -326,7 +325,7 @@
     info->node.major = ide_major[hd];
     info->node.minor = 0;
     info->hd = hd;
-    link->dev = &info->node;
+    link->dev_node = &info->node;
     printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
 	   info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
 
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index 0c504dc..3b7461e 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -101,49 +101,37 @@
 
 static int avmcs_attach(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link;
     local_info_t *local;
 
-    /* Initialize the dev_link_t structure */
-    link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-    if (!link)
-        goto err;
-    memset(link, 0, sizeof(struct dev_link_t));
-
     /* The io structure describes IO port mapping */
-    link->io.NumPorts1 = 16;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    link->io.NumPorts2 = 0;
+    p_dev->io.NumPorts1 = 16;
+    p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+    p_dev->io.NumPorts2 = 0;
 
     /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
+    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    
+    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+
     /* General socket configuration */
-    link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-    link->conf.ConfigIndex = 1;
-    link->conf.Present = PRESENT_OPTION;
+    p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+    p_dev->conf.IntType = INT_MEMORY_AND_IO;
+    p_dev->conf.ConfigIndex = 1;
+    p_dev->conf.Present = PRESENT_OPTION;
 
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local)
-        goto err_kfree;
+        goto err;
     memset(local, 0, sizeof(local_info_t));
-    link->priv = local;
+    p_dev->priv = local;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
-    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-    avmcs_config(link);
+    p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    avmcs_config(p_dev);
 
     return 0;
 
- err_kfree:
-    kfree(link);
  err:
     return -EINVAL;
 } /* avmcs_attach */
@@ -165,7 +153,6 @@
 	avmcs_release(link);
 
     kfree(link->priv);
-    kfree(link);
 } /* avmcs_detach */
 
 /*======================================================================
@@ -330,7 +317,7 @@
 
     dev->node.major = 64;
     dev->node.minor = 0;
-    link->dev = &dev->node;
+    link->dev_node = &dev->node;
     
     link->state &= ~DEV_CONFIG_PENDING;
     /* If any step failed, release any partially configured state */
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 8d23e5a..f7143fe 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -118,50 +118,39 @@
 
 static int avma1cs_attach(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link;
     local_info_t *local;
 
     DEBUG(0, "avma1cs_attach()\n");
 
-    /* Initialize the dev_link_t structure */
-    link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-    if (!link)
-	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);
+    if (!local)
 	return -ENOMEM;
-    }
+
     memset(local, 0, sizeof(local_info_t));
-    link->priv = local;
+    p_dev->priv = local;
 
     /* The io structure describes IO port mapping */
-    link->io.NumPorts1 = 16;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    link->io.NumPorts2 = 16;
-    link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
-    link->io.IOAddrLines = 5;
+    p_dev->io.NumPorts1 = 16;
+    p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+    p_dev->io.NumPorts2 = 16;
+    p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
+    p_dev->io.IOAddrLines = 5;
 
     /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
+    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
 
     /* General socket configuration */
-    link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-    link->conf.ConfigIndex = 1;
-    link->conf.Present = PRESENT_OPTION;
+    p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+    p_dev->conf.IntType = INT_MEMORY_AND_IO;
+    p_dev->conf.ConfigIndex = 1;
+    p_dev->conf.Present = PRESENT_OPTION;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
-    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-    avma1cs_config(link);
+    p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    avma1cs_config(p_dev);
 
     return 0;
 } /* avma1cs_attach */
@@ -185,7 +174,6 @@
 	    avma1cs_release(link);
 
     kfree(link->priv);
-    kfree(link);
 } /* avma1cs_detach */
 
 /*======================================================================
@@ -335,7 +323,7 @@
     strcpy(dev->node.dev_name, "A1");
     dev->node.major = 45;
     dev->node.minor = 0;
-    link->dev = &dev->node;
+    link->dev_node = &dev->node;
     
     link->state &= ~DEV_CONFIG_PENDING;
     /* If any step failed, release any partially configured state */
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 00835d5..bcda675 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -121,7 +121,7 @@
 */
 
 typedef struct local_info_t {
-    dev_link_t          link;
+	struct pcmcia_device	*p_dev;
     dev_node_t          node;
     int                 busy;
     int			cardnr;
@@ -141,8 +141,8 @@
 
 static int elsa_cs_attach(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link;
     local_info_t *local;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "elsa_cs_attach()\n");
 
@@ -150,8 +150,11 @@
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local) return -ENOMEM;
     memset(local, 0, sizeof(local_info_t));
+
+    local->p_dev = p_dev;
+    link->priv = local;
+
     local->cardnr = -1;
-    link = &local->link; link->priv = local;
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
@@ -172,9 +175,6 @@
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     elsa_cs_config(link);
 
@@ -320,7 +320,7 @@
     sprintf(dev->node.dev_name, "elsa");
     dev->node.major = dev->node.minor = 0x0;
 
-    link->dev = &dev->node;
+    link->dev_node = &dev->node;
 
     /* Finally, report what we've done */
     printk(KERN_INFO "%s: index 0x%02x: ",
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index a3cd1c5..6025722 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -130,7 +130,7 @@
 */
    
 typedef struct local_info_t {
-    dev_link_t		link;
+	struct pcmcia_device	*p_dev;
     dev_node_t		node;
     int			stop;
     int			cardnr;
@@ -151,7 +151,7 @@
 static int sedlbauer_attach(struct pcmcia_device *p_dev)
 {
     local_info_t *local;
-    dev_link_t *link;
+    dev_link_t *link = dev_to_instance(p_dev);
     
     DEBUG(0, "sedlbauer_attach()\n");
 
@@ -160,8 +160,10 @@
     if (!local) return -ENOMEM;
     memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
-    link = &local->link; link->priv = local;
-    
+
+    local->p_dev = p_dev;
+    link->priv = local;
+
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
@@ -182,13 +184,9 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.IOAddrLines = 3;
 
-
     link->conf.Attributes = 0;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     sedlbauer_config(link);
 
@@ -397,7 +395,7 @@
     */
     sprintf(dev->node.dev_name, "sedlbauer");
     dev->node.major = dev->node.minor = 0;
-    link->dev = &dev->node;
+    link->dev_node = &dev->node;
 
     /* Finally, report what we've done */
     printk(KERN_INFO "%s: index 0x%02x:",
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 040f098..ea16ebf 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -112,7 +112,7 @@
 */
 
 typedef struct local_info_t {
-    dev_link_t          link;
+	struct pcmcia_device	*p_dev;
     dev_node_t          node;
     int                 busy;
     int			cardnr;
@@ -132,8 +132,8 @@
 
 static int teles_attach(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link;
     local_info_t *local;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "teles_attach()\n");
 
@@ -142,7 +142,9 @@
     if (!local) return -ENOMEM;
     memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
-    link = &local->link; link->priv = local;
+
+    local->p_dev = p_dev;
+    link->priv = local;
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
@@ -163,9 +165,6 @@
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     teles_cs_config(link);
 
@@ -311,7 +310,7 @@
     sprintf(dev->node.dev_name, "teles");
     dev->node.major = dev->node.minor = 0x0;
 
-    link->dev = &dev->node;
+    link->dev_node = &dev->node;
 
     /* Finally, report what we've done */
     printk(KERN_INFO "%s: index 0x%02x:",
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index 0026460..8259dca 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -54,7 +54,7 @@
 #define MAX_PCMCIA_ADDR	0x4000000
 
 struct pcmciamtd_dev {
-	dev_link_t	link;		/* PCMCIA link */
+	struct pcmcia_device	*p_dev;
 	dev_node_t	node;		/* device node */
 	caddr_t		win_base;	/* ioremapped address of PCMCIA window */
 	unsigned int	win_size;	/* size of window */
@@ -111,8 +111,8 @@
 	memreq_t mrq;
 	int ret;
 
-	if(!(dev->link.state & DEV_PRESENT)) {
-		DEBUG(1, "device removed state = 0x%4.4X", dev->link.state);
+	if(!(dev->p_dev->state & DEV_PRESENT)) {
+		DEBUG(1, "device removed state = 0x%4.4X", dev->p_dev->state);
 		return 0;
 	}
 
@@ -122,7 +122,7 @@
 		      dev->offset, mrq.CardOffset);
 		mrq.Page = 0;
 		if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) {
-			cs_error(dev->link.handle, MapMemPage, ret);
+			cs_error(dev->p_dev->handle, MapMemPage, ret);
 			return NULL;
 		}
 		dev->offset = mrq.CardOffset;
@@ -319,7 +319,7 @@
 static void pcmciamtd_set_vpp(struct map_info *map, int on)
 {
 	struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
-	dev_link_t *link = &dev->link;
+	dev_link_t *link = dev->p_dev;
 	modconf_t mod;
 	int ret;
 
@@ -650,7 +650,7 @@
 	   use the faster non-remapping read/write functions */
 	if(mtd->size <= dev->win_size) {
 		DEBUG(1, "Using non remapping memory functions");
-		dev->pcmcia_map.map_priv_1 = (unsigned long)&(dev->link.state);
+		dev->pcmcia_map.map_priv_1 = (unsigned long)&(dev->p_dev->state);
 		dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base;
 		if (dev->pcmcia_map.bankwidth == 1) {
 			dev->pcmcia_map.read = pcmcia_read8;
@@ -673,7 +673,7 @@
 	snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index);
 	info("mtd%d: %s", mtd->index, mtd->name);
 	link->state &= ~DEV_CONFIG_PENDING;
-	link->dev = &dev->node;
+	link->dev_node = &dev->node;
 	return;
 
  cs_failed:
@@ -735,7 +735,7 @@
 static int pcmciamtd_attach(struct pcmcia_device *p_dev)
 {
 	struct pcmciamtd_dev *dev;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	/* Create new memory card device */
 	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
@@ -743,16 +743,12 @@
 	DEBUG(1, "dev=0x%p", dev);
 
 	memset(dev, 0, sizeof(*dev));
-	link = &dev->link;
+	dev->p_dev = p_dev;
 	link->priv = dev;
 
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY;
 
-	link->next = NULL;
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	pcmciamtd_config(link);
 
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 179c9b7..b65758d 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -204,7 +204,7 @@
 #define MEDIA_TP	0x00C0	/* Enable link beat and jabber for 10baseT. */
 
 struct el3_private {
-	dev_link_t link;
+	struct pcmcia_device	*p_dev;
 	dev_node_t node;
 	struct net_device_stats stats;
 	u16 advertising, partner;		/* NWay media advertisement */
@@ -259,8 +259,8 @@
 static int tc574_attach(struct pcmcia_device *p_dev)
 {
 	struct el3_private *lp;
-	dev_link_t *link;
 	struct net_device *dev;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	DEBUG(0, "3c574_attach()\n");
 
@@ -269,8 +269,8 @@
 	if (!dev)
 		return -ENOMEM;
 	lp = netdev_priv(dev);
-	link = &lp->link;
 	link->priv = dev;
+	lp->p_dev = p_dev;
 
 	spin_lock_init(&lp->window_lock);
 	link->io.NumPorts1 = 32;
@@ -297,9 +297,6 @@
 	dev->watchdog_timeo = TX_TIMEOUT;
 #endif
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	tc574_config(link);
 
@@ -322,7 +319,7 @@
 
 	DEBUG(0, "3c574_detach(0x%p)\n", link);
 
-	if (link->dev)
+	if (link->dev_node)
 		unregister_netdev(dev);
 
 	if (link->state & DEV_CONFIG)
@@ -473,12 +470,12 @@
 	}
 
 	link->state &= ~DEV_CONFIG_PENDING;
-	link->dev = &lp->node;
+	link->dev_node = &lp->node;
 	SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
 	if (register_netdev(dev) != 0) {
 		printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
-		link->dev = NULL;
+		link->dev_node = NULL;
 		goto failed;
 	}
 
@@ -742,7 +739,7 @@
 static int el3_open(struct net_device *dev)
 {
 	struct el3_private *lp = netdev_priv(dev);
-	dev_link_t *link = &lp->link;
+	dev_link_t *link = lp->p_dev;
 
 	if (!DEV_OK(link))
 		return -ENODEV;
@@ -1188,7 +1185,7 @@
 {
 	kio_addr_t ioaddr = dev->base_addr;
 	struct el3_private *lp = netdev_priv(dev);
-	dev_link_t *link = &lp->link;
+	dev_link_t *link = lp->p_dev;
 
 	DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
 	
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 7e8036f..4faf1fa 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -105,7 +105,7 @@
 #define TX_TIMEOUT	((400*HZ)/1000)
 
 struct el3_private {
-    dev_link_t		link;
+	struct pcmcia_device	*p_dev;
     dev_node_t 		node;
     struct net_device_stats stats;
     /* For transceiver monitoring */
@@ -173,8 +173,8 @@
 static int tc589_attach(struct pcmcia_device *p_dev)
 {
     struct el3_private *lp;
-    dev_link_t *link;
     struct net_device *dev;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "3c589_attach()\n");
 
@@ -183,8 +183,8 @@
     if (!dev)
 	 return -ENOMEM;
     lp = netdev_priv(dev);
-    link = &lp->link;
     link->priv = dev;
+    lp->p_dev = p_dev;
 
     spin_lock_init(&lp->lock);
     link->io.NumPorts1 = 16;
@@ -212,9 +212,6 @@
 #endif
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     tc589_config(link);
 
@@ -237,7 +234,7 @@
 
     DEBUG(0, "3c589_detach(0x%p)\n", link);
 
-    if (link->dev)
+    if (link->dev_node)
 	unregister_netdev(dev);
 
     if (link->state & DEV_CONFIG)
@@ -345,13 +342,13 @@
     else
 	printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
     
-    link->dev = &lp->node;
+    link->dev_node = &lp->node;
     link->state &= ~DEV_CONFIG_PENDING;
     SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
-	link->dev = NULL;
+	link->dev_node = NULL;
 	goto failed;
     }
 
@@ -572,7 +569,7 @@
 static int el3_open(struct net_device *dev)
 {
     struct el3_private *lp = netdev_priv(dev);
-    dev_link_t *link = &lp->link;
+    dev_link_t *link = lp->p_dev;
     
     if (!DEV_OK(link))
 	return -ENODEV;
@@ -833,7 +830,7 @@
 {
     struct el3_private *lp = netdev_priv(dev);
     unsigned long flags;
-    dev_link_t *link = &lp->link;
+    dev_link_t *link = lp->p_dev;
 
     if (DEV_OK(link)) {
     	spin_lock_irqsave(&lp->lock, flags);
@@ -935,7 +932,7 @@
 static void set_multicast_list(struct net_device *dev)
 {
     struct el3_private *lp = netdev_priv(dev);
-    dev_link_t *link = &lp->link;
+    dev_link_t *link = lp->p_dev;
     kio_addr_t ioaddr = dev->base_addr;
     u16 opts = SetRxFilter | RxStation | RxBroadcast;
 
@@ -950,7 +947,7 @@
 static int el3_close(struct net_device *dev)
 {
     struct el3_private *lp = netdev_priv(dev);
-    dev_link_t *link = &lp->link;
+    dev_link_t *link = lp->p_dev;
     kio_addr_t ioaddr = dev->base_addr;
     
     DEBUG(1, "%s: shutting down ethercard.\n", dev->name);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 5ca0d57..58dc7c3 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -117,7 +117,7 @@
 /*====================================================================*/
 
 typedef struct axnet_dev_t {
-    dev_link_t		link;
+	struct pcmcia_device	*p_dev;
     dev_node_t		node;
     caddr_t		base;
     struct timer_list	watchdog;
@@ -145,8 +145,8 @@
 static int axnet_attach(struct pcmcia_device *p_dev)
 {
     axnet_dev_t *info;
-    dev_link_t *link;
     struct net_device *dev;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "axnet_attach()\n");
 
@@ -157,7 +157,7 @@
 	return -ENOMEM;
 
     info = PRIV(dev);
-    link = &info->link;
+    info->p_dev = p_dev;
     link->priv = dev;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
@@ -169,9 +169,6 @@
     dev->do_ioctl = &axnet_ioctl;
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     axnet_config(link);
 
@@ -194,7 +191,7 @@
 
     DEBUG(0, "axnet_detach(0x%p)\n", link);
 
-    if (link->dev)
+    if (link->dev_node)
 	unregister_netdev(dev);
 
     if (link->state & DEV_CONFIG)
@@ -409,13 +406,13 @@
     }
 
     info->phy_id = (i < 32) ? i : -1;
-    link->dev = &info->node;
+    link->dev_node = &info->node;
     link->state &= ~DEV_CONFIG_PENDING;
     SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
-	link->dev = NULL;
+	link->dev_node = NULL;
 	goto failed;
     }
 
@@ -543,7 +540,7 @@
 static int axnet_open(struct net_device *dev)
 {
     axnet_dev_t *info = PRIV(dev);
-    dev_link_t *link = &info->link;
+    dev_link_t *link = info->p_dev;
     
     DEBUG(2, "axnet_open('%s')\n", dev->name);
 
@@ -569,7 +566,7 @@
 static int axnet_close(struct net_device *dev)
 {
     axnet_dev_t *info = PRIV(dev);
-    dev_link_t *link = &info->link;
+    dev_link_t *link = info->p_dev;
 
     DEBUG(2, "axnet_close('%s')\n", dev->name);
 
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index e14d3d1..44da01c 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -140,7 +140,6 @@
 
 static int com20020_attach(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link;
     com20020_dev_t *info;
     struct net_device *dev;
     struct arcnet_local *lp;
@@ -148,10 +147,6 @@
     DEBUG(0, "com20020_attach()\n");
 
     /* Create new network device */
-    link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-    if (!link)
-	return -ENOMEM;
-
     info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
     if (!info)
 	goto fail_alloc_info;
@@ -161,7 +156,6 @@
 	goto fail_alloc_dev;
 
     memset(info, 0, sizeof(struct com20020_dev_t));
-    memset(link, 0, sizeof(struct dev_link_t));
     lp = dev->priv;
     lp->timeout = timeout;
     lp->backplane = backplane;
@@ -172,27 +166,26 @@
     /* fill in our module parameters as defaults */
     dev->dev_addr[0] = node;
 
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    link->io.NumPorts1 = 16;
-    link->io.IOAddrLines = 16;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-    link->conf.Present = PRESENT_OPTION;
+    p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+    p_dev->io.NumPorts1 = 16;
+    p_dev->io.IOAddrLines = 16;
+    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+    p_dev->conf.IntType = INT_MEMORY_AND_IO;
+    p_dev->conf.Present = PRESENT_OPTION;
 
-    link->irq.Instance = info->dev = dev;
-    link->priv = info;
+    p_dev->irq.Instance = info->dev = dev;
+    p_dev->priv = info;
 
-    link->state |= DEV_PRESENT;
-    com20020_config(link);
+    p_dev->state |= DEV_PRESENT;
+    com20020_config(p_dev);
 
     return 0;
 
 fail_alloc_dev:
     kfree(info);
 fail_alloc_info:
-    kfree(link);
     return -ENOMEM;
 } /* com20020_attach */
 
@@ -215,7 +208,7 @@
 
     DEBUG(0, "com20020_detach(0x%p)\n", link);
 
-    if (link->dev) {
+    if (link->dev_node) {
 	DEBUG(1,"unregister...\n");
 
 	unregister_netdev(dev);
@@ -244,8 +237,6 @@
 	DEBUG(1,"kfree2...\n");
 	kfree(info);
     }
-    DEBUG(1,"kfree3...\n");
-    kfree(link);
 
 } /* com20020_detach */
 
@@ -341,7 +332,7 @@
     lp->card_name = "PCMCIA COM20020";
     lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
 
-    link->dev = &info->node;
+    link->dev_node = &info->node;
     link->state &= ~DEV_CONFIG_PENDING;
     SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
@@ -349,7 +340,7 @@
     
     if (i != 0) {
 	DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
-	link->dev = NULL;
+	link->dev_node = NULL;
 	goto failed;
     }
 
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 34bf963..3f0ace4 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -116,7 +116,7 @@
     driver specific data structure
 */
 typedef struct local_info_t {
-    dev_link_t link;
+	struct pcmcia_device	*p_dev;
     dev_node_t node;
     struct net_device_stats stats;
     long open_time;
@@ -231,8 +231,8 @@
 static int fmvj18x_attach(struct pcmcia_device *p_dev)
 {
     local_info_t *lp;
-    dev_link_t *link;
     struct net_device *dev;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "fmvj18x_attach()\n");
 
@@ -241,8 +241,8 @@
     if (!dev)
 	return -ENOMEM;
     lp = netdev_priv(dev);
-    link = &lp->link;
     link->priv = dev;
+    lp->p_dev = p_dev;
 
     /* The io structure describes IO port mapping */
     link->io.NumPorts1 = 32;
@@ -273,9 +273,6 @@
 #endif
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     fmvj18x_config(link);
 
@@ -291,7 +288,7 @@
 
     DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
 
-    if (link->dev)
+    if (link->dev_node)
 	unregister_netdev(dev);
 
     if (link->state & DEV_CONFIG)
@@ -539,13 +536,13 @@
     }
 
     lp->cardtype = cardtype;
-    link->dev = &lp->node;
+    link->dev_node = &lp->node;
     link->state &= ~DEV_CONFIG_PENDING;
     SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
-	link->dev = NULL;
+	link->dev_node = NULL;
 	goto failed;
     }
 
@@ -1125,7 +1122,7 @@
 static int fjn_open(struct net_device *dev)
 {
     struct local_info_t *lp = netdev_priv(dev);
-    dev_link_t *link = &lp->link;
+    dev_link_t *link = lp->p_dev;
 
     DEBUG(4, "fjn_open('%s').\n", dev->name);
 
@@ -1150,7 +1147,7 @@
 static int fjn_close(struct net_device *dev)
 {
     struct local_info_t *lp = netdev_priv(dev);
-    dev_link_t *link = &lp->link;
+    dev_link_t *link = lp->p_dev;
     kio_addr_t ioaddr = dev->base_addr;
 
     DEBUG(4, "fjn_close('%s').\n", dev->name);
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index 904c5cb..f4c3dd8 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -113,7 +113,7 @@
 /*====================================================================*/
 
 typedef struct ibmtr_dev_t {
-    dev_link_t		link;
+	struct pcmcia_device	*p_dev;
     struct net_device	*dev;
     dev_node_t          node;
     window_handle_t     sram_win_handle;
@@ -141,8 +141,8 @@
 static int ibmtr_attach(struct pcmcia_device *p_dev)
 {
     ibmtr_dev_t *info;
-    dev_link_t *link;
     struct net_device *dev;
+    dev_link_t *link = dev_to_instance(p_dev);
     
     DEBUG(0, "ibmtr_attach()\n");
 
@@ -156,7 +156,7 @@
 	return -ENOMEM;
     }
 
-    link = &info->link;
+    info->p_dev = p_dev;
     link->priv = info;
     info->ti = netdev_priv(dev);
 
@@ -171,11 +171,8 @@
     link->conf.Present = PRESENT_OPTION;
 
     link->irq.Instance = info->dev = dev;
-    
-    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    link->handle = p_dev;
-    p_dev->instance = link;
+    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
     link->state |= DEV_PRESENT;
     ibmtr_config(link);
@@ -200,7 +197,7 @@
 
     DEBUG(0, "ibmtr_detach(0x%p)\n", link);
 
-    if (link->dev)
+    if (link->dev_node)
 	unregister_netdev(dev);
 
     {
@@ -308,14 +305,14 @@
         Adapters Technical Reference"  SC30-3585 for this info.  */
     ibmtr_hw_setup(dev, mmiobase);
 
-    link->dev = &info->node;
+    link->dev_node = &info->node;
     link->state &= ~DEV_CONFIG_PENDING;
     SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     i = ibmtr_probe_card(dev);
     if (i != 0) {
 	printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
-	link->dev = NULL;
+	link->dev_node = NULL;
 	goto failed;
     }
 
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index c25d945..0ccca12 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -362,7 +362,7 @@
 } mace_statistics;
 
 typedef struct _mace_private {
-    dev_link_t link;
+	struct pcmcia_device	*p_dev;
     dev_node_t node;
     struct net_device_stats linux_stats; /* Linux statistics counters */
     mace_statistics mace_stats; /* MACE chip statistics counters */
@@ -446,8 +446,8 @@
 static int nmclan_attach(struct pcmcia_device *p_dev)
 {
     mace_private *lp;
-    dev_link_t *link;
     struct net_device *dev;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "nmclan_attach()\n");
     DEBUG(1, "%s\n", rcsid);
@@ -457,7 +457,7 @@
     if (!dev)
 	    return -ENOMEM;
     lp = netdev_priv(dev);
-    link = &lp->link;
+    lp->p_dev = p_dev;
     link->priv = dev;
     
     spin_lock_init(&lp->bank_lock);
@@ -488,9 +488,6 @@
     dev->watchdog_timeo = TX_TIMEOUT;
 #endif
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     nmclan_config(link);
 
@@ -512,7 +509,7 @@
 
     DEBUG(0, "nmclan_detach(0x%p)\n", link);
 
-    if (link->dev)
+    if (link->dev_node)
 	unregister_netdev(dev);
 
     if (link->state & DEV_CONFIG)
@@ -729,14 +726,14 @@
   else
     printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
 
-  link->dev = &lp->node;
+  link->dev_node = &lp->node;
   link->state &= ~DEV_CONFIG_PENDING;
   SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
   i = register_netdev(dev);
   if (i != 0) {
     printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
-    link->dev = NULL;
+    link->dev_node = NULL;
     goto failed;
   }
 
@@ -869,7 +866,7 @@
 {
   kio_addr_t ioaddr = dev->base_addr;
   mace_private *lp = netdev_priv(dev);
-  dev_link_t *link = &lp->link;
+  dev_link_t *link = lp->p_dev;
 
   if (!DEV_OK(link))
     return -ENODEV;
@@ -892,7 +889,7 @@
 {
   kio_addr_t ioaddr = dev->base_addr;
   mace_private *lp = netdev_priv(dev);
-  dev_link_t *link = &lp->link;
+  dev_link_t *link = lp->p_dev;
 
   DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
 
@@ -947,7 +944,7 @@
 static void mace_tx_timeout(struct net_device *dev)
 {
   mace_private *lp = netdev_priv(dev);
-  dev_link_t *link = &lp->link;
+  dev_link_t *link = lp->p_dev;
 
   printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
 #if RESET_ON_TIMEOUT
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 5a7e58a..8ed6a41 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -214,7 +214,7 @@
 static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII };
 
 typedef struct pcnet_dev_t {
-    dev_link_t		link;
+	struct pcmcia_device	*p_dev;
     dev_node_t		node;
     u_int		flags;
     void		__iomem *base;
@@ -243,8 +243,8 @@
 static int pcnet_probe(struct pcmcia_device *p_dev)
 {
     pcnet_dev_t *info;
-    dev_link_t *link;
     struct net_device *dev;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "pcnet_attach()\n");
 
@@ -252,7 +252,7 @@
     dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
     if (!dev) return -ENOMEM;
     info = PRIV(dev);
-    link = &info->link;
+    info->p_dev = p_dev;
     link->priv = dev;
 
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -265,9 +265,6 @@
     dev->stop = &pcnet_close;
     dev->set_config = &set_config;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     pcnet_config(link);
 
@@ -290,7 +287,7 @@
 
 	DEBUG(0, "pcnet_detach(0x%p)\n", link);
 
-	if (link->dev)
+	if (link->dev_node)
 		unregister_netdev(dev);
 
 	if (link->state & DEV_CONFIG)
@@ -674,7 +671,7 @@
 	    info->eth_phy = 0;
     }
 
-    link->dev = &info->node;
+    link->dev_node = &info->node;
     link->state &= ~DEV_CONFIG_PENDING;
     SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
@@ -684,7 +681,7 @@
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
-	link->dev = NULL;
+	link->dev_node = NULL;
 	goto failed;
     }
 
@@ -1005,8 +1002,8 @@
 static int pcnet_open(struct net_device *dev)
 {
     pcnet_dev_t *info = PRIV(dev);
-    dev_link_t *link = &info->link;
-    
+    dev_link_t *link = info->p_dev;
+
     DEBUG(2, "pcnet_open('%s')\n", dev->name);
 
     if (!DEV_OK(link))
@@ -1033,7 +1030,7 @@
 static int pcnet_close(struct net_device *dev)
 {
     pcnet_dev_t *info = PRIV(dev);
-    dev_link_t *link = &info->link;
+    dev_link_t *link = info->p_dev;
 
     DEBUG(2, "pcnet_close('%s')\n", dev->name);
 
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index b46b7e1..a18b02a 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -104,7 +104,7 @@
 #define MEMORY_WAIT_TIME       	8
 
 struct smc_private {
-    dev_link_t			link;
+	struct pcmcia_device	*p_dev;
     spinlock_t			lock;
     u_short			manfid;
     u_short			cardid;
@@ -312,8 +312,8 @@
 static int smc91c92_attach(struct pcmcia_device *p_dev)
 {
     struct smc_private *smc;
-    dev_link_t *link;
     struct net_device *dev;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "smc91c92_attach()\n");
 
@@ -322,7 +322,7 @@
     if (!dev)
 	return -ENOMEM;
     smc = netdev_priv(dev);
-    link = &smc->link;
+    smc->p_dev = p_dev;
     link->priv = dev;
 
     spin_lock_init(&smc->lock);
@@ -357,9 +357,6 @@
     smc->mii_if.phy_id_mask = 0x1f;
     smc->mii_if.reg_num_mask = 0x1f;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     smc91c92_config(link);
 
@@ -382,7 +379,7 @@
 
     DEBUG(0, "smc91c92_detach(0x%p)\n", link);
 
-    if (link->dev)
+    if (link->dev_node)
 	unregister_netdev(dev);
 
     if (link->state & DEV_CONFIG)
@@ -1120,13 +1117,13 @@
 	SMC_SELECT_BANK(0);
     }
 
-    link->dev = &smc->node;
+    link->dev_node = &smc->node;
     link->state &= ~DEV_CONFIG_PENDING;
     SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
-	link->dev = NULL;
+	link->dev_node = NULL;
 	goto config_undo;
     }
 
@@ -1272,7 +1269,7 @@
 static int smc_open(struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    dev_link_t *link = &smc->link;
+    dev_link_t *link = smc->p_dev;
 
 #ifdef PCMCIA_DEBUG
     DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n",
@@ -1309,7 +1306,7 @@
 static int smc_close(struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    dev_link_t *link = &smc->link;
+    dev_link_t *link = smc->p_dev;
     kio_addr_t ioaddr = dev->base_addr;
 
     DEBUG(0, "%s: smc_close(), status %4.4x.\n",
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index f5fa86d..94a1e64 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -332,7 +332,7 @@
  */
 
 typedef struct local_info_t {
-    dev_link_t link;
+	struct pcmcia_device	*p_dev;
     dev_node_t node;
     struct net_device_stats stats;
     int card_type;
@@ -555,9 +555,9 @@
 static int
 xirc2ps_attach(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link;
     struct net_device *dev;
     local_info_t *local;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "attach()\n");
 
@@ -566,7 +566,7 @@
     if (!dev)
 	    return -ENOMEM;
     local = netdev_priv(dev);
-    link = &local->link;
+    local->p_dev = p_dev;
     link->priv = dev;
 
     /* General socket configuration */
@@ -592,9 +592,6 @@
     dev->watchdog_timeo = TX_TIMEOUT;
 #endif
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     xirc2ps_config(link);
 
@@ -616,7 +613,7 @@
 
     DEBUG(0, "detach(0x%p)\n", link);
 
-    if (link->dev)
+    if (link->dev_node)
 	unregister_netdev(dev);
 
     if (link->state & DEV_CONFIG)
@@ -1049,13 +1046,13 @@
     if (local->dingo)
 	do_reset(dev, 1); /* a kludge to make the cem56 work */
 
-    link->dev = &local->node;
+    link->dev_node = &local->node;
     link->state &= ~DEV_CONFIG_PENDING;
     SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     if ((err=register_netdev(dev))) {
 	printk(KNOT_XIRC "register_netdev() failed\n");
-	link->dev = NULL;
+	link->dev_node = NULL;
 	goto config_error;
     }
 
@@ -1537,7 +1534,7 @@
 do_open(struct net_device *dev)
 {
     local_info_t *lp = netdev_priv(dev);
-    dev_link_t *link = &lp->link;
+    dev_link_t *link = lp->p_dev;
 
     DEBUG(0, "do_open(%p)\n", dev);
 
@@ -1867,7 +1864,7 @@
 {
     kio_addr_t ioaddr = dev->base_addr;
     local_info_t *lp = netdev_priv(dev);
-    dev_link_t *link = &lp->link;
+    dev_link_t *link = lp->p_dev;
 
     DEBUG(0, "do_stop(%p)\n", dev);
 
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 2216c04..836c71f 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -143,22 +143,14 @@
 
 static int airo_attach(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link;
 	local_info_t *local;
 
 	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 -ENOMEM;
-	}
-	
 	/* Interrupt setup */
-	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-	link->irq.Handler = NULL;
+	p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	p_dev->irq.Handler = NULL;
 	
 	/*
 	  General socket configuration defaults can go here.  In this
@@ -167,23 +159,19 @@
 	  and attributes of IO windows) are fixed by the nature of the
 	  device, and can be hard-wired here.
 	*/
-	link->conf.Attributes = 0;
-	link->conf.IntType = INT_MEMORY_AND_IO;
+	p_dev->conf.Attributes = 0;
+	p_dev->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 "airo_cs: no memory for new device\n");
-		kfree (link);
 		return -ENOMEM;
 	}
-	link->priv = local;
+	p_dev->priv = local;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	airo_config(link);
+	p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	airo_config(p_dev);
 
 	return 0;
 } /* airo_attach */
@@ -212,7 +200,6 @@
 	((local_info_t*)link->priv)->eth_dev = NULL;
 
 	kfree(link->priv);
-	kfree(link);
 } /* airo_detach */
 
 /*======================================================================
@@ -378,11 +365,11 @@
 	
 	/*
 	  At this point, the dev_node_t structure(s) need to be
-	  initialized and arranged in a linked list at link->dev.
+	  initialized and arranged in a linked list at link->dev_node.
 	*/
 	strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
 	dev->node.major = dev->node.minor = 0;
-	link->dev = &dev->node;
+	link->dev_node = &dev->node;
 	
 	/* Finally, report what we've done */
 	printk(KERN_INFO "%s: index 0x%02x: ",
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 53fdaa2..522bbed 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -154,22 +154,14 @@
 
 static int atmel_attach(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link;
 	local_info_t *local;
 
 	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 -ENOMEM;
-	}
-
 	/* Interrupt setup */
-	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-	link->irq.Handler = NULL;
+	p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	p_dev->irq.Handler = NULL;
 
 	/*
 	  General socket configuration defaults can go here.  In this
@@ -178,23 +170,19 @@
 	  and attributes of IO windows) are fixed by the nature of the
 	  device, and can be hard-wired here.
 	*/
-	link->conf.Attributes = 0;
-	link->conf.IntType = INT_MEMORY_AND_IO;
+	p_dev->conf.Attributes = 0;
+	p_dev->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 -ENOMEM;
 	}
-	link->priv = local;
+	p_dev->priv = local;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	atmel_config(link);
+	p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	atmel_config(p_dev);
 
 	return 0;
 } /* atmel_attach */
@@ -218,7 +206,6 @@
 		atmel_release(link);
 
 	kfree(link->priv);
-	kfree(link);
 }
 
 /*======================================================================
@@ -387,11 +374,11 @@
 	
 	/*
 	  At this point, the dev_node_t structure(s) need to be
-	  initialized and arranged in a linked list at link->dev.
+	  initialized and arranged in a linked list at link->dev_node.
 	*/
 	strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
 	dev->node.major = dev->node.minor = 0;
-	link->dev = &dev->node;
+	link->dev_node = &dev->node;
 			
 	link->state &= ~DEV_CONFIG_PENDING;
 	return;
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 69024bfb..e3095a8 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -503,22 +503,11 @@
  * initialize dev_link structure, but do not configure the card yet */
 static int prism2_attach(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link;
-
-	link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
-	if (link == NULL)
-		return -ENOMEM;
-
-	memset(link, 0, sizeof(dev_link_t));
-
 	PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
-	link->conf.IntType = INT_MEMORY_AND_IO;
+	p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	if (prism2_config(link))
+	p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	if (prism2_config(p_dev))
 		PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
 
 	return 0;
@@ -546,7 +535,6 @@
 		prism2_free_local_data(dev);
 		kfree(hw_priv);
 	}
-	kfree(link);
 }
 
 
@@ -713,7 +701,7 @@
 	local->hw_priv = hw_priv;
 	hw_priv->link = link;
 	strcpy(hw_priv->node.dev_name, dev->name);
-	link->dev = &hw_priv->node;
+	link->dev_node = &hw_priv->node;
 
 	/*
 	 * Allocate an interrupt line.  Note that this does not assign a
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 23d6b33..68dfe68 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -268,7 +268,7 @@
 };	
    
 typedef struct netwave_private {
-    dev_link_t link;
+	struct pcmcia_device	*p_dev;
     spinlock_t	spinlock;	/* Serialize access to the hardware (SMP) */
     dev_node_t node;
     u_char     __iomem *ramBase;
@@ -378,9 +378,9 @@
  */
 static int netwave_attach(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link;
     struct net_device *dev;
     netwave_private *priv;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "netwave_attach()\n");
 
@@ -389,7 +389,7 @@
     if (!dev)
 	return -ENOMEM;
     priv = netdev_priv(dev);
-    link = &priv->link;
+    priv->p_dev = p_dev;
     link->priv = dev;
 
     /* The io structure describes IO port mapping */
@@ -429,9 +429,6 @@
     dev->stop = &netwave_close;
     link->irq.Instance = dev;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     netwave_pcmcia_config( link);
 
@@ -456,7 +453,7 @@
 	if (link->state & DEV_CONFIG)
 		netwave_release(link);
 
-	if (link->dev)
+	if (link->dev_node)
 		unregister_netdev(dev);
 
 	free_netdev(dev);
@@ -830,7 +827,7 @@
     }
 
     strcpy(priv->node.dev_name, dev->name);
-    link->dev = &priv->node;
+    link->dev_node = &priv->node;
     link->state &= ~DEV_CONFIG_PENDING;
 
     /* Reset card before reading physical address */
@@ -1103,7 +1100,7 @@
     u_char __iomem *ramBase;
     struct net_device *dev = (struct net_device *)dev_id;
     struct netwave_private *priv = netdev_priv(dev);
-    dev_link_t *link = &priv->link;
+    dev_link_t *link = priv->p_dev;
     int i;
     
     if (!netif_device_present(dev))
@@ -1357,7 +1354,7 @@
 
 static int netwave_open(struct net_device *dev) {
     netwave_private *priv = netdev_priv(dev);
-    dev_link_t *link = &priv->link;
+    dev_link_t *link = priv->p_dev;
 
     DEBUG(1, "netwave_open: starting.\n");
     
@@ -1374,7 +1371,7 @@
 
 static int netwave_close(struct net_device *dev) {
     netwave_private *priv = netdev_priv(dev);
-    dev_link_t *link = &priv->link;
+    dev_link_t *link = priv->p_dev;
 
     DEBUG(1, "netwave_close: finishing.\n");
 
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 75981d8..f10d97b 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -49,7 +49,7 @@
 /* PCMCIA specific device information (goes in the card field of
  * struct orinoco_private */
 struct orinoco_pccard {
-	dev_link_t link;
+	struct pcmcia_device	*p_dev;
 	dev_node_t node;
 
 	/* Used to handle hard reset */
@@ -75,7 +75,7 @@
 orinoco_cs_hard_reset(struct orinoco_private *priv)
 {
 	struct orinoco_pccard *card = priv->card;
-	dev_link_t *link = &card->link;
+	dev_link_t *link = card->p_dev;
 	int err;
 
 	/* We need atomic ops here, because we're not holding the lock */
@@ -109,7 +109,7 @@
 	struct net_device *dev;
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
 	if (! dev)
@@ -118,7 +118,7 @@
 	card = priv->card;
 
 	/* Link both structures together */
-	link = &card->link;
+	card->p_dev = p_dev;
 	link->priv = dev;
 
 	/* Interrupt setup */
@@ -135,12 +135,6 @@
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = NULL;
-
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	orinoco_cs_config(link);
 
@@ -161,8 +155,8 @@
 	if (link->state & DEV_CONFIG)
 		orinoco_cs_release(link);
 
-	DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
-	if (link->dev) {
+	DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node);
+	if (link->dev_node) {
 		DEBUG(0, PFX "About to unregister net device %p\n",
 		      dev);
 		unregister_netdev(dev);
@@ -364,9 +358,9 @@
 	}
 
 	/* At this point, the dev_node_t structure(s) needs to be
-	 * initialized and arranged in a linked list at link->dev. */
+	 * initialized and arranged in a linked list at link->dev_node. */
 	strcpy(card->node.dev_name, dev->name);
-	link->dev = &card->node; /* link->dev being non-NULL is also
+	link->dev_node = &card->node; /* link->dev_node being non-NULL is also
                                     used to indicate that the
                                     net_device has been registered */
 	link->state &= ~DEV_CONFIG_PENDING;
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 7d95587d..6029746 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -190,12 +190,6 @@
 static char *phy_addr = NULL;
 
 
-/* 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).
-*/
-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
@@ -204,6 +198,9 @@
 */
 static unsigned int ray_mem_speed = 500;
 
+/* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */
+static struct pcmcia_device *this_device = NULL;
+
 MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
 MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
 MODULE_LICENSE("GPL");
@@ -308,53 +305,44 @@
 =============================================================================*/
 static int ray_attach(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link;
     ray_dev_t *local;
     struct net_device *dev;
-    
+
     DEBUG(1, "ray_attach()\n");
 
-    /* Initialize the dev_link_t structure */
-    link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-
-    if (!link)
-	    return -ENOMEM;
-
     /* Allocate space for private device-specific data */
     dev = alloc_etherdev(sizeof(ray_dev_t));
-
     if (!dev)
 	    goto fail_alloc_dev;
 
     local = dev->priv;
-
-    memset(link, 0, sizeof(struct dev_link_t));
+    local->finder = p_dev;
 
     /* The io structure describes IO port mapping. None used here */
-    link->io.NumPorts1 = 0;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    link->io.IOAddrLines = 5;
+    p_dev->io.NumPorts1 = 0;
+    p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+    p_dev->io.IOAddrLines = 5;
 
     /* Interrupt setup. For PCMCIA, driver takes what's given */
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    link->irq.Handler = &ray_interrupt;
+    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    p_dev->irq.Handler = &ray_interrupt;
 
     /* General socket configuration */
-    link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-    link->conf.ConfigIndex = 1;
-    link->conf.Present = PRESENT_OPTION;
+    p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+    p_dev->conf.IntType = INT_MEMORY_AND_IO;
+    p_dev->conf.ConfigIndex = 1;
+    p_dev->conf.Present = PRESENT_OPTION;
 
-    link->priv = dev;
-    link->irq.Instance = dev;
+    p_dev->priv = dev;
+    p_dev->irq.Instance = dev;
     
-    local->finder = link;
+    local->finder = p_dev;
     local->card_status = CARD_INSERTED;
     local->authentication_state = UNAUTHENTICATED;
     local->num_multi = 0;
-    DEBUG(2,"ray_attach link = %p,  dev = %p,  local = %p, intr = %p\n",
-          link,dev,local,&ray_interrupt);
+    DEBUG(2,"ray_attach p_dev = %p,  dev = %p,  local = %p, intr = %p\n",
+          p_dev,dev,local,&ray_interrupt);
 
     /* Raylink entries in the device structure */
     dev->hard_start_xmit = &ray_dev_start_xmit;
@@ -378,16 +366,13 @@
 
     init_timer(&local->timer);
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
-    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-    ray_config(link);
+    p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    this_device = p_dev;
+    ray_config(p_dev);
 
     return 0;
 
 fail_alloc_dev:
-    kfree(link);
     return -ENOMEM;
 } /* ray_attach */
 /*=============================================================================
@@ -399,18 +384,12 @@
 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);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-        if (*linkp == link) break;
-    if (*linkp == NULL)
-        return;
 
+    this_device = NULL;
     dev = link->priv;
 
     if (link->state & DEV_CONFIG) {
@@ -420,13 +399,10 @@
             del_timer(&local->timer);
     }
 
-    /* Unlink device structure, free pieces */
-    *linkp = link->next;
     if (link->priv) {
-	if (link->dev) unregister_netdev(dev);
+	if (link->dev_node) unregister_netdev(dev);
         free_netdev(dev);
     }
-    kfree(link);
     DEBUG(2,"ray_cs ray_detach ending\n");
 } /* ray_detach */
 /*=============================================================================
@@ -537,7 +513,7 @@
     }
 
     strcpy(local->node.dev_name, dev->name);
-    link->dev = &local->node;
+    link->dev_node = &local->node;
 
     link->state &= ~DEV_CONFIG_PENDING;
     printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
@@ -1640,18 +1616,14 @@
 /*===========================================================================*/
 static int ray_open(struct net_device *dev)
 {
-    dev_link_t *link;
     ray_dev_t *local = (ray_dev_t *)dev->priv;
+    dev_link_t *link;
+    link = local->finder;
     
     DEBUG(1, "ray_open('%s')\n", dev->name);
 
-    for (link = dev_list; link; link = link->next)
-        if (link->priv == dev) break;
-    if (!DEV_OK(link)) {
-        return -ENODEV;
-    }
-
-    if (link->open == 0) local->num_multi = 0;
+    if (link->open == 0)
+	    local->num_multi = 0;
     link->open++;
 
     /* If the card is not started, time to start it ! - Jean II */
@@ -1678,15 +1650,12 @@
 /*===========================================================================*/
 static int ray_dev_close(struct net_device *dev)
 {
+    ray_dev_t *local = (ray_dev_t *)dev->priv;
     dev_link_t *link;
+    link = local->finder;
 
     DEBUG(1, "ray_dev_close('%s')\n", dev->name);
 
-    for (link = dev_list; link; link = link->next)
-        if (link->priv == dev) break;
-    if (link == NULL)
-        return -ENODEV;
-
     link->open--;
     netif_stop_queue(dev);
 
@@ -2679,7 +2648,7 @@
     struct freq_hop_element *pfh;
     UCHAR c[33];
 
-    link = dev_list;
+    link = this_device;
     if (!link)
     	return 0;
     dev = (struct net_device *)link->priv;
@@ -2923,7 +2892,6 @@
 #endif
 
     pcmcia_unregister_driver(&ray_driver);
-    BUG_ON(dev_list != NULL);
 } /* exit_ray_cs */
 
 module_init(init_ray_cs);
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 7a4a80b..be36679 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -63,7 +63,7 @@
 /* PCMCIA specific device information (goes in the card field of
  * struct orinoco_private */
 struct orinoco_pccard {
-	dev_link_t link;
+	struct pcmcia_device	*p_dev;
 	dev_node_t node;
 };
 
@@ -554,12 +554,12 @@
 spectrum_cs_hard_reset(struct orinoco_private *priv)
 {
 	struct orinoco_pccard *card = priv->card;
-	dev_link_t *link = &card->link;
+	dev_link_t *link = card->p_dev;
 	int err;
 
 	if (!hermes_present(&priv->hw)) {
 		/* The firmware needs to be reloaded */
-		if (spectrum_dl_firmware(&priv->hw, &card->link) != 0) {
+		if (spectrum_dl_firmware(&priv->hw, link) != 0) {
 			printk(KERN_ERR PFX "Firmware download failed\n");
 			err = -ENODEV;
 		}
@@ -589,7 +589,7 @@
 	struct net_device *dev;
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
 	if (! dev)
@@ -598,7 +598,7 @@
 	card = priv->card;
 
 	/* Link both structures together */
-	link = &card->link;
+	card->p_dev = p_dev;
 	link->priv = dev;
 
 	/* Interrupt setup */
@@ -615,9 +615,6 @@
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	spectrum_cs_config(link);
 
@@ -638,8 +635,8 @@
 	if (link->state & DEV_CONFIG)
 		spectrum_cs_release(link);
 
-	DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
-	if (link->dev) {
+	DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node);
+	if (link->dev_node) {
 		DEBUG(0, PFX "About to unregister net device %p\n",
 		      dev);
 		unregister_netdev(dev);
@@ -842,9 +839,9 @@
 	}
 
 	/* At this point, the dev_node_t structure(s) needs to be
-	 * initialized and arranged in a linked list at link->dev. */
+	 * initialized and arranged in a linked list at link->dev_node. */
 	strcpy(card->node.dev_name, dev->name);
-	link->dev = &card->node; /* link->dev being non-NULL is also
+	link->dev_node = &card->node; /* link->dev_node being non-NULL is also
                                     used to indicate that the
                                     net_device has been registered */
 	link->state &= ~DEV_CONFIG_PENDING;
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index daa17dc..baa1011 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4081,7 +4081,7 @@
     }
 
   strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name);
-  link->dev = &((net_local *) netdev_priv(dev))->node;
+  link->dev_node = &((net_local *) netdev_priv(dev))->node;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "<-wv_pcmcia_config()\n");
@@ -4583,7 +4583,6 @@
 static int
 wavelan_attach(struct pcmcia_device *p_dev)
 {
-  dev_link_t *	link;		/* Info for cardmgr */
   struct net_device *	dev;		/* Interface generic data */
   net_local *	lp;		/* Interface specific data */
 
@@ -4591,34 +4590,26 @@
   printk(KERN_DEBUG "-> wavelan_attach()\n");
 #endif
 
-  /* Initialize the dev_link_t structure */
-  link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-  if (!link) return -ENOMEM;
-
   /* The io structure describes IO port mapping */
-  link->io.NumPorts1 = 8;
-  link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-  link->io.IOAddrLines = 3;
+  p_dev->io.NumPorts1 = 8;
+  p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+  p_dev->io.IOAddrLines = 3;
 
   /* Interrupt setup */
-  link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-  link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-  link->irq.Handler = wavelan_interrupt;
+  p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+  p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+  p_dev->irq.Handler = wavelan_interrupt;
 
   /* General socket configuration */
-  link->conf.Attributes = CONF_ENABLE_IRQ;
-  link->conf.IntType = INT_MEMORY_AND_IO;
-
-  /* Chain drivers */
-  link->next = NULL;
+  p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+  p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
   /* Allocate the generic data structure */
   dev = alloc_etherdev(sizeof(net_local));
-  if (!dev) {
-      kfree(link);
+  if (!dev)
       return -ENOMEM;
-  }
-  link->priv = link->irq.Instance = dev;
+
+  p_dev->priv = p_dev->irq.Instance = dev;
 
   lp = netdev_priv(dev);
 
@@ -4635,7 +4626,6 @@
   spin_lock_init(&lp->spinlock);
 
   /* back links */
-  lp->link = link;
   lp->dev = dev;
 
   /* wavelan NET3 callbacks */
@@ -4661,11 +4651,8 @@
   /* Other specific data */
   dev->mtu = WAVELAN_MTU;
 
-  link->handle = p_dev;
-  p_dev->instance = link;
-
-  link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-  if(wv_pcmcia_config(link) &&
+  p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+  if(wv_pcmcia_config(p_dev) &&
      wv_hw_config(dev))
 	  wv_init_info(dev);
   else
@@ -4713,14 +4700,13 @@
 
       /* Remove ourselves from the kernel list of ethernet devices */
       /* Warning : can't be called from interrupt, timer or wavelan_close() */
-      if (link->dev)
+      if (link->dev_node)
 	unregister_netdev(dev);
-      link->dev = NULL;
+      link->dev_node = NULL;
       ((net_local *)netdev_priv(dev))->link = NULL;
       ((net_local *)netdev_priv(dev))->dev = NULL;
       free_netdev(dev);
     }
-  kfree(link);
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "<- wavelan_detach()\n");
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
index 4303c50..65ceb08 100644
--- a/drivers/net/wireless/wl3501.h
+++ b/drivers/net/wireless/wl3501.h
@@ -611,5 +611,6 @@
 	struct iw_spy_data		spy_data;
 	struct iw_public_data		wireless_data;
 	struct dev_node_t		node;
+	struct pcmcia_device		*p_dev;
 };
 #endif
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 393b5cb..4b054f5 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -226,17 +226,6 @@
 	iw_set_mgmt_info_element(from->id, to, from->data, from->len);
 }
 
-/*
- * A linked list of "instances" of the wl24 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 *wl3501_dev_list;
-
 static inline void wl3501_switch_page(struct wl3501_card *this, u8 page)
 {
 	wl3501_outb(page, this->base_addr + WL3501_NIC_BSS);
@@ -1282,14 +1271,9 @@
 	int rc = -ENODEV;
 	unsigned long flags;
 	dev_link_t *link;
+	link = this->p_dev;
 
 	spin_lock_irqsave(&this->lock, flags);
-	/* Check if the device is in wl3501_dev_list */
-	for (link = wl3501_dev_list; link; link = link->next)
-		if (link->priv == dev)
-			break;
-	if (!link)
-		goto out;
 	link->open--;
 
 	/* Stop wl3501_hard_start_xmit() from now on */
@@ -1301,7 +1285,6 @@
 
 	rc = 0;
 	printk(KERN_INFO "%s: WL3501 closed\n", dev->name);
-out:
 	spin_unlock_irqrestore(&this->lock, flags);
 	return rc;
 }
@@ -1401,12 +1384,9 @@
 	struct wl3501_card *this = dev->priv;
 	unsigned long flags;
 	dev_link_t *link;
+	link = this->p_dev;
 
 	spin_lock_irqsave(&this->lock, flags);
-	/* Check if the device is in wl3501_dev_list */
-	for (link = wl3501_dev_list; link; link = link->next)
-		if (link->priv == dev)
-			break;
 	if (!DEV_OK(link))
 		goto out;
 	netif_device_attach(dev);
@@ -1500,16 +1480,8 @@
 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)
-		if (*linkp == link)
-			break;
-	if (!*linkp)
-		goto out;
-
 	/* 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(). */
@@ -1522,13 +1494,9 @@
 		wl3501_release(link);
 	}
 
-	/* Unlink device structure, free pieces */
-	*linkp = link->next;
-
 	if (link->priv)
 		free_netdev(link->priv);
-	kfree(link);
-out:
+
 	return;
 }
 
@@ -1955,14 +1923,9 @@
  */
 static int wl3501_attach(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link;
 	struct net_device *dev;
 	struct wl3501_card *this;
-
-	/* Initialize the dev_link_t structure */
-	link = kzalloc(sizeof(*link), GFP_KERNEL);
-	if (!link)
-		return -ENOMEM;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	/* The io structure describes IO port mapping */
 	link->io.NumPorts1	= 16;
@@ -1991,22 +1954,18 @@
 	dev->get_stats		= wl3501_get_stats;
 	this = dev->priv;
 	this->wireless_data.spy_data = &this->spy_data;
+	this->p_dev = p_dev;
 	dev->wireless_data	= &this->wireless_data;
 	dev->wireless_handlers	= (struct iw_handler_def *)&wl3501_handler_def;
 	SET_ETHTOOL_OPS(dev, &ops);
 	netif_stop_queue(dev);
 	link->priv = link->irq.Instance = dev;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	wl3501_config(link);
+	wl3501_config(p_dev);
 
 	return 0;
 out_link:
-	kfree(link);
-	link = NULL;
 	return -ENOMEM;
 }
 
@@ -2087,9 +2046,9 @@
 	this = dev->priv;
 	/*
 	 * At this point, the dev_node_t structure(s) should be initialized and
-	 * arranged in a linked list at link->dev.
+	 * arranged in a linked list at link->dev_node.
 	 */
-	link->dev = &this->node;
+	link->dev_node = &this->node;
 	link->state &= ~DEV_CONFIG_PENDING;
 
 	this->base_addr = dev->base_addr;
@@ -2148,7 +2107,7 @@
 	struct net_device *dev = link->priv;
 
 	/* Unlink the device chain */
-	if (link->dev)
+	if (link->dev_node)
 		unregister_netdev(dev);
 
 	pcmcia_disable_device(link->handle);
@@ -2206,9 +2165,7 @@
 
 static void __exit wl3501_exit_module(void)
 {
-	dprintk(0, ": unloading");
 	pcmcia_unregister_driver(&wl3501_driver);
-	BUG_ON(wl3501_dev_list != NULL);
 }
 
 module_init(wl3501_init_module);
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 8d60146..ad2738a 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -81,7 +81,7 @@
 #define FORCE_EPP_MODE	0x08
 
 typedef struct parport_info_t {
-    dev_link_t		link;
+	struct pcmcia_device	*p_dev;
     int			ndev;
     dev_node_t		node;
     struct parport	*port;
@@ -102,7 +102,7 @@
 static int parport_attach(struct pcmcia_device *p_dev)
 {
     parport_info_t *info;
-    dev_link_t *link;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "parport_attach()\n");
 
@@ -110,7 +110,8 @@
     info = kmalloc(sizeof(*info), GFP_KERNEL);
     if (!info) return -ENOMEM;
     memset(info, 0, sizeof(*info));
-    link = &info->link; link->priv = info;
+    link->priv = info;
+    info->p_dev = p_dev;
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
@@ -119,9 +120,6 @@
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     parport_config(link);
 
@@ -239,7 +237,7 @@
     info->node.minor = p->number;
     info->port = p;
     strcpy(info->node.dev_name, p->name);
-    link->dev = &info->node;
+    link->dev_node = &info->node;
 
     link->state &= ~DEV_CONFIG_PENDING;
     return;
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 488448a..4ab9568 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -391,6 +391,7 @@
 	}
 
 	p_dev->p_state &= ~CLIENT_UNBOUND;
+	p_dev->handle = p_dev;
 
 	ret = p_drv->probe(p_dev);
 	if (ret)
@@ -1039,12 +1040,10 @@
 		ret = p_drv->suspend(p_dev);
 		if (ret)
 			return ret;
-		if (p_dev->instance) {
-			p_dev->instance->state |= DEV_SUSPEND;
-			if ((p_dev->instance->state & DEV_CONFIG) &&
-			    !(p_dev->instance->state & DEV_SUSPEND_NORELEASE))
+		p_dev->state |= DEV_SUSPEND;
+			if ((p_dev->state & DEV_CONFIG) &&
+			    !(p_dev->state & DEV_SUSPEND_NORELEASE))
 				pcmcia_release_configuration(p_dev);
-		}
 	}
 
 	return 0;
@@ -1061,16 +1060,14 @@
 		p_drv = to_pcmcia_drv(dev->driver);
 
 	if (p_drv && p_drv->resume) {
-		if (p_dev->instance) {
-			p_dev->instance->state &= ~DEV_SUSPEND;
-			if ((p_dev->instance->state & DEV_CONFIG) &&
-			    !(p_dev->instance->state & DEV_SUSPEND_NORELEASE)){
+		p_dev->state &= ~DEV_SUSPEND;
+			if ((p_dev->state & DEV_CONFIG) &&
+			    !(p_dev->state & DEV_SUSPEND_NORELEASE)){
 				ret = pcmcia_request_configuration(p_dev,
-						 &p_dev->instance->conf);
+						 &p_dev->conf);
 				if (ret)
 					return ret;
 			}
-		}
 		return p_drv->resume(p_dev);
 	}
 
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index be08bc9..2b11a332 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -229,7 +229,7 @@
 					 * by userspace before, we need to
 					 * return the "instance". */
 					spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-					bind_info->instance = p_dev->instance;
+					bind_info->instance = p_dev;
 					ret = -EBUSY;
 					goto err_put_module;
 				} else {
@@ -358,16 +358,15 @@
  found:
 	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
-	if ((!p_dev->instance) ||
-	    (p_dev->instance->state & DEV_CONFIG_PENDING)) {
+	if (p_dev->state & DEV_CONFIG_PENDING) {
 		ret = -EAGAIN;
 		goto err_put;
 	}
 
 	if (first)
-		node = p_dev->instance->dev;
+		node = p_dev->dev_node;
 	else
-		for (node = p_dev->instance->dev; node; node = node->next)
+		for (node = p_dev->dev_node; node; node = node->next)
 			if (node == bind_info->next)
 				break;
 	if (!node) {
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index ab0bbb6..93ab940 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -942,15 +942,12 @@
 EXPORT_SYMBOL(pcmcia_request_window);
 
 void pcmcia_disable_device(struct pcmcia_device *p_dev) {
-	if (!p_dev->instance)
-		return;
-
 	pcmcia_release_configuration(p_dev);
-	pcmcia_release_io(p_dev, &p_dev->instance->io);
-	pcmcia_release_irq(p_dev, &p_dev->instance->irq);
-	if (&p_dev->instance->win)
-		pcmcia_release_window(p_dev->instance->win);
+	pcmcia_release_io(p_dev, &p_dev->io);
+	pcmcia_release_irq(p_dev, &p_dev->irq);
+	if (&p_dev->win)
+		pcmcia_release_window(p_dev->win);
 
-	p_dev->instance->dev = NULL;
+	p_dev->dev_node = NULL;
 }
 EXPORT_SYMBOL(pcmcia_disable_device);
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 12ec94d..0c196fb 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -89,7 +89,7 @@
 /*====================================================================*/
 
 typedef struct scsi_info_t {
-    dev_link_t		link;
+	struct pcmcia_device	*p_dev;
     dev_node_t		node;
     struct Scsi_Host	*host;
 } scsi_info_t;
@@ -103,7 +103,7 @@
 static int aha152x_attach(struct pcmcia_device *p_dev)
 {
     scsi_info_t *info;
-    dev_link_t *link;
+    dev_link_t *link = dev_to_instance(p_dev);
     
     DEBUG(0, "aha152x_attach()\n");
 
@@ -111,7 +111,8 @@
     info = kmalloc(sizeof(*info), GFP_KERNEL);
     if (!info) return -ENOMEM;
     memset(info, 0, sizeof(*info));
-    link = &info->link; link->priv = info;
+    info->p_dev = p_dev;
+    link->priv = info;
 
     link->io.NumPorts1 = 0x20;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -122,9 +123,6 @@
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     aha152x_config_cs(link);
 
@@ -136,23 +134,14 @@
 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);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
 
     if (link->state & DEV_CONFIG)
 	aha152x_release_cs(link);
 
     /* Unlink device structure, free bits */
-    *linkp = link->next;
     kfree(link->priv);
-    
 } /* aha152x_detach */
 
 /*====================================================================*/
@@ -230,7 +219,7 @@
     }
 
     sprintf(info->node.dev_name, "scsi%d", host->host_no);
-    link->dev = &info->node;
+    link->dev_node = &info->node;
     info->host = host;
 
     link->state &= ~DEV_CONFIG_PENDING;
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index b3cd206..94dcee9 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -73,7 +73,7 @@
 /*====================================================================*/
 
 typedef struct scsi_info_t {
-    dev_link_t		link;
+	struct pcmcia_device	*p_dev;
     dev_node_t		node;
     struct Scsi_Host	*host;
 } scsi_info_t;
@@ -86,7 +86,7 @@
 static int fdomain_attach(struct pcmcia_device *p_dev)
 {
     scsi_info_t *info;
-    dev_link_t *link;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "fdomain_attach()\n");
 
@@ -94,7 +94,8 @@
     info = kmalloc(sizeof(*info), GFP_KERNEL);
     if (!info) return -ENOMEM;
     memset(info, 0, sizeof(*info));
-    link = &info->link; link->priv = info;
+    info->p_dev = p_dev;
+    link->priv = info;
     link->io.NumPorts1 = 0x10;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 10;
@@ -104,9 +105,6 @@
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
     fdomain_config(link);
 
@@ -191,7 +189,7 @@
     scsi_scan_host(host);
 
     sprintf(info->node.dev_name, "scsi%d", host->host_no);
-    link->dev = &info->node;
+    link->dev_node = &info->node;
     info->host = host;
     
     link->state &= ~DEV_CONFIG_PENDING;
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index e41e1fe..23548fb 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1596,8 +1596,8 @@
 static int nsp_cs_attach(struct pcmcia_device *p_dev)
 {
 	scsi_info_t  *info;
-	dev_link_t   *link;
 	nsp_hw_data  *data = &nsp_data_base;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	nsp_dbg(NSP_DEBUG_INIT, "in");
 
@@ -1605,7 +1605,7 @@
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (info == NULL) { return -ENOMEM; }
 	memset(info, 0, sizeof(*info));
-	link = &info->link;
+	info->p_dev = p_dev;
 	link->priv = info;
 	data->ScsiInfo = info;
 
@@ -1630,9 +1630,6 @@
 	link->conf.IntType	 = INT_MEMORY_AND_IO;
 	link->conf.Present	 = PRESENT_OPTION;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	nsp_cs_config(link);
 
@@ -1853,12 +1850,12 @@
 	scsi_scan_host(host);
 
 	snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
-	link->dev  = &info->node;
+	link->dev_node  = &info->node;
 	info->host = host;
 
 #else
 	nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
-	tail = &link->dev;
+	tail = &link->dev_node;
 	info->ndev = 0;
 
 	nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
@@ -1962,7 +1959,7 @@
 #else
 	scsi_unregister_host(&nsp_driver_template);
 #endif
-	link->dev = NULL;
+	link->dev_node = NULL;
 
 	if (link->win) {
 		if (data != NULL) {
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index b66b140..2e1fde4 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -225,7 +225,7 @@
 /*====================================================================*/
 
 typedef struct scsi_info_t {
-	dev_link_t             link;
+	struct pcmcia_device	*p_dev;
 	struct Scsi_Host      *host;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
 	dev_node_t             node;
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 4f28589..c6b3e95 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -91,7 +91,7 @@
 /*====================================================================*/
 
 typedef struct scsi_info_t {
-	dev_link_t link;
+	struct pcmcia_device	*p_dev;
 	dev_node_t node;
 	struct Scsi_Host *host;
 	unsigned short manf_id;
@@ -159,7 +159,7 @@
 static int qlogic_attach(struct pcmcia_device *p_dev)
 {
 	scsi_info_t *info;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	DEBUG(0, "qlogic_attach()\n");
 
@@ -168,7 +168,7 @@
 	if (!info)
 		return -ENOMEM;
 	memset(info, 0, sizeof(*info));
-	link = &info->link;
+	info->p_dev = p_dev;
 	link->priv = info;
 	link->io.NumPorts1 = 16;
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -179,9 +179,6 @@
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->conf.Present = PRESENT_OPTION;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	qlogic_config(link);
 
@@ -278,7 +275,7 @@
 	}
 
 	sprintf(info->node.dev_name, "scsi%d", host->host_no);
-	link->dev = &info->node;
+	link->dev_node = &info->node;
 	info->host = host;
 
 out:
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 2bce7b0..1ef3109 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -202,7 +202,7 @@
 /* ================================================================== */
 
 struct scsi_info_t {
-	dev_link_t link;
+	struct pcmcia_device	*p_dev;
 	dev_node_t node;
 	struct Scsi_Host *host;
 	unsigned short manf_id;
@@ -829,7 +829,7 @@
 	data->fast_pio = USE_FAST_PIO;
 
 	sprintf(info->node.dev_name, "scsi%d", host->host_no);
-	link->dev = &info->node;
+	link->dev_node = &info->node;
 	info->host = host;
 
 	if (scsi_add_host(host, NULL))
@@ -899,7 +899,7 @@
 SYM53C500_attach(struct pcmcia_device *p_dev)
 {
 	struct scsi_info_t *info;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	DEBUG(0, "SYM53C500_attach()\n");
 
@@ -908,7 +908,7 @@
 	if (!info)
 		return -ENOMEM;
 	memset(info, 0, sizeof(*info));
-	link = &info->link;
+	info->p_dev = p_dev;
 	link->priv = info;
 	link->io.NumPorts1 = 16;
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -919,9 +919,6 @@
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->conf.Present = PRESENT_OPTION;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	SYM53C500_config(link);
 
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 1e6889f..6bcde2c 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -97,7 +97,7 @@
 #define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
 
 struct serial_info {
-	dev_link_t		link;
+	struct pcmcia_device	*p_dev;
 	int			ndev;
 	int			multi;
 	int			slave;
@@ -135,16 +135,16 @@
 	/*
 	 * Recheck to see if the device is still configured.
 	 */
-	if (info->link.state & DEV_CONFIG) {
+	if (info->p_dev->state & DEV_CONFIG) {
 		for (i = 0; i < info->ndev; i++)
 			serial8250_unregister_port(info->line[i]);
 
-		info->link.dev = NULL;
+		info->p_dev->dev_node = NULL;
 
 		if (!info->slave)
 			pcmcia_disable_device(link->handle);
 
-		info->link.state &= ~DEV_CONFIG;
+		info->p_dev->state &= ~DEV_CONFIG;
 	}
 }
 
@@ -192,7 +192,7 @@
 static int serial_probe(struct pcmcia_device *p_dev)
 {
 	struct serial_info *info;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	DEBUG(0, "serial_attach()\n");
 
@@ -201,7 +201,7 @@
 	if (!info)
 		return -ENOMEM;
 	memset(info, 0, sizeof (*info));
-	link = &info->link;
+	info->p_dev = p_dev;
 	link->priv = info;
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@@ -215,8 +215,6 @@
 	}
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	serial_config(link);
 
@@ -660,7 +658,7 @@
 		}
 	}
 
-	link->dev = &info->node[0];
+	link->dev_node = &info->node[0];
 	link->state &= ~DEV_CONFIG_PENDING;
 	kfree(cfg_mem);
 	return;
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index de794b2..0afd6c0 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -40,30 +40,20 @@
 
 static int ixj_attach(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link;
-
 	DEBUG(0, "ixj_attach()\n");
 	/* Create new ixj device */
-	link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-	if (!link)
-		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;
-	link->io.IOAddrLines = 3;
-	link->conf.IntType = INT_MEMORY_AND_IO;
-	link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
-	if (!link->priv) {
-		kfree(link);
+	p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+	p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+	p_dev->io.IOAddrLines = 3;
+	p_dev->conf.IntType = INT_MEMORY_AND_IO;
+	p_dev->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
+	if (!p_dev->priv) {
 		return -ENOMEM;
 	}
-	memset(link->priv, 0, sizeof(struct ixj_info_t));
+	memset(p_dev->priv, 0, sizeof(struct ixj_info_t));
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	ixj_config(link);
+	p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	ixj_config(p_dev);
 
 	return 0;
 }
@@ -79,7 +69,6 @@
 		ixj_cs_release(link);
 
         kfree(link->priv);
-        kfree(link);
 }
 
 #define CS_CHECK(fn, ret) \
@@ -212,7 +201,7 @@
 
 	info->ndev = 1;
 	info->node.major = PHONE_MAJOR;
-	link->dev = &info->node;
+	link->dev_node = &info->node;
 	ixj_get_serial(link, j);
 	link->state &= ~DEV_CONFIG_PENDING;
 	return;
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index c6f1baf..8e61faa 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -67,7 +67,7 @@
 static const char driver_name[DEV_NAME_LEN]  = "sl811_cs";
 
 typedef struct local_info_t {
-	dev_link_t		link;
+	struct pcmcia_device	*p_dev;
 	dev_node_t		node;
 } local_info_t;
 
@@ -268,7 +268,7 @@
 
 	sprintf(dev->node.dev_name, driver_name);
 	dev->node.major = dev->node.minor = 0;
-	link->dev = &dev->node;
+	link->dev_node = &dev->node;
 
 	printk(KERN_INFO "%s: index 0x%02x: ",
 	       dev->node.dev_name, link->conf.ConfigIndex);
@@ -294,13 +294,13 @@
 static int sl811_cs_attach(struct pcmcia_device *p_dev)
 {
 	local_info_t *local;
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
 	if (!local)
 		return -ENOMEM;
 	memset(local, 0, sizeof(local_info_t));
-	link = &local->link;
+	local->p_dev = p_dev;
 	link->priv = local;
 
 	/* Initialize */
@@ -311,9 +311,6 @@
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	link->handle = p_dev;
-	p_dev->instance = link;
-
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	sl811_cs_config(link);
 
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index 7f712df..61f7d2d 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -39,7 +39,7 @@
 typedef struct bind_info_t {
     dev_info_t		dev_info;
     u_char		function;
-    struct dev_link_t	*instance;
+    struct pcmcia_device *instance;
     char		name[DEV_NAME_LEN];
     u_short		major, minor;
     void		*next;
@@ -103,18 +103,6 @@
     struct dev_node_t	*next;
 } dev_node_t;
 
-typedef struct dev_link_t {
-    dev_node_t		*dev;
-    u_int		state, open;
-    client_handle_t	handle;
-    io_req_t		io;
-    irq_req_t		irq;
-    config_req_t	conf;
-    window_handle_t	win;
-    void		*priv;
-    struct dev_link_t	*next;
-} dev_link_t;
-
 /* Flags for device state */
 #define DEV_PRESENT		0x01
 #define DEV_CONFIG		0x02
@@ -163,9 +151,17 @@
 
 	struct list_head	socket_device_list;
 
-	/* deprecated, a cleaned up version will be moved into this
-	   struct soon */
-	dev_link_t		*instance;
+	/* deprecated, will be cleaned up soon */
+	dev_node_t		*dev_node;
+	u_int			state;
+	u_int			open;
+	struct pcmcia_device	*handle;
+	io_req_t		io;
+	irq_req_t		irq;
+	config_req_t		conf;
+	window_handle_t		win;
+	void			*priv;
+
 	u_int			p_state;
 
 	/* information about this device */
@@ -189,6 +185,7 @@
 	struct pcmcia_driver *	cardmgr;
 #endif
 };
+typedef struct pcmcia_device dev_link_t;
 
 #define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
 #define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv)
@@ -196,7 +193,7 @@
 #define handle_to_pdev(handle) (handle)
 #define handle_to_dev(handle) (handle->dev)
 
-#define dev_to_instance(dev) (dev->instance)
+#define dev_to_instance(dev) (dev)
 
 /* error reporting */
 void cs_error(client_handle_t handle, int func, int ret);
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 7c4091a..b415820 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -70,7 +70,7 @@
  */
 static int snd_pdacf_free(struct snd_pdacf *pdacf)
 {
-	dev_link_t *link = &pdacf->link;
+	dev_link_t *link = pdacf->p_dev;
 
 	pdacf_release(link);
 
@@ -100,6 +100,8 @@
 		.dev_free =	snd_pdacf_dev_free,
 	};
 
+	link = dev_to_instance(p_dev);
+
 	snd_printdd(KERN_DEBUG "pdacf_attach called\n");
 	/* find an empty slot from the card list */
 	for (i = 0; i < SNDRV_CARDS; i++) {
@@ -133,7 +135,7 @@
 	pdacf->index = i;
 	card_list[i] = card;
 
-	link = &pdacf->link;
+	pdacf->p_dev = p_dev;
 	link->priv = pdacf;
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -150,10 +152,6 @@
 	link->conf.ConfigIndex = 1;
 	link->conf.Present = PRESENT_OPTION;
 
-	/* Chain drivers */
-	link->next = NULL;
-
-	link->handle = p_dev;
 	pdacf_config(link);
 
 	return 0;
@@ -262,7 +260,7 @@
 	if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
 		goto failed;
 
-	link->dev = &pdacf->node;
+	link->dev_node = &pdacf->node;
 	link->state &= ~DEV_CONFIG_PENDING;
 	return;
 
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h
index 2744f18..9a14a4f 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.h
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h
@@ -116,7 +116,7 @@
 	void *pcm_area;
 	
 	/* pcmcia stuff */
-	dev_link_t link;
+	struct pcmcia_device	*p_dev;
 	dev_node_t node;
 };
 
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index ff2f927..87ec48c 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -126,7 +126,8 @@
 /*
  * create vxpocket instance
  */
-static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
+static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl,
+					     struct pcmcia_device *p_dev)
 {
 	dev_link_t *link;		/* Info for cardmgr */
 	struct vx_core *chip;
@@ -135,6 +136,8 @@
 		.dev_free =	snd_vxpocket_dev_free,
 	};
 
+	link = dev_to_instance(p_dev);
+
 	chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops,
 			     sizeof(struct snd_vxpocket) - sizeof(struct vx_core));
 	if (! chip)
@@ -148,7 +151,7 @@
 
 	vxp = (struct snd_vxpocket *)chip;
 
-	link = &vxp->link;
+	vxp->p_dev = p_dev;
 	link->priv = chip;
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -263,7 +266,7 @@
 	if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
 		goto failed;
 
-	link->dev = &vxp->node;
+	link->dev_node = &vxp->node;
 	link->state &= ~DEV_CONFIG_PENDING;
 	kfree(parse);
 	return;
@@ -339,7 +342,7 @@
 		return -ENOMEM;
 	}
 
-	vxp = snd_vxpocket_new(card, ibl[i]);
+	vxp = snd_vxpocket_new(card, ibl[i], p_dev);
 	if (! vxp) {
 		snd_card_free(card);
 		return -ENODEV;
@@ -349,13 +352,10 @@
 	vxp->index = i;
 	card_alloc |= 1 << i;
 
-	/* Chain drivers */
-	vxp->link.next = NULL;
+	vxp->p_dev = p_dev;
+	vxp->p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 
-	vxp->link.handle = p_dev;
-	vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	p_dev->instance = &vxp->link;
-	vxpocket_config(&vxp->link);
+	vxpocket_config(p_dev);
 
 	return 0;
 }
diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h
index 67efae3..27ea002 100644
--- a/sound/pcmcia/vx/vxpocket.h
+++ b/sound/pcmcia/vx/vxpocket.h
@@ -42,7 +42,7 @@
 	int index;	/* card index */
 
 	/* pcmcia stuff */
-	dev_link_t link;
+	struct pcmcia_device	*p_dev;
 	dev_node_t node;
 };