Subject: ebsa-285 i/o patch

From: Philip Blundell <[email-masked]>
Date: Sun, 05 Dec 1999 18:48:33 +0000

This patch is needed for various ISA drivers in 2.3.29.  It's about time we 
got rid of IO_FUDGE_FACTOR in any case.

p.

diff -udpNr rmk/linux/include/asm-arm/arch-ebsa285/io.h linux-991205/include/asm-arm/arch-ebsa285/io.h
--- rmk/linux/include/asm-arm/arch-ebsa285/io.h	Wed Nov  3 19:07:36 1999
+++ linux-991205/include/asm-arm/arch-ebsa285/io.h	Sun Dec  5 17:25:27 1999
@@ -55,14 +55,7 @@ extern __inline__ void __outw(unsigned i
 #define valid_ioaddr(iomem,size) ((iomem) < 0x80000000 && (iomem) + (size) <= 0x80000000)
 #define io_to_phys(iomem)	 ((iomem) + DC21285_PCI_MEM)
 
-/*
- * Fudge up IO addresses by this much.  Once we're confident that nobody
- * is using read*() and so on with addresses they didn't get from ioremap
- * this can go away.
- */
-#define IO_FUDGE_FACTOR		PCIMEM_BASE
-
-#define __pci_mem_addr(x)	((void *)(IO_FUDGE_FACTOR + (unsigned long)(x)))
+#define __pci_mem_addr(x)	((void *)(PCIMEM_BASE + (unsigned long)(x)))
 
 /*
  * ioremap takes a PCI memory address, as specified in
@@ -75,8 +68,6 @@ extern __inline__ void __outw(unsigned i
 	if (valid_ioaddr(_addr, _size)) {				\
 		_addr = io_to_phys(_addr);				\
 		_ret = __ioremap(_addr, _size, 0);			\
-		if (_ret)						\
-			_ret = (void *)((int) _ret - IO_FUDGE_FACTOR);	\
 	}								\
 	_ret; })
 
@@ -84,18 +75,46 @@ extern __inline__ void __outw(unsigned i
 
 #define iounmap(_addr)	do { __iounmap(__pci_mem_addr((_addr))); } while (0)
 
-#define readb(addr)	(*(volatile unsigned char *)__pci_mem_addr(addr))
-#define readw(addr)	(*(volatile unsigned short *)__pci_mem_addr(addr))
-#define readl(addr)	(*(volatile unsigned long *)__pci_mem_addr(addr))
+#define readb(addr)	(*(volatile unsigned char *)(addr))
+#define readw(addr)	(*(volatile unsigned short *)(addr))
+#define readl(addr)	(*(volatile unsigned long *)(addr))
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
 
-#define writeb(b,addr)	(*(volatile unsigned char *)__pci_mem_addr(addr) = (b))
-#define writew(b,addr)	(*(volatile unsigned short *)__pci_mem_addr(addr) = (b))
-#define writel(b,addr)	(*(volatile unsigned long *)__pci_mem_addr(addr) = (b))
+#define writeb(b,addr)	(*(volatile unsigned char *)(addr) = (b))
+#define writew(b,addr)	(*(volatile unsigned short *)(addr) = (b))
+#define writel(b,addr)	(*(volatile unsigned long *)(addr) = (b))
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
 
-#define memset_io(a,b,c)	memset(__pci_mem_addr(a),(b),(c))
-#define memcpy_fromio(a,b,c)	memcpy((a),__pci_mem_addr(b),(c))
-#define memcpy_toio(a,b,c)	memcpy(__pci_mem_addr(a),(b),(c))
+#define memset_io(a,b,c)	memset((a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((a),(b),(c))
 
-#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__pci_mem_addr(b),(c),(d))
+#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(b),(c),(d))
+
+/*
+ * ISA space is 'always mapped' on a typical x86 system, no need to
+ * explicitly ioremap() it. The fact that the ISA IO space is mapped
+ * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
+ * are physical addresses. The following constant pointer can be
+ * used as the IO-area pointer (it can be iounmapped as well, so the
+ * analogy with PCI is quite large):
+ */
+#define isa_readb(a) readb(__pci_mem_addr(a))
+#define isa_readw(a) readw(__pci_mem_addr(a))
+#define isa_readl(a) readl(__pci_mem_addr(a))
+#define isa_writeb(b,a) writeb(b, __pci_mem_addr(a))
+#define isa_writew(w,a) writew(w,__pci_mem_addr(a))
+#define isa_writel(l,a) writel(l,__pci_mem_addr(a))
+#define isa_memset_io(a,b,c)		memset_io(__pci_mem_addr(a),(b),(c))
+#define isa_memcpy_fromio(a,b,c)	memcpy_fromio((a),__pci_mem_addr(b),(c))
+#define isa_memcpy_toio(a,b,c)		memcpy_toio(__pci_mem_addr(a),(b),(c))
+
+#define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__pci_mem_addr(b),(c),(d))
+
+#define isa_check_signature(a,b,c) check_signature(__pci_mem_addr(a),(b),(c))
 
 #endif

unsubscribe: body of `unsubscribe linux-arm-kernel' to [email-masked]

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sun, 5 Dec 1999 19:52:29 +0000 (GMT)

> got rid of IO_FUDGE_FACTOR in any case.

Have you checked that the NetWinder tulip driver is still functional?  I
would think that this change makes the kernel Oops when you load the driver.

If you send the patch system a patch for both this and the tulip, it may
find its way into the next kernel release (whenever the mainstream kernel
guys get themselves sorted out so that ARM kernels actually have some
semblence of actually working on more than one architecture again).
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

---

From: Philip Blundell <[email-masked]>
Date: Sun, 05 Dec 1999 20:04:54 +0000

>Have you checked that the NetWinder tulip driver is still functional?

Yes; the version in CVS works on my CATS machine.  I haven't tried a real 
NetWinder but I can't see any reason it should be different.

p.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sun, 5 Dec 1999 20:12:24 +0000 (GMT)

> NetWinder but I can't see any reason it should be different.

The NetWinder's tulip is unlike the usual tulips - its registers are PCI
memory mapped rather than the more normal PCI IO mapping.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

---

From: Philip Blundell <[email-masked]>
Date: Sun, 05 Dec 1999 20:32:50 +0000

>memory mapped rather than the more normal PCI IO mapping.

That is controlled statically by CONFIG_ARCH_NETWINDER (which is set in my 
configuration) rather than being determined by the actual hardware.

p.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sun, 12 Dec 1999 10:17:03 +0000 (GMT)

> configuration) rather than being determined by the actual hardware.

Err, so?  I've just been looking into the change, and it will break the
tulip driver (since the BASE_1 register is used directly in the readl
macros).  Unfortunately, the general architecture of the tulip driver
does not lend itself to ioremap.

If you'd like to resubmit the patch with the tulip driver fixed, I'll
drop it into the 2.3 stuff.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

---

From: Philip Blundell <[email-masked]>
Date: Sun, 12 Dec 1999 11:32:11 +0000

Russell King wrote:

>Err, so?

So it should make no difference whether I run it on an actual NetWinder or 
not.  A driver compiled with CONFIG_ARCH_NETWINDER set should work the same on 
all machines.  As I said, such a driver works fine on my CATS.

>I've just been looking into the change, and it will break the
>macros).

I don't see this.  Please be more specific about the problem.  If you are 
seeing a crash (which it sounds like you are), what does the Oops message 
say?

Are you sure you are looking at the same version of the tulip driver as me?
This one has:

#ifdef CONFIG_ARCH_NETWINDER
#undef inl
#undef outl
#define inl(p)	  readl((p))
#define outl(v,p) writel((v),(p))
#define tulip_resource  iomem_resource
#else
#define tulip_resource  ioport_resource
#endif

and it does seem to use ioremap to get the base address.

p.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sun, 12 Dec 1999 11:35:25 +0000 (GMT)

> and it does seem to use ioremap to get the base address.

Ah, it does?  In that case, it probably doesn't iounmap it actually,
which means it'll waste memory if it's inserted and removed many times.

(I forgot that I fixed it ;().
   _____

---

From: Philip Blundell <[email-masked]>
Date: Sun, 12 Dec 1999 12:03:38 +0000

>Ah, it does?  In that case, it probably doesn't iounmap it actually,

That does look like it's the case.  It also looks suspiciously like it
might be prepared to try and ioremap an I/O address, which isn't too good.

p.

---

From: Philip Blundell <[email-masked]>
Date: Mon, 13 Dec 1999 19:13:47 +0000

Turns out the cyber2000fb driver was broken by that patch, though.  Here's the 
obvious fix.

p.

Index: cyber2000fb.c
===================================================================
RCS file: /cvsroot/pub/kernel/armlinux/drivers/video/cyber2000fb.c,v
retrieving revision 1.11
diff -u -p -r1.11 cyber2000fb.c
--- cyber2000fb.c	1999/12/05 17:16:10	1.11
+++ cyber2000fb.c	1999/12/13 19:13:05
@@ -1404,7 +1404,6 @@ int __init cyber2000fb_init(void)
 		err = -ENOMEM;
 		goto release_smem_resource;
 	}
-current_par.screen_base += PCIMEM_BASE;
 	current_par.screen_size   = smem_size;
 	current_par.screen_base_p = smem_base + 0x80000000;
 	current_par.regs_base_p   = mmio_base + 0x80000000;

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Mon, 13 Dec 1999 19:32:43 +0000 (GMT)

> Turns out the cyber2000fb driver was broken by that patch, though.  Here's the 

Already got that one.

PS, please don't view linux-arm-kernel as a place to post patches to be
integrated into the kernel - the kernel patch system still stands, and
should most definitely be used for all kernel patches.

You may post the patches here in addition to sending them to the
patch system.
   _____