Re: New resources - pls, explain :-(

Petr Vandrovec (vandrove@vc.cvut.cz)
Thu, 12 Aug 1999 21:27:51 +0200


Hi Linus,
> inline unsigned int readl(unsigned int address)
> {
> if (address < xxx)
> return pci_readl(address);
> if (address < yyy)
> return vme_readl(address);
> if (address < zzz)
> return zorro_readl(address);
> }
No one wants this, I think... It does not cover i2c and if something
other can use ioremap/xxx_readl, it can use little-endian readl
too. Maybe we could push gcc team to optimize (some pseudoasm)
loadle xx,%0
bswap %0
into
loadbe xx,%0
and vice versa? Networking could benefit from this too. And it
should be trivial comparing to alias analysis :-)
> I think we'll just define "readl()" to to be little-endian, and then that
> problem is gone. That takes care of 99% of the market right now, so it
Can I asume that you (we?) just defined it? Now there is only two
outstanding issue: Is it defined whether readl()/writel() does rmb/wmb/mb
before/after memory access (remove what does not apply) or is it
architecture dependent (as it is currently)? And second issue,
what type should be parameter to readl/writel? unsigned long or void*?
Driver uses both, void* is more frequent than unsigned long.
And if we are talking about readl/writel, isn't time to fix i386
drivers for removing (xxx | PAGE_OFFSET) from readx/writex? I'm
using following patch for about year and only warning message I'm
getting is from 'EISA' check during bootup (which can be fixed
by using bus_to_virt(0xFFFD9)...).
Best regards,
Petr Vandrovec
vandrove@vc.cvut.cz

(of course, this patch is not intended for inclusion into 2.3.x,
but ISA devices maintainers should try this if they are not sure...)

diff -urdN linux/include/asm-i386/io.h linux/include/asm-i386/io.h
--- linux/include/asm-i386/io.h Thu May 13 23:42:31 1999
+++ linux/include/asm-i386/io.h Sat Aug 7 22:21:44 1999
@@ -101,8 +101,8 @@
#include <linux/vmalloc.h>
#include <asm/page.h>

-#define __io_virt(x) ((void *)(PAGE_OFFSET | (unsigned long)(x)))
-#define __io_phys(x) ((unsigned long)(x) & ~PAGE_OFFSET)
+#define __io_virt(x) ((void *)(PAGE_OFFSET + (unsigned long)(x)))
+#define __io_phys(x) ((unsigned long)(x) - PAGE_OFFSET)
/*
* Change virtual addresses to physical addresses and vv.
* These are pretty trivial
@@ -149,30 +149,38 @@
* memory location directly.
*/

+extern inline unsigned long __io_virt2(void* addr) {
+ if ((unsigned long)addr < PAGE_OFFSET) {
+ printk("Sorry, access to %lX at %p\n", (unsigned long)addr, __builtin_return_address(0));
+ (unsigned long)addr += PAGE_OFFSET;
+ }
+ return (unsigned long)addr;
+}
-#define readb(addr) (*(volatile unsigned char *) __io_virt(addr))
-#define readw(addr) (*(volatile unsigned short *) __io_virt(addr))
-#define readl(addr) (*(volatile unsigned int *) __io_virt(addr))

+#define readb(addr) (*(volatile unsigned char *) __io_virt2(addr))
+#define readw(addr) (*(volatile unsigned short *) __io_virt2(addr))
+#define readl(addr) (*(volatile unsigned int *) __io_virt2(addr))
-#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b))
-#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b))
-#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b))

+#define writeb(b,addr) (*(volatile unsigned char *) __io_virt2(addr) = (b))
+#define writew(b,addr) (*(volatile unsigned short *) __io_virt2(addr) = (b))
+#define writel(b,addr) (*(volatile unsigned int *) __io_virt2(addr) = (b))
+
-#define memset_io(a,b,c) memset(__io_virt(a),(b),(c))
-#define memcpy_fromio(a,b,c) memcpy((a),__io_virt(b),(c))
-#define memcpy_toio(a,b,c) memcpy(__io_virt(a),(b),(c))
+#define memset_io(a,b,c) memset(__io_virt2(a),(b),(c))
+#define memcpy_fromio(a,b,c) memcpy((a),__io_virt2(b),(c))
+#define memcpy_toio(a,b,c) memcpy(__io_virt2(a),(b),(c))

/*
* Again, i386 does not require mem IO specific function.
*/

-#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(b),(c),(d))
+#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt2(b),(c),(d))

static inline int check_signature(unsigned long io_addr,
const unsigned char *signature, int length)
{
int retval = 0;
do {
- if (readb(io_addr) != *signature)
+ if (readb((void*)io_addr) != *signature)
goto out;
io_addr++;
signature++;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/