<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"> drivers/pcmcia/cistpl.c |  290 ++++++++++++++++++++++++++----------------------
 1 files changed, 160 insertions(+), 130 deletions(-)

diff -puN drivers/pcmcia/cistpl.c~pcmcia-8 drivers/pcmcia/cistpl.c
--- 25/drivers/pcmcia/cistpl.c~pcmcia-8	2003-03-21 20:04:42.000000000 -0800
+++ 25-akpm/drivers/pcmcia/cistpl.c	2003-03-21 20:04:42.000000000 -0800
@@ -84,121 +84,6 @@ INT_MODULE_PARM(cis_width,	0);		/* 16-bi
 
 /*======================================================================
 
-    Low-level functions to read and write CIS memory.  I think the
-    write routine is only useful for writing one-byte registers.
-    
-======================================================================*/
-
-/* Bits in attr field */
-#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;
-    
-    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;
-	writeb(flags, sys+CISREG_ICTRL0);
-	writeb(addr &amp; 0xff, sys+CISREG_IADDR0);
-	writeb((addr&gt;&gt;8) &amp; 0xff, sys+CISREG_IADDR1);
-	writeb((addr&gt;&gt;16) &amp; 0xff, sys+CISREG_IADDR2);
-	writeb((addr&gt;&gt;24) &amp; 0xff, sys+CISREG_IADDR3);
-	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);
-	while (len) {
-	    set_cis_map(s, mem);
-	    sys = s-&gt;cis_virt + (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;
-		*buf = readb(sys);
-	    }
-	    mem-&gt;card_start += s-&gt;cap.map_size;
-	    addr = 0;
-	}
-    }
-    DEBUG(3, "cs:  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
-	  *(u_char *)(ptr+0), *(u_char *)(ptr+1),
-	  *(u_char *)(ptr+2), *(u_char *)(ptr+3));
-    return 0;
-}
-
-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;
-    
-    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;
-	writeb(flags, sys+CISREG_ICTRL0);
-	writeb(addr &amp; 0xff, sys+CISREG_IADDR0);
-	writeb((addr&gt;&gt;8) &amp; 0xff, sys+CISREG_IADDR1);
-	writeb((addr&gt;&gt;16) &amp; 0xff, sys+CISREG_IADDR2);
-	writeb((addr&gt;&gt;24) &amp; 0xff, sys+CISREG_IADDR3);
-	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);
-	while (len) {
-	    set_cis_map(s, mem);
-	    sys = s-&gt;cis_virt + (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;
-		writeb(*buf, sys);
-	    }
-	    mem-&gt;card_start += 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.
     
@@ -256,36 +141,181 @@ static int checksum_match(u_long base)
     return ((a == b) &amp;&amp; (a &gt;= 0));
 }
 
-static int setup_cis_mem(socket_info_t *s)
+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;
-	(s-&gt;cis_mem.sys_start == 0)) {
+	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);
-	s-&gt;cis_mem.sys_start = 0;
+	mem-&gt;sys_start = 0;
 	vs = NULL;
-	if (find_mem_region(&amp;s-&gt;cis_mem.sys_start, s-&gt;cap.map_size,
+	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
+    write routine is only useful for writing one-byte registers.
+    
+======================================================================*/
+
+/* Bits in attr field */
+#define IS_ATTR		1
+#define IS_INDIRECT	8
+
+int read_cis_mem(socket_info_t *s, int attr, u_int addr,
+		 u_int len, void *ptr)
+{
+    u_char *sys, *end, *buf = ptr;
+    
+    DEBUG(3, "cs: read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+
+    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;
+	}
+
+	sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
+	if (!sys) {
+	    memset(ptr, 0xff, len);
 	    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);
+
+	writeb(flags, sys+CISREG_ICTRL0);
+	writeb(addr &amp; 0xff, sys+CISREG_IADDR0);
+	writeb((addr&gt;&gt;8) &amp; 0xff, sys+CISREG_IADDR1);
+	writeb((addr&gt;&gt;16) &amp; 0xff, sys+CISREG_IADDR2);
+	writeb((addr&gt;&gt;24) &amp; 0xff, sys+CISREG_IADDR3);
+	for ( ; len &gt; 0; len--, buf++)
+	    *buf = readb(sys+CISREG_IDATA0);
+    } else {
+	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) {
+	    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 == end)
+		    break;
+		*buf = readb(sys);
+	    }
+	    card_offset += s-&gt;cap.map_size;
+	    addr = 0;
+	}
     }
+    DEBUG(3, "cs:  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
+	  *(u_char *)(ptr+0), *(u_char *)(ptr+1),
+	  *(u_char *)(ptr+2), *(u_char *)(ptr+3));
     return 0;
 }
 
-void release_cis_mem(socket_info_t *s)
+void write_cis_mem(socket_info_t *s, int attr, u_int addr,
+		   u_int len, void *ptr)
 {
-    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;
+    u_char *sys, *end, *buf = ptr;
+    
+    DEBUG(3, "cs: write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+
+    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;
+	}
+
+	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);
+	writeb((addr&gt;&gt;16) &amp; 0xff, sys+CISREG_IADDR2);
+	writeb((addr&gt;&gt;24) &amp; 0xff, sys+CISREG_IADDR3);
+	for ( ; len &gt; 0; len--, buf++)
+	    writeb(*buf, sys+CISREG_IDATA0);
+    } else {
+	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) {
+	    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 == end)
+		    break;
+		writeb(*buf, sys);
+	    }
+	    card_offset += s-&gt;cap.map_size;
+	    addr = 0;
+	}
     }
 }
 

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