<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">diff -urN orig/drivers/pcmcia/cistpl.c linux/drivers/pcmcia/cistpl.c
--- orig/drivers/pcmcia/cistpl.c	Sat Mar 15 22:38:33 2003
+++ linux/drivers/pcmcia/cistpl.c	Sat Mar 15 22:43:35 2003
@@ -84,6 +84,113 @@
 
 INT_MODULE_PARM(cis_width,	0);		/* 16-bit CIS? */
 
+/*======================================================================
+
+    This is tricky... when we set up CIS memory, we try to validate
+    the memory window space allocations.
+    
+======================================================================*/
+
+/* Scratch pointer to the socket we use for validation */
+static socket_info_t *vs = NULL;
+
+/* Validation function for cards with a valid CIS */
+static int cis_readable(u_long base)
+{
+    cisinfo_t info1, info2;
+    int ret;
+    vs-&gt;cis_mem.sys_start = base;
+    vs-&gt;cis_mem.sys_stop = base+vs-&gt;cap.map_size-1;
+    vs-&gt;cis_virt = ioremap(base, vs-&gt;cap.map_size);
+    ret = pcmcia_validate_cis(vs-&gt;clients, &amp;info1);
+    /* invalidate mapping and CIS cache */
+    iounmap(vs-&gt;cis_virt);
+    vs-&gt;cis_used = 0;
+    if ((ret != 0) || (info1.Chains == 0))
+	return 0;
+    vs-&gt;cis_mem.sys_start = base+vs-&gt;cap.map_size;
+    vs-&gt;cis_mem.sys_stop = base+2*vs-&gt;cap.map_size-1;
+    vs-&gt;cis_virt = ioremap(base+vs-&gt;cap.map_size, vs-&gt;cap.map_size);
+    ret = pcmcia_validate_cis(vs-&gt;clients, &amp;info2);
+    iounmap(vs-&gt;cis_virt);
+    vs-&gt;cis_used = 0;
+    return ((ret == 0) &amp;&amp; (info1.Chains == info2.Chains));
+}
+
+/* Validation function for simple memory cards */
+static int checksum(u_long base)
+{
+    int i, a, b, d;
+    vs-&gt;cis_mem.sys_start = base;
+    vs-&gt;cis_mem.sys_stop = base+vs-&gt;cap.map_size-1;
+    vs-&gt;cis_virt = ioremap(base, vs-&gt;cap.map_size);
+    vs-&gt;cis_mem.card_start = 0;
+    vs-&gt;cis_mem.flags = MAP_ACTIVE;
+    vs-&gt;ss_entry-&gt;set_mem_map(vs-&gt;sock, &amp;vs-&gt;cis_mem);
+    /* Don't bother checking every word... */
+    a = 0; b = -1;
+    for (i = 0; i &lt; vs-&gt;cap.map_size; i += 44) {
+	d = readl(vs-&gt;cis_virt+i);
+	a += d; b &amp;= d;
+    }
+    iounmap(vs-&gt;cis_virt);
+    return (b == -1) ? -1 : (a&gt;&gt;1);
+}
+
+static int checksum_match(u_long base)
+{
+    int a = checksum(base), b = checksum(base+vs-&gt;cap.map_size);
+    return ((a == b) &amp;&amp; (a &gt;= 0));
+}
+
+void release_cis_mem(socket_info_t *s)
+{
+    if (s-&gt;cis_mem.sys_start != 0) {
+	s-&gt;cis_mem.flags &amp;= ~MAP_ACTIVE;
+	s-&gt;ss_entry-&gt;set_mem_map(s-&gt;sock, &amp;s-&gt;cis_mem);
+	if (!(s-&gt;cap.features &amp; SS_CAP_STATIC_MAP))
+	    release_mem_region(s-&gt;cis_mem.sys_start, s-&gt;cap.map_size);
+	iounmap(s-&gt;cis_virt);
+	s-&gt;cis_mem.sys_start = 0;
+	s-&gt;cis_virt = NULL;
+    }
+}
+
+/*
+ * Map the card memory at "card_offset" into virtual space.
+ * If flags &amp; MAP_ATTRIB, map the attribute space, otherwise
+ * map the memory space.
+ */
+static unsigned char *
+set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags)
+{
+    pccard_mem_map *mem = &amp;s-&gt;cis_mem;
+    if (!(s-&gt;cap.features &amp; SS_CAP_STATIC_MAP) &amp;&amp;
+	mem-&gt;sys_start == 0) {
+	int low = !(s-&gt;cap.features &amp; SS_CAP_PAGE_REGS);
+	vs = s;
+	validate_mem(cis_readable, checksum_match, low, s);
+	mem-&gt;sys_start = 0;
+	vs = NULL;
+	if (find_mem_region(&amp;mem-&gt;sys_start, s-&gt;cap.map_size,
+			    s-&gt;cap.map_size, low, "card services", s)) {
+	    printk(KERN_NOTICE "cs: unable to map card memory!\n");
+	    return NULL;
+	}
+	mem-&gt;sys_stop = mem-&gt;sys_start+s-&gt;cap.map_size-1;
+	s-&gt;cis_virt = ioremap(mem-&gt;sys_start, s-&gt;cap.map_size);
+    }
+    mem-&gt;card_start = card_offset;
+    mem-&gt;flags = flags;
+    s-&gt;ss_entry-&gt;set_mem_map(s-&gt;sock, mem);
+    if (s-&gt;cap.features &amp; SS_CAP_STATIC_MAP) {
+	if (s-&gt;cis_virt)
+	    iounmap(s-&gt;cis_virt);
+	s-&gt;cis_virt = ioremap(mem-&gt;sys_start, s-&gt;cap.map_size);
+    }
+    return s-&gt;cis_virt;
+}
+
 /*======================================================================
 
     Low-level functions to read and write CIS memory.  I think the
@@ -95,39 +202,28 @@
 #define IS_ATTR		1
 #define IS_INDIRECT	8
 
-static int setup_cis_mem(socket_info_t *s);
-
-static void set_cis_map(socket_info_t *s, pccard_mem_map *mem)
-{
-    s-&gt;ss_entry-&gt;set_mem_map(s-&gt;sock, mem);
-    if (s-&gt;cap.features &amp; SS_CAP_STATIC_MAP) {
-	if (s-&gt;cis_virt)
-	    iounmap(s-&gt;cis_virt);
-	s-&gt;cis_virt = ioremap(mem-&gt;sys_start, s-&gt;cap.map_size);
-    }
-}
-
 int read_cis_mem(socket_info_t *s, int attr, u_int addr,
 		 u_int len, void *ptr)
 {
-    pccard_mem_map *mem = &amp;s-&gt;cis_mem;
-    u_char *sys, *buf = ptr;
+    u_char *sys, *end, *buf = ptr;
     
     DEBUG(3, "cs: read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
-    if (setup_cis_mem(s) != 0) {
-	memset(ptr, 0xff, len);
-	return -1;
-    }
-    mem-&gt;flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
 
     if (attr &amp; IS_INDIRECT) {
 	/* Indirect accesses use a bunch of special registers at fixed
 	   locations in common memory */
 	u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
-	if (attr &amp; IS_ATTR) { addr *= 2; flags = ICTRL0_AUTOINC; }
-	mem-&gt;card_start = 0; mem-&gt;flags = MAP_ACTIVE;
-	set_cis_map(s, mem);
-	sys = s-&gt;cis_virt;
+	if (attr &amp; IS_ATTR) {
+	    addr *= 2;
+	    flags = ICTRL0_AUTOINC;
+	}
+
+	sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
+	if (!sys) {
+	    memset(ptr, 0xff, len);
+	    return -1;
+	}
+
 	writeb(flags, sys+CISREG_ICTRL0);
 	writeb(addr &amp; 0xff, sys+CISREG_IADDR0);
 	writeb((addr&gt;&gt;8) &amp; 0xff, sys+CISREG_IADDR1);
@@ -136,18 +232,30 @@
 	for ( ; len &gt; 0; len--, buf++)
 	    *buf = readb(sys+CISREG_IDATA0);
     } else {
-	u_int inc = 1;
-	if (attr) { mem-&gt;flags |= MAP_ATTRIB; inc++; addr *= 2; }
-	sys += (addr &amp; (s-&gt;cap.map_size-1));
-	mem-&gt;card_start = addr &amp; ~(s-&gt;cap.map_size-1);
+	u_int inc = 1, card_offset, flags;
+
+	flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
+	if (attr) {
+	    flags |= MAP_ATTRIB;
+	    inc++;
+	    addr *= 2;
+	}
+
+	card_offset = addr &amp; ~(s-&gt;cap.map_size-1);
 	while (len) {
-	    set_cis_map(s, mem);
-	    sys = s-&gt;cis_virt + (addr &amp; (s-&gt;cap.map_size-1));
+	    sys = set_cis_map(s, card_offset, flags);
+	    if (!sys) {
+		memset(ptr, 0xff, len);
+		return -1;
+	    }
+	    end = sys + s-&gt;cap.map_size;
+	    sys = sys + (addr &amp; (s-&gt;cap.map_size-1));
 	    for ( ; len &gt; 0; len--, buf++, sys += inc) {
-		if (sys == s-&gt;cis_virt+s-&gt;cap.map_size) break;
+		if (sys == end)
+		    break;
 		*buf = readb(sys);
 	    }
-	    mem-&gt;card_start += s-&gt;cap.map_size;
+	    card_offset += s-&gt;cap.map_size;
 	    addr = 0;
 	}
     }
@@ -160,21 +268,23 @@
 void write_cis_mem(socket_info_t *s, int attr, u_int addr,
 		   u_int len, void *ptr)
 {
-    pccard_mem_map *mem = &amp;s-&gt;cis_mem;
-    u_char *sys, *buf = ptr;
+    u_char *sys, *end, *buf = ptr;
     
     DEBUG(3, "cs: write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
-    if (setup_cis_mem(s) != 0) return;
-    mem-&gt;flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
 
     if (attr &amp; IS_INDIRECT) {
 	/* Indirect accesses use a bunch of special registers at fixed
 	   locations in common memory */
 	u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
-	if (attr &amp; IS_ATTR) { addr *= 2; flags = ICTRL0_AUTOINC; }
-	mem-&gt;card_start = 0; mem-&gt;flags = MAP_ACTIVE;
-	set_cis_map(s, mem);
-	sys = s-&gt;cis_virt;
+	if (attr &amp; IS_ATTR) {
+	    addr *= 2;
+	    flags = ICTRL0_AUTOINC;
+	}
+
+	sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
+	if (!sys)
+		return; /* FIXME: Error */
+
 	writeb(flags, sys+CISREG_ICTRL0);
 	writeb(addr &amp; 0xff, sys+CISREG_IADDR0);
 	writeb((addr&gt;&gt;8) &amp; 0xff, sys+CISREG_IADDR1);
@@ -183,112 +293,32 @@
 	for ( ; len &gt; 0; len--, buf++)
 	    writeb(*buf, sys+CISREG_IDATA0);
     } else {
-	int inc = 1;
-	if (attr &amp; IS_ATTR) { mem-&gt;flags |= MAP_ATTRIB; inc++; addr *= 2; }
-	mem-&gt;card_start = addr &amp; ~(s-&gt;cap.map_size-1);
+	u_int inc = 1, card_offset, flags;
+
+	flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
+	if (attr &amp; IS_ATTR) {
+	    flags |= MAP_ATTRIB;
+	    inc++;
+	    addr *= 2;
+	}
+
+	card_offset = addr &amp; ~(s-&gt;cap.map_size-1);
 	while (len) {
-	    set_cis_map(s, mem);
-	    sys = s-&gt;cis_virt + (addr &amp; (s-&gt;cap.map_size-1));
+	    sys = set_cis_map(s, card_offset, flags);
+	    if (!sys)
+		return; /* FIXME: error */
+
+	    end = sys + s-&gt;cap.map_size;
+	    sys = sys + (addr &amp; (s-&gt;cap.map_size-1));
 	    for ( ; len &gt; 0; len--, buf++, sys += inc) {
-		if (sys == s-&gt;cis_virt+s-&gt;cap.map_size) break;
+		if (sys == end)
+		    break;
 		writeb(*buf, sys);
 	    }
-	    mem-&gt;card_start += s-&gt;cap.map_size;
+	    card_offset += s-&gt;cap.map_size;
 	    addr = 0;
 	}
     }
-}
-
-/*======================================================================
-
-    This is tricky... when we set up CIS memory, we try to validate
-    the memory window space allocations.
-    
-======================================================================*/
-
-/* Scratch pointer to the socket we use for validation */
-static socket_info_t *vs = NULL;
-
-/* Validation function for cards with a valid CIS */
-static int cis_readable(u_long base)
-{
-    cisinfo_t info1, info2;
-    int ret;
-    vs-&gt;cis_mem.sys_start = base;
-    vs-&gt;cis_mem.sys_stop = base+vs-&gt;cap.map_size-1;
-    vs-&gt;cis_virt = ioremap(base, vs-&gt;cap.map_size);
-    ret = pcmcia_validate_cis(vs-&gt;clients, &amp;info1);
-    /* invalidate mapping and CIS cache */
-    iounmap(vs-&gt;cis_virt);
-    vs-&gt;cis_used = 0;
-    if ((ret != 0) || (info1.Chains == 0))
-	return 0;
-    vs-&gt;cis_mem.sys_start = base+vs-&gt;cap.map_size;
-    vs-&gt;cis_mem.sys_stop = base+2*vs-&gt;cap.map_size-1;
-    vs-&gt;cis_virt = ioremap(base+vs-&gt;cap.map_size, vs-&gt;cap.map_size);
-    ret = pcmcia_validate_cis(vs-&gt;clients, &amp;info2);
-    iounmap(vs-&gt;cis_virt);
-    vs-&gt;cis_used = 0;
-    return ((ret == 0) &amp;&amp; (info1.Chains == info2.Chains));
-}
-
-/* Validation function for simple memory cards */
-static int checksum(u_long base)
-{
-    int i, a, b, d;
-    vs-&gt;cis_mem.sys_start = base;
-    vs-&gt;cis_mem.sys_stop = base+vs-&gt;cap.map_size-1;
-    vs-&gt;cis_virt = ioremap(base, vs-&gt;cap.map_size);
-    vs-&gt;cis_mem.card_start = 0;
-    vs-&gt;cis_mem.flags = MAP_ACTIVE;
-    vs-&gt;ss_entry-&gt;set_mem_map(vs-&gt;sock, &amp;vs-&gt;cis_mem);
-    /* Don't bother checking every word... */
-    a = 0; b = -1;
-    for (i = 0; i &lt; vs-&gt;cap.map_size; i += 44) {
-	d = readl(vs-&gt;cis_virt+i);
-	a += d; b &amp;= d;
-    }
-    iounmap(vs-&gt;cis_virt);
-    return (b == -1) ? -1 : (a&gt;&gt;1);
-}
-
-static int checksum_match(u_long base)
-{
-    int a = checksum(base), b = checksum(base+vs-&gt;cap.map_size);
-    return ((a == b) &amp;&amp; (a &gt;= 0));
-}
-
-static int setup_cis_mem(socket_info_t *s)
-{
-    if (!(s-&gt;cap.features &amp; SS_CAP_STATIC_MAP) &amp;&amp;
-	(s-&gt;cis_mem.sys_start == 0)) {
-	int low = !(s-&gt;cap.features &amp; SS_CAP_PAGE_REGS);
-	vs = s;
-	validate_mem(cis_readable, checksum_match, low, s);
-	s-&gt;cis_mem.sys_start = 0;
-	vs = NULL;
-	if (find_mem_region(&amp;s-&gt;cis_mem.sys_start, s-&gt;cap.map_size,
-			    s-&gt;cap.map_size, low, "card services", s)) {
-	    printk(KERN_NOTICE "cs: unable to map card memory!\n");
-	    return -1;
-	}
-	s-&gt;cis_mem.sys_stop = s-&gt;cis_mem.sys_start+s-&gt;cap.map_size-1;
-	s-&gt;cis_virt = ioremap(s-&gt;cis_mem.sys_start, s-&gt;cap.map_size);
-    }
-    return 0;
-}
-
-void release_cis_mem(socket_info_t *s)
-{
-    if (s-&gt;cis_mem.sys_start != 0) {
-	s-&gt;cis_mem.flags &amp;= ~MAP_ACTIVE;
-	s-&gt;ss_entry-&gt;set_mem_map(s-&gt;sock, &amp;s-&gt;cis_mem);
-	if (!(s-&gt;cap.features &amp; SS_CAP_STATIC_MAP))
-	    release_mem_region(s-&gt;cis_mem.sys_start, s-&gt;cap.map_size);
-	iounmap(s-&gt;cis_virt);
-	s-&gt;cis_mem.sys_start = 0;
-	s-&gt;cis_virt = NULL;
-    }
 }
 
 /*======================================================================

</pre></body></html>