Messages in this thread Patch in this message | | | Date | Thu, 12 Aug 1999 21:27:51 +0200 | From | Petr Vandrovec <> | Subject | Re: New resources - pls, explain :-( |
| |
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/
| |