Subject: new asm-mips/io.h

From: Atsushi Nemoto <[email-masked]>
Date: Mon, 26 Nov 2001 12:35:45 +0900 (JST)

A last cleanups for io.h looks bit wrong.  Please apply.

--- linux-sgi-cvs/include/asm-mips/io.h	Mon Nov 26 10:49:40 2001
+++ linux.new/include/asm-mips/io.h	Mon Nov 26 12:06:31 2001
@@ -283,7 +283,7 @@
 {
 	while(count--) {
 		outb(*(__u8 *)addr, port);
-		addr++; port++;
+		addr++;
 	}
 }
 
@@ -291,7 +291,7 @@
 {
 	while(count--) {
 		*(__u8 *)addr = inb(port);
-		addr++; port++;
+		addr++;
 	}
 }
 
@@ -299,7 +299,7 @@
 {
 	while(count--) {
 		outw(*(__u16 *)addr, port);
-		addr+=2; port+=2;
+		addr+=2;
 	}
 }
 
@@ -307,7 +307,7 @@
 {
 	while(count--) {
 		*(__u16 *)addr = inw(port);
-		addr+=2; port+=2;
+		addr+=2;
 	}
 }
 
@@ -315,7 +315,7 @@
 {
 	while(count--) {
 		outl(*(__u32 *)addr, port);
-		addr+=4; port+=4;
+		addr+=4;
 	}
 }
 
@@ -323,7 +323,7 @@
 {
 	while(count--) {
 		*(__u32 *)addr = inw(port);
-		addr+=4; port+=4;
+		addr+=4;
 	}
 }
 
---

By the way, I have some boards which require special I/O routines.
Some of these boards need byteswap on PCI I/O region but noswap on ISA
region.  And some of these boards do not require byteswap but need
swap the address ('port' values).  I added following codes to support
these boards.  Is it worth to apply?

--- linux-sgi-cvs/include/asm-mips/io.h	Mon Nov 26 10:49:40 2001
+++ linux.new/include/asm-mips/io.h	Mon Nov 26 12:06:31 2001
@@ -352,5 +352,88 @@
 #define dma_cache_wback_inv(start,size)	_dma_cache_wback_inv(start,size)
 #define dma_cache_wback(start,size)	_dma_cache_wback(start,size)
 #define dma_cache_inv(start,size)	_dma_cache_inv(start,size)
+
+#ifdef CONFIG_HAVE_BOARD_IO_FUNCS
+/* redefine all I/O access routines */
+struct mips_io_funcs {
+	void (*writeb)(unsigned char b, volatile unsigned char *addr);
+	void (*writew)(unsigned short b, volatile unsigned short *addr);
+	void (*writel)(unsigned int b, volatile unsigned int *addr);
+	unsigned char (*readb)(volatile unsigned char *addr);
+	unsigned short (*readw)(volatile unsigned short *addr);
+	unsigned int (*readl)(volatile unsigned int *addr);
+	void (*outb)(unsigned int value, unsigned long port);
+	void (*outw)(unsigned int value, unsigned long port);
+	void (*outl)(unsigned int value, unsigned long port);
+	unsigned char (*inb)(unsigned long port);
+	unsigned short (*inw)(unsigned long port);
+	unsigned int (*inl)(unsigned long port);
+	void (*outsb)(unsigned long port, const void *addr, unsigned int count);
+	void (*outsw)(unsigned long port, const void *addr, unsigned int count);
+	void (*outsl)(unsigned long port, const void *addr, unsigned int count);
+	void (*insb)(unsigned long port, void *addr, unsigned int count);
+	void (*insw)(unsigned long port, void *addr, unsigned int count);
+	void (*insl)(unsigned long port, void *addr, unsigned int count);
+	void (*memset_io)(volatile void *addr, int c, int len);
+	void (*memcpy_fromio)(void *to, volatile void *from, int len);
+	void (*memcpy_toio)(volatile void *to, const void *from, int len);
+};
+/* board dependent part should declare this variable. */
+extern struct mips_io_funcs mips_io_funcs;
+#undef writeb
+#undef writew
+#undef writel
+#undef readb
+#undef readw
+#undef readl
+#undef outb
+#undef inb
+#undef outb_p
+#undef inb_p
+#undef outw
+#undef inw
+#undef outw_p
+#undef inw_p
+#undef outl
+#undef inl
+#undef outl_p
+#undef inl_p
+#undef outsb
+#undef insb
+#undef outsw
+#undef insw
+#undef outsl
+#undef insl
+#undef memset_io
+#undef memcpy_fromio
+#undef memcpy_toio
+#define writeb(b,addr) (*mips_io_funcs.writeb)(b, (volatile unsigned char *)(addr))
+#define writew(b,addr) (*mips_io_funcs.writew)(b, (volatile unsigned short *)(addr))
+#define writel(b,addr) (*mips_io_funcs.writel)(b, (volatile unsigned int *)(addr))
+#define readb(addr) (*mips_io_funcs.readb)((volatile unsigned char *)(addr))
+#define readw(addr) (*mips_io_funcs.readw)((volatile unsigned short *)(addr))
+#define readl(addr) (*mips_io_funcs.readl)((volatile unsigned int *)(addr))
+#define outb(val,port)	(*mips_io_funcs.outb)((val),(port))
+#define inb(port)	(*mips_io_funcs.inb)(port)
+#define outb_p(val,port)	(*mips_io_funcs.outb)((val),(port))
+#define inb_p(port)	(*mips_io_funcs.inb)(port)
+#define outw(val,port)	(*mips_io_funcs.outw)((val),(port))
+#define inw(port)	(*mips_io_funcs.inw)(port)
+#define outw_p(val,port)	(*mips_io_funcs.outw)((val),(port))
+#define inw_p(port)	(*mips_io_funcs.inw)(port)
+#define outl(val,port)	(*mips_io_funcs.outl)((val),(port))
+#define inl(port)	(*mips_io_funcs.inl)(port)
+#define outl_p(val,port)	(*mips_io_funcs.outl)((val),(port))
+#define inl_p(port)	(*mips_io_funcs.inl)(port)
+#define outsb(port,addr,count)	(*mips_io_funcs.outsb)((port),(addr),(count))
+#define insb(port,addr,count)	(*mips_io_funcs.insb)((port),(addr),(count))
+#define outsw(port,addr,count)	(*mips_io_funcs.outsw)((port),(addr),(count))
+#define insw(port,addr,count)	(*mips_io_funcs.insw)((port),(addr),(count))
+#define outsl(port,addr,count)	(*mips_io_funcs.outsl)((port),(addr),(count))
+#define insl(port,addr,count)	(*mips_io_funcs.insl)((port),(addr),(count))
+#define memset_io(a,b,c)	(*mips_io_funcs.memset_io)((volatile void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	(*mips_io_funcs.memcpy_fromio)((a),(volatile void *)(b),(c))
+#define memcpy_toio(a,b,c)	(*mips_io_funcs.memcpy_toio)((volatile void *)(a),(b),(c))
+#endif /* CONFIG_HAVE_BOARD_IO_FUNCS */
 
 #endif /* _ASM_IO_H */
---
Atsushi Nemoto

---

From: Ralf Baechle <[email-masked]>
Date: Mon, 26 Nov 2001 20:09:46 +1100

> A last cleanups for io.h looks bit wrong.  Please apply.

Yes, the byteswapping stuff (CONFIG_SWAP_IO_SPACE) also got lost.

> these boards.  Is it worth to apply?

Not as is - the kernel has changed, so your patch wouldn't apply anymore.
Aside of that I don't think we'll have any alternative to do something
along the lines of your patch.  There are for example systems where the
high 8 bits of the I/O or memory address on the ISA bus are supplied in
a separate register of the chipset, not as part of the memory address
itself.  It's really remarkable how much bad taste some hardware designers
have ...

  Ralf

---

From: Atsushi Nemoto <[email-masked]>
Date: Tue, 27 Nov 2001 13:04:06 +0900 (JST)

>>>>> On Mon, 26 Nov 2001 20:09:46 +1100, Ralf Baechle <[email-masked]> said:
>> Some of these boards need byteswap on PCI I/O region but noswap on
>> ISA region.  And some of these boards do not require byteswap but
>> need swap the address ('port' values).  I added following codes to
>> support these boards.  Is it worth to apply?

ralf> Not as is - the kernel has changed, so your patch wouldn't apply
ralf> anymore.

Yes, I had not noticed that changes.  Thank you.

ralf> Aside of that I don't think we'll have any alternative to do
ralf> something along the lines of your patch.  There are for example
ralf> systems where the high 8 bits of the I/O or memory address on
ralf> the ISA bus are supplied in a separate register of the chipset,
ralf> not as part of the memory address itself.  It's really
ralf> remarkable how much bad taste some hardware designers have ...

So, what should we do for these tasteless hardware?  Is there any
suggestions? (please don't say "Do not eat" ...)

---
Atsushi Nemoto

---

From: Ralf Baechle <[email-masked]>
Date: Tue, 27 Nov 2001 18:06:48 +1100

On Tue, Nov 27, 2001 at 01:04:06PM +0900, Atsushi Nemoto wrote:

> So, what should we do for these tasteless hardware?

Punish it's developers with fish and chips [1].

> Is there any suggestions? (please don't say "Do not eat" ...)

Not a bad idea in context of fish and chips.

Well, talk to it's developers before it's too late.  Or as it has already
happened for some hardware I think we should simply go with your
suggestion and make all those functions vectors.

  Ralf

[1] Unavoidable part of the Australian experience

---

From: Atsushi Nemoto <[email-masked]>
Date: Tue, 27 Nov 2001 19:10:22 +0900 (JST)

>>>>> On Tue, 27 Nov 2001 18:06:48 +1100, Ralf Baechle <[email-masked]> said:
ralf> Well, talk to it's developers before it's too late.  Or as it
ralf> has already happened for some hardware I think we should simply
ralf> go with your suggestion and make all those functions vectors.

For me, currently it happens only in big endian and I can live happy
in a little endian world.  I will create new patch when I REALLY need
it.  Thank you.

---
Atsushi Nemoto

---

From: Ralf Baechle <[email-masked]>
Date: Wed, 28 Nov 2001 01:19:07 +1100

> in a little endian world.  I will create new patch when I REALLY need

Right now the Linux philosophy is that we don't provide any swapping
facility for I/O port accesses.  Some hardware supports byteswapping for I/O
port and memory access, others must do that in software't, so big endian
systems can set CONFIG_SWAP_IO_SPACE to enable swapping for I/O ports and
memory.  In the past there has been quite some confusion about this and
how to use this properly in drivers ...

  Ralf

---

From: Jun Sun <[email-masked]>
Date: Tue, 27 Nov 2001 09:44:51 -0800

> suggestion and make all those functions vectors.

I don't know about the details of function vectors, but would imagine it would
be 1) slow, 2)clumsy with extra layer of abstraction and 3) intrusive to the
most common cases which is the current io file.

My suggestion is to have a separate io file for the board, and then add the
following to the beginning of io.h:

/* for tasteless boards */
#if defined(CONFIG_TOSHIBA_TASTELESS)
#define _ASM_IO_H		/* so that we don't include the rest */
#include <asm/toshiba/tasteless_io.h>
#endif

This way not only we have minimum impact to the majority, but also easier to
remove such ad hoc support when toshiba becomes more tasteful.

Jun