diff -urN -X /home/spse/dontdiff linux-2.5/drivers/mtd/maps/pcmciamtd.c mtd-2.5-spse/drivers/mtd/maps/pcmciamtd.c
--- linux-2.5/drivers/mtd/maps/pcmciamtd.c	2002-10-15 21:29:24.000000000 +0100
+++ mtd-2.5-spse/drivers/mtd/maps/pcmciamtd.c	2002-10-27 16:08:16.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: pcmciamtd.c,v 1.36 2002/10/14 18:49:12 rmk Exp $
+ * $Id: pcmciamtd.c,v 1.37 2002/10/27 16:07:10 spse Exp $
  *
  * pcmciamtd.c - MTD driver for PCMCIA flash memory cards
  *
@@ -41,33 +41,32 @@
 static const int debug = 0;
 #endif
 
-#define err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ## arg)
+#define err(format, arg...) printk(KERN_ERR "pcmciamtd: " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO "pcmciamtd: " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "pcmciamtd: " format "\n" , ## arg)
 
 
 #define DRIVER_DESC	"PCMCIA Flash memory card driver"
-#define DRIVER_VERSION	"$Revision: 1.36 $"
+#define DRIVER_VERSION	"$Revision: 1.37 $"
 
 /* Size of the PCMCIA address space: 26 bits = 64 MB */
 #define MAX_PCMCIA_ADDR	0x4000000
 
 struct pcmciamtd_dev {
-	struct list_head list;
 	dev_link_t	link;		/* PCMCIA link */
+	dev_node_t	node;		/* device node */
 	caddr_t		win_base;	/* ioremapped address of PCMCIA window */
 	unsigned int	win_size;	/* size of window */
-	unsigned int	cardsize;	/* size of whole card */
 	unsigned int	offset;		/* offset into card the window currently points at */
 	struct map_info	pcmcia_map;
 	struct mtd_info	*mtd_info;
-	u8		vpp;
+	int		vpp;
 	char		mtd_name[sizeof(struct cistpl_vers_1_t)];
 };
 
 
 static dev_info_t dev_info = "pcmciamtd";
-static LIST_HEAD(dev_list);
+static dev_link_t *dev_list;
 
 /* Module parameters */
 
@@ -123,6 +122,11 @@
 	memreq_t mrq;
 	int ret;
 
+	if(!(dev->link.state & DEV_PRESENT)) {
+		DEBUG(1, "device removed state = 0x%4.4X", dev->link.state);
+		return 0;
+	}
+
 	mrq.CardOffset = to & ~(dev->win_size-1);
 	if(mrq.CardOffset != dev->offset) {
 		DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
@@ -245,11 +249,16 @@
 
 /* read/write{8,16} copy_{from,to} routines with direct access */
 
+#define DEV_REMOVED(x)  (!(*(u_int *)x->map_priv_1 & DEV_PRESENT))
+
 static u8 pcmcia_read8(struct map_info *map, unsigned long ofs)
 {
 	caddr_t win_base = (caddr_t)map->map_priv_2;
 	u8 d;
 
+	if(DEV_REMOVED(map))
+		return 0;
+
 	d = readb(win_base + ofs);
 	DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, win_base + ofs, d);
 	return d;
@@ -261,6 +270,9 @@
 	caddr_t win_base = (caddr_t)map->map_priv_2;
 	u16 d;
 
+	if(DEV_REMOVED(map))
+		return 0;
+
 	d = readw(win_base + ofs);
 	DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, win_base + ofs, d);
 	return d;
@@ -271,6 +283,9 @@
 {
 	caddr_t win_base = (caddr_t)map->map_priv_2;
 
+	if(DEV_REMOVED(map))
+		return;
+
 	DEBUG(3, "to = %p from = %lu len = %u", to, from, len);
 	memcpy_fromio(to, win_base + from, len);
 }
@@ -280,6 +295,9 @@
 {
 	caddr_t win_base = (caddr_t)map->map_priv_2;
 
+	if(DEV_REMOVED(map))
+		return;
+
 	DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02x", adr, win_base + adr, d);
 	writeb(d, win_base + adr);
 }
@@ -289,6 +307,9 @@
 {
 	caddr_t win_base = (caddr_t)map->map_priv_2;
 
+	if(DEV_REMOVED(map))
+		return;
+
 	DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04x", adr, win_base + adr, d);
 	writew(d, win_base + adr);
 }
@@ -298,6 +319,9 @@
 {
 	caddr_t win_base = (caddr_t)map->map_priv_2;
 
+	if(DEV_REMOVED(map))
+		return;
+
 	DEBUG(3, "to = %lu from = %p len = %u", to, from, len);
 	memcpy_toio(win_base + to, from, len);
 }
@@ -330,40 +354,18 @@
 static void pcmciamtd_release(u_long arg)
 {
 	dev_link_t *link = (dev_link_t *)arg;
-	struct pcmciamtd_dev *dev = NULL;
-	int ret;
-	struct list_head *temp1, *temp2;
+	struct pcmciamtd_dev *dev = link->priv;
 
 	DEBUG(3, "link = 0x%p", link);
-	/* Find device in list */
-	list_for_each_safe(temp1, temp2, &dev_list) {
-		dev = list_entry(temp1, struct pcmciamtd_dev, list);
-		if(link == &dev->link)
-			break;
-	}
-	if(link != &dev->link) {
-		DEBUG(1, "Cant find %p in dev_list", link);
-		return;
-	}
 
-	if(dev) {
-		if(dev->mtd_info) {
-			del_mtd_device(dev->mtd_info);
-			dev->mtd_info = NULL;
-			MOD_DEC_USE_COUNT;
-		}
-		if (link->win) {
-			if(dev->win_base) {
-				iounmap(dev->win_base);
-				dev->win_base = NULL;
-			}
-			CardServices(ReleaseWindow, link->win);
+	if (link->win) {
+		if(dev->win_base) {
+			iounmap(dev->win_base);
+			dev->win_base = NULL;
 		}
-		ret = CardServices(ReleaseConfiguration, link->handle);
-		if(ret != CS_SUCCESS)
-			cs_error(link->handle, ReleaseConfiguration, ret);
-			
+		CardServices(ReleaseWindow, link->win);
 	}
+	CardServices(ReleaseConfiguration, link->handle);
 	link->state &= ~DEV_CONFIG;
 }
 
@@ -472,7 +474,6 @@
 	if(force_size) {
 		dev->pcmcia_map.size = force_size << 20;
 		DEBUG(2, "size forced to %dM", force_size);
-
 	}
 
 	if(buswidth) {
@@ -586,9 +587,8 @@
 	}
 	DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x",
 	      dev, req.Base, dev->win_base, req.Size);
-	dev->cardsize = 0;
-	dev->offset = 0;
 
+	dev->offset = 0;
 	dev->pcmcia_map.map_priv_1 = (unsigned long)dev;
 	dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
 
@@ -620,9 +620,6 @@
 		cs_error(link->handle, RequestConfiguration, ret);
 	}
 
-	link->dev = NULL;
-	link->state &= ~DEV_CONFIG_PENDING;
-
 	if(mem_type == 1) {
 		mtd = do_map_probe("map_ram", &dev->pcmcia_map);
 	} else if(mem_type == 2) {
@@ -646,7 +643,6 @@
 
 	dev->mtd_info = mtd;
 	mtd->module = THIS_MODULE;
-	dev->cardsize = mtd->size;
 
 	if(new_name) {
 		int size = 0;
@@ -655,19 +651,19 @@
 		   size */
 		if(mtd->size < 1048576) { /* <1MB in size, show size in K */
 			size = mtd->size >> 10;
-			unit = 'K'; 
+			unit = 'K';
 		} else {
 			size = mtd->size >> 20;
 			unit = 'M';
 		}
-		sprintf(mtd->name, "%d%cB %s", size, unit, "PCMCIA Memory card");
+		snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%cB %s", size, unit, "PCMCIA Memory card");
 	}
 
 	/* If the memory found is fits completely into the mapped PCMCIA window,
 	   use the faster non-remapping read/write functions */
-	if(dev->cardsize <= dev->win_size) {
+	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_2 = (unsigned long)dev->win_base;
 		dev->pcmcia_map.read8 = pcmcia_read8;
 		dev->pcmcia_map.read16 = pcmcia_read16;
@@ -677,16 +673,17 @@
 		dev->pcmcia_map.copy_to = pcmcia_copy_to;
 	}
 
-	MOD_INC_USE_COUNT;
 	if(add_mtd_device(mtd)) {
+		map_destroy(mtd);
 		dev->mtd_info = NULL;
-		MOD_DEC_USE_COUNT;
 		err("Couldnt register MTD device");
 		pcmciamtd_release((u_long)link);
 		return;
 	}
-	DEBUG(1, "mtd added @ %p mtd->priv = %p", mtd, mtd->priv);
-
+	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;
 	return;
 
  cs_failed:
@@ -713,8 +710,14 @@
 	case CS_EVENT_CARD_REMOVAL:
 		DEBUG(2, "EVENT_CARD_REMOVAL");
 		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
+		if (link->state & DEV_CONFIG) {
+			struct pcmciamtd_dev *dev = link->priv;
+			if(dev->mtd_info) {
+				del_mtd_device(dev->mtd_info);
+				info("mtd%d: Removed", dev->mtd_info->index);
+			}
 			mod_timer(&link->release, jiffies + HZ/20);
+		}
 		break;
 	case CS_EVENT_CARD_INSERTION:
 		DEBUG(2, "EVENT_CARD_INSERTION");
@@ -752,47 +755,23 @@
 
 static void pcmciamtd_detach(dev_link_t *link)
 {
-	int ret;
-	struct pcmciamtd_dev *dev = NULL;
-	struct list_head *temp1, *temp2;
-
 	DEBUG(3, "link=0x%p", link);
 
-	/* Find device in list */
-	list_for_each_safe(temp1, temp2, &dev_list) {
-		dev = list_entry(temp1, struct pcmciamtd_dev, list);
-		if(link == &dev->link)
-			break;
-	}
-	if(link != &dev->link) {
-		DEBUG(1, "Cant find %p in dev_list", link);
-		return;
-	}
-	
 	del_timer(&link->release);
 
-	if(!dev) {
-		DEBUG(3, "dev is NULL");
-		return;
-	}
-
-	if (link->state & DEV_CONFIG) {
-		//pcmciamtd_release((u_long)link);
-		DEBUG(3, "DEV_CONFIG set");
-		link->state |= DEV_STALE_LINK;
-		return;
+	if(link->state & DEV_CONFIG) {
+		pcmciamtd_release((u_long)link);
 	}
 
 	if (link->handle) {
+		int ret;
 		DEBUG(2, "Deregistering with card services");
 		ret = CardServices(DeregisterClient, link->handle);
 		if (ret != CS_SUCCESS)
 			cs_error(link->handle, DeregisterClient, ret);
 	}
-	DEBUG(3, "Freeing dev (%p)", dev);
-	list_del(&dev->list);
-	link->priv = NULL;
-	kfree(dev);
+
+	link->state |= DEV_STALE_LINK;
 }
 
 
@@ -814,7 +793,8 @@
 	DEBUG(1, "dev=0x%p", dev);
 
 	memset(dev, 0, sizeof(*dev));
-	link = &dev->link; link->priv = dev;
+	link = &dev->link;
+	link->priv = dev;
 
 	link->release.function = &pcmciamtd_release;
 	link->release.data = (u_long)link;
@@ -822,7 +802,8 @@
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY;
 
-	list_add(&dev->list, &dev_list);
+	link->next = dev_list;
+	dev_list = link;
 
 	/* Register with Card Services */
 	client_reg.dev_info = &dev_info;
@@ -841,7 +822,7 @@
 		pcmciamtd_detach(link);
 		return NULL;
 	}
-
+	DEBUG(2, "link = %p", link);
 	return link;
 }
 
@@ -876,15 +857,35 @@
 
 static void __exit exit_pcmciamtd(void)
 {
-	struct list_head *temp1, *temp2;
-
 	DEBUG(1, DRIVER_DESC " unloading");
 	unregister_pccard_driver(&dev_info);
-	list_for_each_safe(temp1, temp2, &dev_list) {
-		dev_link_t *link = &list_entry(temp1, struct pcmciamtd_dev, list)->link;
-		if (link && (link->state & DEV_CONFIG)) {
-			pcmciamtd_release((u_long)link);
-			pcmciamtd_detach(link);
+
+	while(dev_list) {
+		dev_link_t *link = dev_list;
+
+		dev_list = link->next;
+		if (link) {
+			struct pcmciamtd_dev *dev = link->priv;
+			
+ 			if(dev) {
+				if(link->state & DEV_PRESENT) {
+					if (!(link->state & DEV_STALE_LINK)) {
+						pcmciamtd_detach(link);
+					}
+					link->state &= ~DEV_PRESENT;
+					if(dev->mtd_info) {
+						del_mtd_device(dev->mtd_info);
+						info("mtd%d: Removed",
+						     dev->mtd_info->index);
+					}
+				}
+				if(dev->mtd_info) {
+					DEBUG(2, "Destroying map for mtd%d",
+					      dev->mtd_info->index);
+					map_destroy(dev->mtd_info);
+				}
+				kfree(dev);
+			}
 		}
 	}
 }
