* [PATCH] I/O helpers rework
@ 2004-12-15 21:13 Maciej W. Rozycki
2005-01-06 15:45 ` Atsushi Nemoto
` (2 more replies)
0 siblings, 3 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2004-12-15 21:13 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips, Maciej W. Rozycki
Hello,
While trying using an IDE interface driver with big-endian systems, I've
noticed some of our port/mm I/O accessory functions/macros get endianness
incorrectly. In particular a lot of drivers expect single I/O accesses to
return correct numerical value of data as seen by the CPU while string I/O
accesses to preserve byte ordering in memory.
As the whole file seemed a bit messy to me I decided to rewrite these
functions/macros completely. To ease long-term maintenance I created
common templates for all classes of accesses which expand to appropriate
code for different transfer unit width. I made all operations to be
expressed as inline functions to catch dangerous/incorrect uses. The
result are the following function classes:
1. in*()/out*()/read*()/write*() perform single operations on data using
little-endian ordering.
2. __raw_in*()/__raw_out*()/__raw_read*()/__raw_write*() perform single
operations on data using memory ordering.
3. bus_read*()/bus_write*() perform single on data using CPU bus ordering
(that is as it appears at the bus, regardless of any address or lane
swappers that may modify it on the way between the CPU and a device).
4. __bus_readq()/__bus_writeq() are hacks for 64-bit accesses avoiding
interrupt masking when used with a 32-bit kernel and are otherwise the
same as bus_readq()/bus_writeq().
5. ins*()/outs*()/reads*()/writes*() perform string operations on data
using memory ordering yielding the same result as a corresponding DMA
transfer would.
The naming of 1., 2. and perhaps 5. above is a bit unfortunate, but that's
what much code elsewhere expects. These variants assume a ISA/EISA/PCI
bus, little-endian. They perform minimum of swapping required -- they
avoid swapping data back and forth to keep good performance. For
buses/devices that follow CPU endianness use 3. or perhaps 4. if
interrupts have already been masked.
The changes have been verified with a Malta board for port I/O and with a
SWARM one for memory-mapped I/O (with an updated driver; to be sent
separately). Broadcom SiByte systems are the only ones utilizing current
__raw_*() and ____raw_*() calls. I have a patch to convert them to
bus_*() and __bus_*() ones as appropriate ready as well.
OK to apply?
Maciej
patch-mips-2.6.10-rc2-20041124-mips-ide-27
diff -up --recursive --new-file linux-mips-2.6.10-rc2-20041124.macro/include/asm-mips/io.h linux-mips-2.6.10-rc2-20041124/include/asm-mips/io.h
--- linux-mips-2.6.10-rc2-20041124.macro/include/asm-mips/io.h 2004-11-22 14:27:59.000000000 +0000
+++ linux-mips-2.6.10-rc2-20041124/include/asm-mips/io.h 2004-12-13 13:05:29.000000000 +0000
@@ -6,21 +6,26 @@
* Copyright (C) 1994, 1995 Waldorf GmbH
* Copyright (C) 1994 - 2000 Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2004 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
*/
#ifndef _ASM_IO_H
#define _ASM_IO_H
#include <linux/config.h>
#include <linux/compiler.h>
+#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/addrspace.h>
+#include <asm/bug.h>
+#include <asm/byteorder.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
#include <asm/page.h>
#include <asm/pgtable-bits.h>
#include <asm/processor.h>
-#include <asm/byteorder.h>
+
#include <mangle-port.h>
/*
@@ -29,34 +34,52 @@
#undef CONF_SLOWDOWN_IO
/*
- * Sane hardware offers swapping of I/O space accesses in hardware; less
- * sane hardware forces software to fiddle with this ...
+ * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
+ * less sane hardware forces software to fiddle with this...
*/
-#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
+#if defined(CONFIG_SWAP_IO_SPACE)
-#define __ioswab8(x) (x)
-
-#ifdef CONFIG_SGI_IP22
+# define ioswabb(x) (x)
+# define __raw_ioswabb(x) (x)
+# ifdef CONFIG_SGI_IP22
/*
* IP22 seems braindead enough to swap 16bits values in hardware, but
* not 32bits. Go figure... Can't tell without documentation.
*/
-#define __ioswab16(x) (x)
-#else
-#define __ioswab16(x) swab16(x)
-#endif
-#define __ioswab32(x) swab32(x)
-#define __ioswab64(x) swab64(x)
+# define ioswabw(x) (x)
+# define __raw_ioswabw(x) le16_to_cpu(x)
+# else
+# define ioswabw(x) le16_to_cpu(x)
+# define __raw_ioswabw(x) (x)
+# endif
+# define ioswabl(x) le32_to_cpu(x)
+# define __raw_ioswabl(x) (x)
+# define ioswabq(x) le64_to_cpu(x)
+# define __raw_ioswabq(x) (x)
#else
-#define __ioswab8(x) (x)
-#define __ioswab16(x) (x)
-#define __ioswab32(x) (x)
-#define __ioswab64(x) (x)
+# define ioswabb(x) (x)
+# define __raw_ioswabb(x) (x)
+# define ioswabw(x) (x)
+# define __raw_ioswabw(x) cpu_to_le16(x)
+# define ioswabl(x) (x)
+# define __raw_ioswabl(x) cpu_to_le32(x)
+# define ioswabq(x) (x)
+# define __raw_ioswabq(x) cpu_to_le64(x)
#endif
+/*
+ * Native bus accesses never swapped.
+ */
+#define bus_ioswabb(x) (x)
+#define bus_ioswabw(x) (x)
+#define bus_ioswabl(x) (x)
+#define bus_ioswabq(x) (x)
+
+#define __bus_ioswabq bus_ioswabq
+
#define IO_SPACE_LIMIT 0xffff
/*
@@ -245,108 +268,202 @@ static inline void iounmap(volatile void
__iounmap(addr);
}
-#define __raw_readb(addr) \
- (*(volatile unsigned char *) __swizzle_addr_b((unsigned long)(addr)))
-#define __raw_readw(addr) \
- (*(volatile unsigned short *) __swizzle_addr_w((unsigned long)(addr)))
-#define __raw_readl(addr) \
- (*(volatile unsigned int *) __swizzle_addr_l((unsigned long)(addr)))
-#ifdef CONFIG_MIPS32
-#define ____raw_readq(addr) \
-({ \
- u64 __res; \
- \
- __asm__ __volatile__ ( \
- " .set mips3 # ____raw_readq \n" \
- " ld %L0, (%1) \n" \
- " dsra32 %M0, %L0, 0 \n" \
- " sll %L0, %L0, 0 \n" \
- " .set mips0 \n" \
- : "=r" (__res) \
- : "r" (__swizzle_addr_q((unsigned long)(addr)))); \
- __res; \
-})
-#define __raw_readq(addr) \
-({ \
- unsigned long __flags; \
- u64 __res; \
- \
- local_irq_save(__flags); \
- __res = ____raw_readq(addr); \
- local_irq_restore(__flags); \
- __res; \
-})
-#endif
-#ifdef CONFIG_MIPS64
-#define ____raw_readq(addr) \
- (*(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)))
-#define __raw_readq(addr) ____raw_readq(addr)
-#endif
-#define readb(addr) __ioswab8(__raw_readb(addr))
-#define readw(addr) __ioswab16(__raw_readw(addr))
-#define readl(addr) __ioswab32(__raw_readl(addr))
-#define readq(addr) __ioswab64(__raw_readq(addr))
-#define readb_relaxed(addr) readb(addr)
-#define readw_relaxed(addr) readw(addr)
-#define readl_relaxed(addr) readl(addr)
-#define readq_relaxed(addr) readq(addr)
-
-#define __raw_writeb(b,addr) \
-do { \
- ((*(volatile unsigned char *)__swizzle_addr_b((unsigned long)(addr))) = (b)); \
-} while (0)
-
-#define __raw_writew(w,addr) \
-do { \
- ((*(volatile unsigned short *)__swizzle_addr_w((unsigned long)(addr))) = (w)); \
-} while (0)
-
-#define __raw_writel(l,addr) \
-do { \
- ((*(volatile unsigned int *)__swizzle_addr_l((unsigned long)(addr))) = (l)); \
-} while (0)
-
-#ifdef CONFIG_MIPS32
-#define ____raw_writeq(val,addr) \
-do { \
- u64 __tmp; \
- \
- __asm__ __volatile__ ( \
- " .set mips3 \n" \
- " dsll32 %L0, %L0, 0 # ____raw_writeq\n" \
- " dsrl32 %L0, %L0, 0 \n" \
- " dsll32 %M0, %M0, 0 \n" \
- " or %L0, %L0, %M0 \n" \
- " sd %L0, (%2) \n" \
- " .set mips0 \n" \
- : "=r" (__tmp) \
- : "0" ((unsigned long long)val), \
- "r" (__swizzle_addr_q((unsigned long)(addr)))); \
-} while (0)
-
-#define __raw_writeq(val,addr) \
-do { \
- unsigned long __flags; \
- \
- local_irq_save(__flags); \
- ____raw_writeq(val, addr); \
- local_irq_restore(__flags); \
-} while (0)
-#endif
-#ifdef CONFIG_MIPS64
-#define ____raw_writeq(q,addr) \
-do { \
- *(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)) = (q); \
-} while (0)
+#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
+ \
+static inline void pfx##write##bwlq(type val, void *mem) \
+{ \
+ volatile type *__mem; \
+ type __val; \
+ \
+ __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
+ \
+ __val = pfx##ioswab##bwlq(val); \
+ \
+ if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
+ *__mem = __val; \
+ else if (cpu_has_64bits) { \
+ unsigned long __flags; \
+ type __tmp; \
+ \
+ if (irq) \
+ local_irq_save(__flags); \
+ __asm__ __volatile__( \
+ ".set mips3" "\t\t# __writeq""\n\t" \
+ "dsll32 %L0, %L0, 0" "\n\t" \
+ "dsrl32 %L0, %L0, 0" "\n\t" \
+ "dsll32 %M0, %M0, 0" "\n\t" \
+ "or %L0, %L0, %M0" "\n\t" \
+ "sd %L0, %2" "\n\t" \
+ ".set mips0" "\n" \
+ : "=r" (__tmp) \
+ : "0" (__val), "m" (*__mem)); \
+ if (irq) \
+ local_irq_restore(__flags); \
+ } else \
+ BUG(); \
+} \
+ \
+static inline type pfx##read##bwlq(void *mem) \
+{ \
+ volatile type *__mem; \
+ type __val; \
+ \
+ __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
+ \
+ if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
+ __val = *__mem; \
+ else if (cpu_has_64bits) { \
+ unsigned long __flags; \
+ \
+ local_irq_save(__flags); \
+ __asm__ __volatile__( \
+ ".set mips3" "\t\t# __readq" "\n\t" \
+ "ld %L0, %1" "\n\t" \
+ "dsra32 %M0, %L0, 0" "\n\t" \
+ "sll %L0, %L0, 0" "\n\t" \
+ ".set mips0" "\n" \
+ : "=r" (__val) \
+ : "m" (*__mem)); \
+ local_irq_restore(__flags); \
+ } else { \
+ __val = 0; \
+ BUG(); \
+ } \
+ \
+ return pfx##ioswab##bwlq(__val); \
+}
-#define __raw_writeq(q,addr) ____raw_writeq(q, addr)
-#endif
+#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \
+ \
+static inline void pfx##out##bwlq##p(type val, unsigned long port) \
+{ \
+ volatile type *__addr; \
+ type __val; \
+ \
+ port = __swizzle_addr_##bwlq(port); \
+ __addr = (void *)(mips_io_port_base + port); \
+ \
+ __val = pfx##ioswab##bwlq(val); \
+ \
+ if (sizeof(type) != sizeof(u64)) { \
+ *__addr = __val; \
+ slow; \
+ } else \
+ BUILD_BUG(); \
+} \
+ \
+static inline type pfx##in##bwlq##p(unsigned long port) \
+{ \
+ volatile type *__addr; \
+ type __val; \
+ \
+ port = __swizzle_addr_##bwlq(port); \
+ __addr = (void *)(mips_io_port_base + port); \
+ \
+ if (sizeof(type) != sizeof(u64)) { \
+ __val = *__addr; \
+ slow; \
+ } else { \
+ __val = 0; \
+ BUILD_BUG(); \
+ } \
+ \
+ return pfx##ioswab##bwlq(__val); \
+}
+
+#define __BUILD_MEMORY_PFX(bus, bwlq, type) \
+ \
+__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
+
+#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
+ \
+__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
+__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
+
+#define BUILDIO(bwlq, type) \
+ \
+__BUILD_MEMORY_PFX(, bwlq, type) \
+__BUILD_MEMORY_PFX(__raw_, bwlq, type) \
+__BUILD_MEMORY_PFX(bus_, bwlq, type) \
+__BUILD_IOPORT_PFX(, bwlq, type) \
+__BUILD_IOPORT_PFX(__raw_, bwlq, type)
+
+#define __BUILDIO(bwlq, type) \
+ \
+__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0)
+
+BUILDIO(b, u8)
+BUILDIO(w, u16)
+BUILDIO(l, u32)
+BUILDIO(q, u64)
+
+__BUILDIO(q, u64)
+
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
+#define readq_relaxed readq
+
+
+#define __BUILD_MEMORY_STRING(bwlq, type) \
+ \
+static inline void writes##bwlq(void *mem, void *addr, \
+ unsigned int count) \
+{ \
+ volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ __raw_write##bwlq(*__addr, mem); \
+ __addr++; \
+ } \
+} \
+ \
+static inline void reads##bwlq(void *mem, void *addr, \
+ unsigned int count) \
+{ \
+ volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ *__addr = __raw_read##bwlq(mem); \
+ __addr++; \
+ } \
+}
+
+#define __BUILD_IOPORT_STRING(bwlq, type) \
+ \
+static inline void outs##bwlq(unsigned long port, void *addr, \
+ unsigned int count) \
+{ \
+ volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ __raw_out##bwlq(*__addr, port); \
+ __addr++; \
+ } \
+} \
+ \
+static inline void ins##bwlq(unsigned long port, void *addr, \
+ unsigned int count) \
+{ \
+ volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ *__addr = __raw_in##bwlq(port); \
+ __addr++; \
+ } \
+}
+
+#define BUILDSTRING(bwlq, type) \
+ \
+__BUILD_MEMORY_STRING(bwlq, type) \
+__BUILD_IOPORT_STRING(bwlq, type)
+
+BUILDSTRING(b, u8)
+BUILDSTRING(w, u16)
+BUILDSTRING(l, u32)
+BUILDSTRING(q, u64)
-#define writeb(b,addr) __raw_writeb(__ioswab8(b),(addr))
-#define writew(w,addr) __raw_writew(__ioswab16(w),(addr))
-#define writel(l,addr) __raw_writel(__ioswab32(l),(addr))
-#define writeq(q,addr) __raw_writeq(__ioswab64(q),(addr))
/* Depends on MIPS II instruction set */
#define mmiowb() asm volatile ("sync" ::: "memory")
@@ -394,7 +511,7 @@ do { \
* address should have been obtained by ioremap.
* Returns 1 on a match.
*/
-static inline int check_signature(unsigned long io_addr,
+static inline int check_signature(char __iomem *io_addr,
const unsigned char *signature, int length)
{
int retval = 0;
@@ -424,177 +541,6 @@ out:
*/
#define isa_check_signature(io, s, l) check_signature(i,s,l)
-static inline void __outb(unsigned char val, unsigned long port)
-{
- port = __swizzle_addr_b(port);
-
- *(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val);
-}
-
-static inline void __outw(unsigned short val, unsigned long port)
-{
- port = __swizzle_addr_w(port);
-
- *(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val);
-}
-
-static inline void __outl(unsigned int val, unsigned long port)
-{
- port = __swizzle_addr_l(port);
-
- *(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val);
-}
-
-static inline void __outb_p(unsigned char val, unsigned long port)
-{
- port = __swizzle_addr_b(port);
-
- *(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val);
- SLOW_DOWN_IO;
-}
-
-static inline void __outw_p(unsigned short val, unsigned long port)
-{
- port = __swizzle_addr_w(port);
-
- *(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val);
- SLOW_DOWN_IO;
-}
-
-static inline void __outl_p(unsigned int val, unsigned long port)
-{
- port = __swizzle_addr_l(port);
-
- *(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val);
- SLOW_DOWN_IO;
-}
-
-#define outb(val, port) __outb(val, port)
-#define outw(val, port) __outw(val, port)
-#define outl(val, port) __outl(val, port)
-#define outb_p(val, port) __outb_p(val, port)
-#define outw_p(val, port) __outw_p(val, port)
-#define outl_p(val, port) __outl_p(val, port)
-
-static inline unsigned char __inb(unsigned long port)
-{
- port = __swizzle_addr_b(port);
-
- return __ioswab8(*(volatile u8 *)(mips_io_port_base + port));
-}
-
-static inline unsigned short __inw(unsigned long port)
-{
- port = __swizzle_addr_w(port);
-
- return __ioswab16(*(volatile u16 *)(mips_io_port_base + port));
-}
-
-static inline unsigned int __inl(unsigned long port)
-{
- port = __swizzle_addr_l(port);
-
- return __ioswab32(*(volatile u32 *)(mips_io_port_base + port));
-}
-
-static inline unsigned char __inb_p(unsigned long port)
-{
- u8 __val;
-
- port = __swizzle_addr_b(port);
-
- __val = *(volatile u8 *)(mips_io_port_base + port);
- SLOW_DOWN_IO;
-
- return __ioswab8(__val);
-}
-
-static inline unsigned short __inw_p(unsigned long port)
-{
- u16 __val;
-
- port = __swizzle_addr_w(port);
-
- __val = *(volatile u16 *)(mips_io_port_base + port);
- SLOW_DOWN_IO;
-
- return __ioswab16(__val);
-}
-
-static inline unsigned int __inl_p(unsigned long port)
-{
- u32 __val;
-
- port = __swizzle_addr_l(port);
-
- __val = *(volatile u32 *)(mips_io_port_base + port);
- SLOW_DOWN_IO;
-
- return __ioswab32(__val);
-}
-
-#define inb(port) __inb(port)
-#define inw(port) __inw(port)
-#define inl(port) __inl(port)
-#define inb_p(port) __inb_p(port)
-#define inw_p(port) __inw_p(port)
-#define inl_p(port) __inl_p(port)
-
-static inline void __outsb(unsigned long port, void *addr, unsigned int count)
-{
- while (count--) {
- outb(*(u8 *)addr, port);
- addr++;
- }
-}
-
-static inline void __insb(unsigned long port, void *addr, unsigned int count)
-{
- while (count--) {
- *(u8 *)addr = inb(port);
- addr++;
- }
-}
-
-static inline void __outsw(unsigned long port, void *addr, unsigned int count)
-{
- while (count--) {
- outw(*(u16 *)addr, port);
- addr += 2;
- }
-}
-
-static inline void __insw(unsigned long port, void *addr, unsigned int count)
-{
- while (count--) {
- *(u16 *)addr = inw(port);
- addr += 2;
- }
-}
-
-static inline void __outsl(unsigned long port, void *addr, unsigned int count)
-{
- while (count--) {
- outl(*(u32 *)addr, port);
- addr += 4;
- }
-}
-
-static inline void __insl(unsigned long port, void *addr, unsigned int count)
-{
- while (count--) {
- *(u32 *)addr = inl(port);
- addr += 4;
- }
-}
-
-#define outsb(port, addr, count) __outsb(port, addr, count)
-#define insb(port, addr, count) __insb(port, addr, count)
-#define outsw(port, addr, count) __outsw(port, addr, count)
-#define insw(port, addr, count) __insw(port, addr, count)
-#define outsl(port, addr, count) __outsl(port, addr, count)
-#define insl(port, addr, count) __insl(port, addr, count)
-
/*
* The caches on some architectures aren't dma-coherent and have need to
* handle this in software. There are three types of operations that
diff -up --recursive --new-file linux-mips-2.6.10-rc2-20041124.macro/include/asm-mips/mach-generic/ide.h linux-mips-2.6.10-rc2-20041124/include/asm-mips/mach-generic/ide.h
--- linux-mips-2.6.10-rc2-20041124.macro/include/asm-mips/mach-generic/ide.h 2004-11-24 21:37:52.000000000 +0000
+++ linux-mips-2.6.10-rc2-20041124/include/asm-mips/mach-generic/ide.h 2004-12-14 17:25:36.000000000 +0000
@@ -64,7 +64,17 @@ static __inline__ unsigned long ide_defa
#define ide_init_default_irq(base) ide_default_irq(base)
#endif
-#include <asm-generic/ide_iops.h>
+/* MIPS port and memory-mapped I/O string operations. */
+
+#define __ide_insw insw
+#define __ide_insl insl
+#define __ide_outsw outsw
+#define __ide_outsl outsl
+
+#define __ide_mm_insw readsw
+#define __ide_mm_insl readsl
+#define __ide_mm_outsw writesw
+#define __ide_mm_outsl writesl
#endif /* __KERNEL__ */
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH] I/O helpers rework
2004-12-15 21:13 [PATCH] I/O helpers rework Maciej W. Rozycki
@ 2005-01-06 15:45 ` Atsushi Nemoto
2005-01-10 15:28 ` Maciej W. Rozycki
2005-01-21 16:50 ` Atsushi Nemoto
2005-01-06 16:33 ` Herbert Valerio Riedel
2005-01-13 22:18 ` Manish Lachwani
2 siblings, 2 replies; 23+ messages in thread
From: Atsushi Nemoto @ 2005-01-06 15:45 UTC (permalink / raw)
To: macro; +Cc: ralf, linux-mips, macro
>>>>> On Wed, 15 Dec 2004 21:13:37 +0000 (GMT), "Maciej W. Rozycki" <macro@mips.com> said:
macro> As the whole file seemed a bit messy to me I decided to
macro> rewrite these functions/macros completely. To ease long-term
macro> maintenance I created common templates for all classes of
macro> accesses which expand to appropriate code for different
macro> transfer unit width. I made all operations to be expressed as
macro> inline functions to catch dangerous/incorrect uses. The result
macro> are the following function classes:
Thanks for your good job. I have a few comments/requests.
1. How about adding 'volatile' and '__iomem' to *read*()/*write*() ?
While some archs use 'volatile void __iomem *' and some are not, I
think *read*()/*write*()/ioremap()/iounmap() should use same type.
This will remove some compiler warnings.
2. How about using 'const void *' for outs*()? This will remove some
compiler warnings too.
3. In *in*()/*out*(), it would be better to call __swizzle_addr*()
AFTER adding mips_io_port_base. This unifies the meaning of the
argument of __swizzle_addr*() (always virtual address). Then,
mach-specific __swizzle_addr*() can to every evil thing based on
the argument.
4. How about enclosing all *ioswab*() by '#ifndef' ? Also how about
passing virtual address to *ioswab*() ? I mean something like:
# ifndef ioswabw
# define ioswabw(a,x) le16_to_cpu(x)
# endif
# ifndef __raw_ioswabw
# define __raw_ioswabw(a,x) (x)
# endif
...
__val = pfx##ioswab##bwlq(__mem, val); \
Then we can provide mach-specific *ioswab*() in mach-*/mangle-port.h
and can do every evil thing based on its argument. It is usefull on
machines which have regions with defirrent endian conversion scheme.
Also, this can clean up CONFIG_SGI_IP22 from io.h
(mach-ip22/mangle-port.h can provide its own *ioswabw*()).
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-06 15:45 ` Atsushi Nemoto
@ 2005-01-10 15:28 ` Maciej W. Rozycki
2005-01-10 17:21 ` Atsushi Nemoto
2005-01-21 16:50 ` Atsushi Nemoto
1 sibling, 1 reply; 23+ messages in thread
From: Maciej W. Rozycki @ 2005-01-10 15:28 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: ralf, linux-mips, macro
On Fri, 7 Jan 2005, Atsushi Nemoto wrote:
> 1. How about adding 'volatile' and '__iomem' to *read*()/*write*() ?
> While some archs use 'volatile void __iomem *' and some are not, I
> think *read*()/*write*()/ioremap()/iounmap() should use same type.
> This will remove some compiler warnings.
Hmm, what's the semantics of "volatile void *"? I can't imagine any, so
I don't think it would be useful. OTOH, I do agree the types used should
be the same for all the mentioned functions and I'm inclined to make it
"void __iomem *". For *read*(), "const" would be included as well.
> 2. How about using 'const void *' for outs*()? This will remove some
> compiler warnings too.
Agreed.
> 3. In *in*()/*out*(), it would be better to call __swizzle_addr*()
> AFTER adding mips_io_port_base. This unifies the meaning of the
> argument of __swizzle_addr*() (always virtual address). Then,
> mach-specific __swizzle_addr*() can to every evil thing based on
> the argument.
Well, it shouldn't really matter as mips_io_port_base is expected to be
page-aligned anyway. But I have no objections either.
> 4. How about enclosing all *ioswab*() by '#ifndef' ? Also how about
> passing virtual address to *ioswab*() ? I mean something like:
>
> # ifndef ioswabw
> # define ioswabw(a,x) le16_to_cpu(x)
> # endif
> # ifndef __raw_ioswabw
> # define __raw_ioswabw(a,x) (x)
> # endif
> ...
> __val = pfx##ioswab##bwlq(__mem, val); \
>
> Then we can provide mach-specific *ioswab*() in mach-*/mangle-port.h
> and can do every evil thing based on its argument. It is usefull on
> machines which have regions with defirrent endian conversion scheme.
> Also, this can clean up CONFIG_SGI_IP22 from io.h
> (mach-ip22/mangle-port.h can provide its own *ioswabw*()).
Instead of using "#ifndef" the generic versions could be moved to
<asm-mips/mach-generic/mangle-port.h>. Otherwise it sounds reasonable.
Note that __mem is a virtual address, though, so you'd have to perform a
physical address lookup before deciding on a swapping strategy -- would we
really have a gain on any system from using regions with different
swapping properties?
Thanks for your feedback.
Maciej
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-10 15:28 ` Maciej W. Rozycki
@ 2005-01-10 17:21 ` Atsushi Nemoto
2005-01-10 18:11 ` Maciej W. Rozycki
0 siblings, 1 reply; 23+ messages in thread
From: Atsushi Nemoto @ 2005-01-10 17:21 UTC (permalink / raw)
To: macro; +Cc: ralf, linux-mips, macro
>>>>> On Mon, 10 Jan 2005 15:28:24 +0000 (GMT), "Maciej W. Rozycki" <macro@mips.com> said:
macro> Hmm, what's the semantics of "volatile void *"? I can't
macro> imagine any, so I don't think it would be useful.
Well, maybe the 'volatile' have no sense, but some archs (including
i386, of course :-)) and some drivers use it. Adding the 'volatile'
will remove some compiler warnings.
macro> Instead of using "#ifndef" the generic versions could be moved
macro> to <asm-mips/mach-generic/mangle-port.h>. Otherwise it sounds
macro> reasonable.
Hmm, if all *ioswab*() were moved to mangle-port.h,
mach-ip22/mangle-port.h (for example) must provide all *ioswab*()
instead of only ioswabw() and __raw_ioswabw(). OTOH providing
complete set of *ioswab* in one file might be better to understand the
code. Both are acceptable for me.
macro> Note that __mem is a virtual address, though, so you'd have to
macro> perform a physical address lookup before deciding on a swapping
macro> strategy -- would we really have a gain on any system from
macro> using regions with different swapping properties?
Yes, virt-to-phys conversion might be needed, but if we only use KSEG1
for I/O port/memory, it does not matter.
And I have some custom boards which really needs different swapping
properties (PCI regions need SWAP_IO_SPACE, but ISA region does not,
for example). I agree that those boards were misdesigned but I want
to run Linux on it without modifying existing drivers.
Thank you.
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-10 17:21 ` Atsushi Nemoto
@ 2005-01-10 18:11 ` Maciej W. Rozycki
2005-01-11 0:53 ` Atsushi Nemoto
2005-01-13 18:12 ` Richard Sandiford
0 siblings, 2 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2005-01-10 18:11 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: ralf, linux-mips, macro
On Tue, 11 Jan 2005, Atsushi Nemoto wrote:
> Well, maybe the 'volatile' have no sense, but some archs (including
> i386, of course :-)) and some drivers use it. Adding the 'volatile'
> will remove some compiler warnings.
As will removing "volatile" from broken ports.
> Yes, virt-to-phys conversion might be needed, but if we only use KSEG1
> for I/O port/memory, it does not matter.
ioremap() is free to return a KSEG2 address on a 32-bit system. With
64-bit systems there is no problem.
> And I have some custom boards which really needs different swapping
> properties (PCI regions need SWAP_IO_SPACE, but ISA region does not,
> for example). I agree that those boards were misdesigned but I want
> to run Linux on it without modifying existing drivers.
Hmm, that's strange -- does the system glue ISA otherwise than behind a
PCI-ISA bridge? So far I've only spotted a single PCI/ISA system wiring
the buses as "peers", namely the ancient Intel's i82420EX for 486-class
processors.
Maciej
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-10 18:11 ` Maciej W. Rozycki
@ 2005-01-11 0:53 ` Atsushi Nemoto
2005-01-13 18:12 ` Richard Sandiford
1 sibling, 0 replies; 23+ messages in thread
From: Atsushi Nemoto @ 2005-01-11 0:53 UTC (permalink / raw)
To: macro; +Cc: ralf, linux-mips, macro
>>>>> On Mon, 10 Jan 2005 18:11:14 +0000 (GMT), "Maciej W. Rozycki" <macro@mips.com> said:
>> Well, maybe the 'volatile' have no sense, but some archs (including
>> i386, of course :-)) and some drivers use it. Adding the
>> 'volatile' will remove some compiler warnings.
macro> As will removing "volatile" from broken ports.
Sure.
>> And I have some custom boards which really needs different swapping
>> properties (PCI regions need SWAP_IO_SPACE, but ISA region does
>> not, for example). I agree that those boards were misdesigned but
>> I want to run Linux on it without modifying existing drivers.
macro> Hmm, that's strange -- does the system glue ISA otherwise than
macro> behind a PCI-ISA bridge? So far I've only spotted a single
macro> PCI/ISA system wiring the buses as "peers", namely the ancient
macro> Intel's i82420EX for 486-class processors.
Yes. The system have ISA devices connected via local bus (like ROMs).
Also I have an another system which have two PCI controllers with
different endian conversion (what mad hardware!).
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-10 18:11 ` Maciej W. Rozycki
2005-01-11 0:53 ` Atsushi Nemoto
@ 2005-01-13 18:12 ` Richard Sandiford
2005-01-13 18:25 ` Maciej W. Rozycki
1 sibling, 1 reply; 23+ messages in thread
From: Richard Sandiford @ 2005-01-13 18:12 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Atsushi Nemoto, ralf, linux-mips, macro
"Maciej W. Rozycki" <macro@mips.com> writes:
> On Tue, 11 Jan 2005, Atsushi Nemoto wrote:
>
>> Well, maybe the 'volatile' have no sense, but some archs (including
>> i386, of course :-)) and some drivers use it. Adding the 'volatile'
>> will remove some compiler warnings.
>
> As will removing "volatile" from broken ports.
There's nothing wrong with "volatile void *".
Richard
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-13 18:12 ` Richard Sandiford
@ 2005-01-13 18:25 ` Maciej W. Rozycki
2005-01-13 21:48 ` Richard Sandiford
0 siblings, 1 reply; 23+ messages in thread
From: Maciej W. Rozycki @ 2005-01-13 18:25 UTC (permalink / raw)
To: Richard Sandiford; +Cc: Atsushi Nemoto, ralf, linux-mips, macro
On Thu, 13 Jan 2005, Richard Sandiford wrote:
> >> Well, maybe the 'volatile' have no sense, but some archs (including
> >> i386, of course :-)) and some drivers use it. Adding the 'volatile'
> >> will remove some compiler warnings.
> >
> > As will removing "volatile" from broken ports.
>
> There's nothing wrong with "volatile void *".
So what's the volatile value you can get by dereferencing such a pointer?
Maciej
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-13 18:25 ` Maciej W. Rozycki
@ 2005-01-13 21:48 ` Richard Sandiford
2005-01-14 1:52 ` Atsushi Nemoto
2005-01-14 19:57 ` Maciej W. Rozycki
0 siblings, 2 replies; 23+ messages in thread
From: Richard Sandiford @ 2005-01-13 21:48 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Atsushi Nemoto, ralf, linux-mips, macro
"Maciej W. Rozycki" <macro@mips.com> writes:
> On Thu, 13 Jan 2005, Richard Sandiford wrote:
>
>> >> Well, maybe the 'volatile' have no sense, but some archs (including
>> >> i386, of course :-)) and some drivers use it. Adding the 'volatile'
>> >> will remove some compiler warnings.
>> >
>> > As will removing "volatile" from broken ports.
>>
>> There's nothing wrong with "volatile void *".
>
> So what's the volatile value you can get by dereferencing such a pointer?
You can't dereference it, obviously, just like you can't deference a
normal "void *". But you can assign it to any "volatile T *" without
an explicit cast. I assumed that's what was happening in this case?
Richard
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-13 21:48 ` Richard Sandiford
@ 2005-01-14 1:52 ` Atsushi Nemoto
2005-01-14 11:05 ` Richard Sandiford
2005-01-14 19:57 ` Maciej W. Rozycki
1 sibling, 1 reply; 23+ messages in thread
From: Atsushi Nemoto @ 2005-01-14 1:52 UTC (permalink / raw)
To: rsandifo; +Cc: macro, ralf, linux-mips, macro
>>>>> On Thu, 13 Jan 2005 21:48:36 +0000, Richard Sandiford <rsandifo@redhat.com> said:
rsandifo> You can't dereference it, obviously, just like you can't
rsandifo> deference a normal "void *". But you can assign it to any
rsandifo> "volatile T *" without an explicit cast. I assumed that's
rsandifo> what was happening in this case?
Assigning "void *" to "volatile T *" is not a problem. Compiler warns
if you assigned "volatile T *" to "void *".
The warnings I mentioned before are:
/usr/src/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h: In function `ahc_inb':
/usr/src/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h:589: warning: passing arg 1 of `readb' discards qualifiers from pointer target type
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-14 1:52 ` Atsushi Nemoto
@ 2005-01-14 11:05 ` Richard Sandiford
0 siblings, 0 replies; 23+ messages in thread
From: Richard Sandiford @ 2005-01-14 11:05 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: macro, ralf, linux-mips, macro
Atsushi Nemoto <anemo@mba.ocn.ne.jp> writes:
> rsandifo> You can't dereference it, obviously, just like you can't
> rsandifo> deference a normal "void *". But you can assign it to any
> rsandifo> "volatile T *" without an explicit cast. I assumed that's
> rsandifo> what was happening in this case?
>
> Assigning "void *" to "volatile T *" is not a problem. Compiler warns
> if you assigned "volatile T *" to "void *".
Ooops! Quite right, and thanks for the correction. (That's what
I meant to write really, honest ;)
Richard
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-13 21:48 ` Richard Sandiford
2005-01-14 1:52 ` Atsushi Nemoto
@ 2005-01-14 19:57 ` Maciej W. Rozycki
1 sibling, 0 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2005-01-14 19:57 UTC (permalink / raw)
To: Richard Sandiford; +Cc: Atsushi Nemoto, ralf, linux-mips, macro
On Thu, 13 Jan 2005, Richard Sandiford wrote:
> You can't dereference it, obviously, just like you can't deference a
> normal "void *". But you can assign it to any "volatile T *" without
> an explicit cast. I assumed that's what was happening in this case?
That's useful, indeed, and I've missed it. Thanks for the tip.
Maciej
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-06 15:45 ` Atsushi Nemoto
2005-01-10 15:28 ` Maciej W. Rozycki
@ 2005-01-21 16:50 ` Atsushi Nemoto
2005-01-22 2:51 ` Maciej W. Rozycki
1 sibling, 1 reply; 23+ messages in thread
From: Atsushi Nemoto @ 2005-01-21 16:50 UTC (permalink / raw)
To: macro; +Cc: rsandifo, ralf, linux-mips, macro
>>>>> On Fri, 07 Jan 2005 00:45:21 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> said:
anemo> Thanks for your good job. I have a few comments/requests.
Revised.
1. How about using 'const void *' for outs*()/reads*() ? This will
remove some compiler warnings too. Also, it seems 'volatile' for
memory buffer are unneeded.
2. In *in*()/*out*(), it would be better to call __swizzle_addr*()
AFTER adding mips_io_port_base. This unifies the meaning of the
argument of __swizzle_addr*() (always virtual address). Then,
mach-specific __swizzle_addr*() can to every evil thing based on
the argument.
3. How about Moving generic ioswab*() to mangle-port.h ? Also how
about passing virtual address to *ioswab*() ? Then we can provide
mach-specific ioswab*() and can do every evil thing based on its
argument. It is usefull on machines which have regions with
different endian conversion scheme.
Here is a patch for CVS HEAD.
diff -urP linux-mips/include/asm-mips/io.h linux/include/asm-mips/io.h
--- linux-mips/include/asm-mips/io.h 2005-01-21 00:58:52.000000000 +0900
+++ linux/include/asm-mips/io.h 2005-01-22 01:34:49.000000000 +0900
@@ -39,46 +39,18 @@
* hardware. An example use would be for flash memory that's used for
* execute in place.
*/
-# define __raw_ioswabb(x) (x)
-# define __raw_ioswabw(x) (x)
-# define __raw_ioswabl(x) (x)
-# define __raw_ioswabq(x) (x)
-
-/*
- * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
- * less sane hardware forces software to fiddle with this...
- */
-#if defined(CONFIG_SWAP_IO_SPACE)
-
-# define ioswabb(x) (x)
-# ifdef CONFIG_SGI_IP22
-/*
- * IP22 seems braindead enough to swap 16bits values in hardware, but
- * not 32bits. Go figure... Can't tell without documentation.
- */
-# define ioswabw(x) (x)
-# else
-# define ioswabw(x) le16_to_cpu(x)
-# endif
-# define ioswabl(x) le32_to_cpu(x)
-# define ioswabq(x) le64_to_cpu(x)
-
-#else
-
-# define ioswabb(x) (x)
-# define ioswabw(x) (x)
-# define ioswabl(x) (x)
-# define ioswabq(x) (x)
-
-#endif
+# define __raw_ioswabb(a,x) (x)
+# define __raw_ioswabw(a,x) (x)
+# define __raw_ioswabl(a,x) (x)
+# define __raw_ioswabq(a,x) (x)
/*
* Native bus accesses never swapped.
*/
-#define bus_ioswabb(x) (x)
-#define bus_ioswabw(x) (x)
-#define bus_ioswabl(x) (x)
-#define bus_ioswabq(x) (x)
+#define bus_ioswabb(a,x) (x)
+#define bus_ioswabw(a,x) (x)
+#define bus_ioswabl(a,x) (x)
+#define bus_ioswabq(a,x) (x)
#define __bus_ioswabq bus_ioswabq
@@ -281,7 +253,7 @@
\
__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
\
- __val = pfx##ioswab##bwlq(val); \
+ __val = pfx##ioswab##bwlq(__mem, val); \
\
if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
*__mem = __val; \
@@ -334,7 +306,7 @@
BUG(); \
} \
\
- return pfx##ioswab##bwlq(__val); \
+ return pfx##ioswab##bwlq(__mem, __val); \
}
#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \
@@ -344,10 +316,10 @@
volatile type *__addr; \
type __val; \
\
- port = __swizzle_addr_##bwlq(port); \
__addr = (void *)(mips_io_port_base + port); \
+ __addr = (void *)__swizzle_addr_##bwlq((unsigned long)__addr); \
\
- __val = pfx##ioswab##bwlq(val); \
+ __val = pfx##ioswab##bwlq(__addr, val); \
\
if (sizeof(type) != sizeof(u64)) { \
*__addr = __val; \
@@ -361,8 +333,8 @@
volatile type *__addr; \
type __val; \
\
- port = __swizzle_addr_##bwlq(port); \
__addr = (void *)(mips_io_port_base + port); \
+ __addr = (void *)__swizzle_addr_##bwlq((unsigned long)__addr); \
\
if (sizeof(type) != sizeof(u64)) { \
__val = *__addr; \
@@ -372,7 +344,7 @@
BUILD_BUG(); \
} \
\
- return pfx##ioswab##bwlq(__val); \
+ return pfx##ioswab##bwlq(__addr, __val); \
}
#define __BUILD_MEMORY_PFX(bus, bwlq, type) \
@@ -416,10 +388,10 @@
#define __BUILD_MEMORY_STRING(bwlq, type) \
\
-static inline void writes##bwlq(volatile void __iomem *mem, void *addr, \
+static inline void writes##bwlq(volatile void __iomem *mem, const void *addr, \
unsigned int count) \
{ \
- volatile type *__addr = addr; \
+ const type *__addr = addr; \
\
while (count--) { \
__raw_write##bwlq(*__addr, mem); \
@@ -430,7 +402,7 @@
static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \
unsigned int count) \
{ \
- volatile type *__addr = addr; \
+ type *__addr = addr; \
\
while (count--) { \
*__addr = __raw_read##bwlq(mem); \
@@ -440,10 +412,10 @@
#define __BUILD_IOPORT_STRING(bwlq, type) \
\
-static inline void outs##bwlq(unsigned long port, void *addr, \
+static inline void outs##bwlq(unsigned long port, const void *addr, \
unsigned int count) \
{ \
- volatile type *__addr = addr; \
+ const type *__addr = addr; \
\
while (count--) { \
__raw_out##bwlq(*__addr, port); \
@@ -454,7 +426,7 @@
static inline void ins##bwlq(unsigned long port, void *addr, \
unsigned int count) \
{ \
- volatile type *__addr = addr; \
+ type *__addr = addr; \
\
while (count--) { \
*__addr = __raw_in##bwlq(port); \
diff -urP linux-mips/include/asm-mips/mach-generic/mangle-port.h linux/include/asm-mips/mach-generic/mangle-port.h
--- linux-mips/include/asm-mips/mach-generic/mangle-port.h 2004-08-21 00:34:13.000000000 +0900
+++ linux/include/asm-mips/mach-generic/mangle-port.h 2005-01-22 01:35:03.000000000 +0900
@@ -13,4 +13,24 @@
#define __swizzle_addr_l(port) (port)
#define __swizzle_addr_q(port) (port)
+/*
+ * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
+ * less sane hardware forces software to fiddle with this...
+ */
+#if defined(CONFIG_SWAP_IO_SPACE)
+
+# define ioswabb(a,x) (x)
+# define ioswabw(a,x) le16_to_cpu(x)
+# define ioswabl(a,x) le32_to_cpu(x)
+# define ioswabq(a,x) le64_to_cpu(x)
+
+#else
+
+# define ioswabb(a,x) (x)
+# define ioswabw(a,x) (x)
+# define ioswabl(a,x) (x)
+# define ioswabq(a,x) (x)
+
+#endif
+
#endif /* __ASM_MACH_GENERIC_MANGLE_PORT_H */
diff -urP linux-mips/include/asm-mips/mach-ip22/mangle-port.h linux/include/asm-mips/mach-ip22/mangle-port.h
--- linux-mips/include/asm-mips/mach-ip22/mangle-port.h 1970-01-01 09:00:00.000000000 +0900
+++ linux/include/asm-mips/mach-ip22/mangle-port.h 2005-01-22 01:40:59.000000000 +0900
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ */
+#ifndef __ASM_MACH_IP22_MANGLE_PORT_H
+#define __ASM_MACH_IP22_MANGLE_PORT_H
+
+#define __swizzle_addr_b(port) (port)
+#define __swizzle_addr_w(port) (port)
+#define __swizzle_addr_l(port) (port)
+#define __swizzle_addr_q(port) (port)
+
+/*
+ * IP22 seems braindead enough to swap 16bits values in hardware, but
+ * not 32bits. Go figure... Can't tell without documentation.
+ */
+#define ioswabb(a,x) (x)
+#define ioswabw(a,x) (x)
+#define ioswabl(a,x) le32_to_cpu(x)
+#define ioswabq(a,x) le64_to_cpu(x)
+
+#endif /* __ASM_MACH_IP22_MANGLE_PORT_H */
diff -urP linux-mips/include/asm-mips/mach-ip27/mangle-port.h linux/include/asm-mips/mach-ip27/mangle-port.h
--- linux-mips/include/asm-mips/mach-ip27/mangle-port.h 2004-08-21 00:34:13.000000000 +0900
+++ linux/include/asm-mips/mach-ip27/mangle-port.h 2005-01-22 01:35:17.000000000 +0900
@@ -13,4 +13,9 @@
#define __swizzle_addr_l(port) (port)
#define __swizzle_addr_q(port) (port)
+#define ioswabb(a,x) (x)
+#define ioswabw(a,x) (x)
+#define ioswabl(a,x) (x)
+#define ioswabq(a,x) (x)
+
#endif /* __ASM_MACH_IP27_MANGLE_PORT_H */
diff -urP linux-mips/include/asm-mips/mach-ip32/mangle-port.h linux/include/asm-mips/mach-ip32/mangle-port.h
--- linux-mips/include/asm-mips/mach-ip32/mangle-port.h 2004-10-27 23:30:28.000000000 +0900
+++ linux/include/asm-mips/mach-ip32/mangle-port.h 2005-01-22 01:35:23.000000000 +0900
@@ -14,4 +14,9 @@
#define __swizzle_addr_l(port) (port)
#define __swizzle_addr_q(port) (port)
+#define ioswabb(a,x) (x)
+#define ioswabw(a,x) (x)
+#define ioswabl(a,x) (x)
+#define ioswabq(a,x) (x)
+
#endif /* __ASM_MACH_IP32_MANGLE_PORT_H */
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH] I/O helpers rework
2005-01-21 16:50 ` Atsushi Nemoto
@ 2005-01-22 2:51 ` Maciej W. Rozycki
2005-01-25 1:09 ` Atsushi Nemoto
2005-02-17 1:34 ` Ralf Baechle
0 siblings, 2 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2005-01-22 2:51 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: macro, Richard Sandiford, Ralf Baechle, linux-mips
On Sat, 22 Jan 2005, Atsushi Nemoto wrote:
> Revised.
>
> 1. How about using 'const void *' for outs*()/reads*() ? This will
> remove some compiler warnings too. Also, it seems 'volatile' for
> memory buffer are unneeded.
>
> 2. In *in*()/*out*(), it would be better to call __swizzle_addr*()
> AFTER adding mips_io_port_base. This unifies the meaning of the
> argument of __swizzle_addr*() (always virtual address). Then,
> mach-specific __swizzle_addr*() can to every evil thing based on
> the argument.
>
> 3. How about Moving generic ioswab*() to mangle-port.h ? Also how
> about passing virtual address to *ioswab*() ? Then we can provide
> mach-specific ioswab*() and can do every evil thing based on its
> argument. It is usefull on machines which have regions with
> different endian conversion scheme.
Thanks for your insight -- your comments are not lost and I am working on
taking them into account. But meanwhile a confusion around the semantics
of these operations arose (there is no documentation on them and some
drivers expect some of these functions to swap, while others expect them
not to) and changes were made to the tree that invalidated some of the
fixes. That needs to be addressed first and I expect another update to
the file. Here's a patch I'm going to start with. Functions it adds have
been named dma_* to indicate they are meant to preserve memory byte
ordering.
Maciej
patch-mips-2.6.11-rc1-20050120-mips-io-0
--- linux-mips-2.6.11-rc1-20050120.macro/include/asm-mips/io.h 19 Jan 2005 17:00:32 -0000 1.81
+++ linux-mips-2.6.11-rc1-20050120/include/asm-mips/io.h 20 Jan 2005 01:44:07 -0000
@@ -34,7 +34,7 @@
#undef CONF_SLOWDOWN_IO
/*
- * Raw operations are never swapped in software. Otoh values that raw
+ * Raw operations are never swapped in software. OTOH values that raw
* operations are working on may or may not have been swapped by the bus
* hardware. An example use would be for flash memory that's used for
* execute in place.
@@ -43,6 +43,7 @@
# define __raw_ioswabw(x) (x)
# define __raw_ioswabl(x) (x)
# define __raw_ioswabq(x) (x)
+# define ____raw_ioswabq(x) (x)
/*
* Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
@@ -51,37 +52,36 @@
#if defined(CONFIG_SWAP_IO_SPACE)
# define ioswabb(x) (x)
+# define dma_ioswabb(x) (x)
# ifdef CONFIG_SGI_IP22
/*
* IP22 seems braindead enough to swap 16bits values in hardware, but
* not 32bits. Go figure... Can't tell without documentation.
*/
# define ioswabw(x) (x)
+# define dma_ioswabw(x) le16_to_cpu(x)
# else
# define ioswabw(x) le16_to_cpu(x)
+# define dma_ioswabw(x) (x)
# endif
# define ioswabl(x) le32_to_cpu(x)
+# define dma_ioswabl(x) (x)
# define ioswabq(x) le64_to_cpu(x)
+# define dma_ioswabq(x) (x)
#else
# define ioswabb(x) (x)
+# define dma_ioswabb(x) (x)
# define ioswabw(x) (x)
+# define dma_ioswabw(x) cpu_to_le16(x)
# define ioswabl(x) (x)
+# define dma_ioswabl(x) cpu_to_le32(x)
# define ioswabq(x) (x)
+# define dma_ioswabq(x) cpu_to_le32(x)
#endif
-/*
- * Native bus accesses never swapped.
- */
-#define bus_ioswabb(x) (x)
-#define bus_ioswabw(x) (x)
-#define bus_ioswabl(x) (x)
-#define bus_ioswabq(x) (x)
-
-#define __bus_ioswabq bus_ioswabq
-
#define IO_SPACE_LIMIT 0xffff
/*
@@ -386,15 +386,15 @@ __BUILD_IOPORT_SINGLE(bus, bwlq, type, _
#define BUILDIO(bwlq, type) \
\
-__BUILD_MEMORY_PFX(, bwlq, type) \
__BUILD_MEMORY_PFX(__raw_, bwlq, type) \
-__BUILD_MEMORY_PFX(bus_, bwlq, type) \
+__BUILD_MEMORY_PFX(, bwlq, type) \
+__BUILD_MEMORY_PFX(dma_, bwlq, type) \
__BUILD_IOPORT_PFX(, bwlq, type) \
-__BUILD_IOPORT_PFX(__raw_, bwlq, type)
+__BUILD_IOPORT_PFX(dma_, bwlq, type)
#define __BUILDIO(bwlq, type) \
\
-__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0)
+__BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 0)
BUILDIO(b, u8)
BUILDIO(w, u16)
@@ -422,7 +422,7 @@ static inline void writes##bwlq(volatile
volatile type *__addr = addr; \
\
while (count--) { \
- __raw_write##bwlq(*__addr, mem); \
+ dma_write##bwlq(*__addr, mem); \
__addr++; \
} \
} \
@@ -433,7 +433,7 @@ static inline void reads##bwlq(volatile
volatile type *__addr = addr; \
\
while (count--) { \
- *__addr = __raw_read##bwlq(mem); \
+ *__addr = dma_read##bwlq(mem); \
__addr++; \
} \
}
@@ -446,7 +446,7 @@ static inline void outs##bwlq(unsigned l
volatile type *__addr = addr; \
\
while (count--) { \
- __raw_out##bwlq(*__addr, port); \
+ dma_out##bwlq(*__addr, port); \
__addr++; \
} \
} \
@@ -457,7 +457,7 @@ static inline void ins##bwlq(unsigned lo
volatile type *__addr = addr; \
\
while (count--) { \
- *__addr = __raw_in##bwlq(port); \
+ *__addr = dma_in##bwlq(port); \
__addr++; \
} \
}
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH] I/O helpers rework
2005-01-22 2:51 ` Maciej W. Rozycki
@ 2005-01-25 1:09 ` Atsushi Nemoto
2005-02-17 1:34 ` Ralf Baechle
1 sibling, 0 replies; 23+ messages in thread
From: Atsushi Nemoto @ 2005-01-25 1:09 UTC (permalink / raw)
To: macro; +Cc: macro, rsandifo, ralf, linux-mips
>>>>> On Sat, 22 Jan 2005 02:51:47 +0000 (GMT), "Maciej W. Rozycki" <macro@linux-mips.org> said:
macro> That needs to be addressed first and I expect another update to
macro> the file. Here's a patch I'm going to start with. Functions
macro> it adds have been named dma_* to indicate they are meant to
macro> preserve memory byte ordering.
Thank you. The new patch seems good for me. It fixes io-string
operations for no SWAP_IO_SPACE system again.
And, of course, I hope the new dma_ioswab*() will also be customizable
by mangle-port.h :-)
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-22 2:51 ` Maciej W. Rozycki
2005-01-25 1:09 ` Atsushi Nemoto
@ 2005-02-17 1:34 ` Ralf Baechle
2005-02-18 19:44 ` Maciej W. Rozycki
1 sibling, 1 reply; 23+ messages in thread
From: Ralf Baechle @ 2005-02-17 1:34 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Atsushi Nemoto, macro, Richard Sandiford, linux-mips
On Sat, Jan 22, 2005 at 02:51:47AM +0000, Maciej W. Rozycki wrote:
> > 1. How about using 'const void *' for outs*()/reads*() ? This will
> > remove some compiler warnings too. Also, it seems 'volatile' for
> > memory buffer are unneeded.
> >
> > 2. In *in*()/*out*(), it would be better to call __swizzle_addr*()
> > AFTER adding mips_io_port_base. This unifies the meaning of the
> > argument of __swizzle_addr*() (always virtual address). Then,
> > mach-specific __swizzle_addr*() can to every evil thing based on
> > the argument.
> >
> > 3. How about Moving generic ioswab*() to mangle-port.h ? Also how
> > about passing virtual address to *ioswab*() ? Then we can provide
> > mach-specific ioswab*() and can do every evil thing based on its
> > argument. It is usefull on machines which have regions with
> > different endian conversion scheme.
>
> Thanks for your insight -- your comments are not lost and I am working on
> taking them into account. But meanwhile a confusion around the semantics
> of these operations arose (there is no documentation on them and some
> drivers expect some of these functions to swap, while others expect them
> not to) and changes were made to the tree that invalidated some of the
> fixes. That needs to be addressed first and I expect another update to
> the file. Here's a patch I'm going to start with. Functions it adds have
> been named dma_* to indicate they are meant to preserve memory byte
> ordering.
Looks good but I don't really like the dma_* name prefix as these functions
really have nothing to do with DMA - in fact they're the opposite.
Ralf
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-02-17 1:34 ` Ralf Baechle
@ 2005-02-18 19:44 ` Maciej W. Rozycki
0 siblings, 0 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2005-02-18 19:44 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Atsushi Nemoto, macro, Richard Sandiford, linux-mips
On Thu, 17 Feb 2005, Ralf Baechle wrote:
> > Thanks for your insight -- your comments are not lost and I am working on
> > taking them into account. But meanwhile a confusion around the semantics
> > of these operations arose (there is no documentation on them and some
> > drivers expect some of these functions to swap, while others expect them
> > not to) and changes were made to the tree that invalidated some of the
> > fixes. That needs to be addressed first and I expect another update to
> > the file. Here's a patch I'm going to start with. Functions it adds have
> > been named dma_* to indicate they are meant to preserve memory byte
> > ordering.
>
> Looks good but I don't really like the dma_* name prefix as these functions
> really have nothing to do with DMA - in fact they're the opposite.
Well, the name is meant to imply DMA byte ordering is preserved. If
that's not clear enough (I don't insist it is), then I'd love to hear a
reasonable proposal for an alternative.
Maciej
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2004-12-15 21:13 [PATCH] I/O helpers rework Maciej W. Rozycki
2005-01-06 15:45 ` Atsushi Nemoto
@ 2005-01-06 16:33 ` Herbert Valerio Riedel
2005-01-10 13:05 ` Maciej W. Rozycki
2005-01-13 22:18 ` Manish Lachwani
2 siblings, 1 reply; 23+ messages in thread
From: Herbert Valerio Riedel @ 2005-01-06 16:33 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Ralf Baechle, linux-mips, Maciej W. Rozycki
On Wed, 2004-12-15 at 21:13 +0000, Maciej W. Rozycki wrote:
[..]
> The changes have been verified with a Malta board for port I/O and with a
> SWARM one for memory-mapped I/O (with an updated driver; to be sent
> separately). Broadcom SiByte systems are the only ones utilizing current
> __raw_*() and ____raw_*() calls. I have a patch to convert them to
> bus_*() and __bus_*() ones as appropriate ready as well.
>
> OK to apply?
jfyi, this change broke mtd and au1xxx-usb on big endian au1xxx systems,
as the _raw calls do suddenly byteswapping :-(
was this intended?
regards,
--
Herbert Valerio Riedel <hvr@inso.tuwien.ac.at>
Research Group for Industrial Software @ Vienna University of Technology
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-06 16:33 ` Herbert Valerio Riedel
@ 2005-01-10 13:05 ` Maciej W. Rozycki
2005-01-10 14:46 ` Herbert Valerio Riedel
0 siblings, 1 reply; 23+ messages in thread
From: Maciej W. Rozycki @ 2005-01-10 13:05 UTC (permalink / raw)
To: Herbert Valerio Riedel; +Cc: Ralf Baechle, linux-mips, Maciej W. Rozycki
On Thu, 6 Jan 2005, Herbert Valerio Riedel wrote:
> jfyi, this change broke mtd and au1xxx-usb on big endian au1xxx systems,
> as the _raw calls do suddenly byteswapping :-(
>
> was this intended?
It was. Generic code elsewhere expects it and the MIPS implementation
used to be broken because of that. Note these functions are intended for
PCI/EISA/ISA accesses only and these buses are little-endian by
definition. More specifically __raw_ calls are mainly for PIO copying
to/from memory over these buses when you want to keep byte ordering the
same as it would be for a DMA transfer.
If you have a driver that handles a non-PCI/EISA/ISA device you may and
probably should use bus_ calls to get a non-swapped access.
Maciej
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2005-01-10 13:05 ` Maciej W. Rozycki
@ 2005-01-10 14:46 ` Herbert Valerio Riedel
2005-01-10 14:49 ` Herbert Valerio Riedel
0 siblings, 1 reply; 23+ messages in thread
From: Herbert Valerio Riedel @ 2005-01-10 14:46 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Ralf Baechle, linux-mips, Maciej W. Rozycki
On Mon, 2005-01-10 at 13:05 +0000, Maciej W. Rozycki wrote:
> On Thu, 6 Jan 2005, Herbert Valerio Riedel wrote:
>
> > jfyi, this change broke mtd and au1xxx-usb on big endian au1xxx systems,
> > as the _raw calls do suddenly byteswapping :-(
> >
> > was this intended?
>
> It was. Generic code elsewhere expects it and the MIPS implementation
> used to be broken because of that. Note these functions are intended for
> PCI/EISA/ISA accesses only and these buses are little-endian by
> definition. More specifically __raw_ calls are mainly for PIO copying
> to/from memory over these buses when you want to keep byte ordering the
> same as it would be for a DMA transfer.
> If you have a driver that handles a non-PCI/EISA/ISA device you may and
> probably should use bus_ calls to get a non-swapped access.
so this means, the mtd subsystem should use them and that the patch
below is the way to fix it? (hoping it won't brake on other systems?)
Index: map.h
===================================================================
RCS file: /home/cvs/linux/include/linux/mtd/map.h,v
retrieving revision 1.12
diff -u -r1.12 map.h
--- map.h 25 Oct 2004 20:44:46 -0000 1.12
+++ map.h 10 Jan 2005 14:45:00 -0000
@@ -343,14 +343,14 @@
map_word r;
if (map_bankwidth_is_1(map))
- r.x[0] = __raw_readb(map->virt + ofs);
+ r.x[0] = readb(map->virt + ofs);
else if (map_bankwidth_is_2(map))
- r.x[0] = __raw_readw(map->virt + ofs);
+ r.x[0] = readw(map->virt + ofs);
else if (map_bankwidth_is_4(map))
- r.x[0] = __raw_readl(map->virt + ofs);
+ r.x[0] = readl(map->virt + ofs);
#if BITS_PER_LONG >= 64
else if (map_bankwidth_is_8(map))
- r.x[0] = __raw_readq(map->virt + ofs);
+ r.x[0] = readq(map->virt + ofs);
#endif
else if (map_bankwidth_is_large(map))
memcpy_fromio(r.x, map->virt+ofs, map->bankwidth);
@@ -361,14 +361,14 @@
static inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
{
if (map_bankwidth_is_1(map))
- __raw_writeb(datum.x[0], map->virt + ofs);
+ writeb(datum.x[0], map->virt + ofs);
else if (map_bankwidth_is_2(map))
- __raw_writew(datum.x[0], map->virt + ofs);
+ writew(datum.x[0], map->virt + ofs);
else if (map_bankwidth_is_4(map))
- __raw_writel(datum.x[0], map->virt + ofs);
+ writel(datum.x[0], map->virt + ofs);
#if BITS_PER_LONG >= 64
else if (map_bankwidth_is_8(map))
- __raw_writeq(datum.x[0], map->virt + ofs);
+ writeq(datum.x[0], map->virt + ofs);
#endif
else if (map_bankwidth_is_large(map))
memcpy_toio(map->virt+ofs, datum.x, map->bankwidth);
--
Herbert Valerio Riedel <hvr@inso.tuwien.ac.at>
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH] I/O helpers rework
2005-01-10 14:46 ` Herbert Valerio Riedel
@ 2005-01-10 14:49 ` Herbert Valerio Riedel
2005-01-14 20:07 ` Maciej W. Rozycki
0 siblings, 1 reply; 23+ messages in thread
From: Herbert Valerio Riedel @ 2005-01-10 14:49 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Ralf Baechle, linux-mips, Maciej W. Rozycki
On Mon, 2005-01-10 at 15:46 +0100, Herbert Valerio Riedel wrote:
> so this means, the mtd subsystem should use them and that the patch
> below is the way to fix it? (hoping it won't brake on other systems?)
sorry, wrong patch... the patch below should have s/__raw_/bus_/g
instead of s/__raw_//g;
anyway, are the bus_# memory accessors defined for all archs at all?
>
> Index: map.h
> ===================================================================
> RCS file: /home/cvs/linux/include/linux/mtd/map.h,v
> retrieving revision 1.12
> diff -u -r1.12 map.h
> --- map.h 25 Oct 2004 20:44:46 -0000 1.12
> +++ map.h 10 Jan 2005 14:45:00 -0000
> @@ -343,14 +343,14 @@
> map_word r;
>
> if (map_bankwidth_is_1(map))
> - r.x[0] = __raw_readb(map->virt + ofs);
> + r.x[0] = readb(map->virt + ofs);
> else if (map_bankwidth_is_2(map))
> - r.x[0] = __raw_readw(map->virt + ofs);
> + r.x[0] = readw(map->virt + ofs);
> else if (map_bankwidth_is_4(map))
> - r.x[0] = __raw_readl(map->virt + ofs);
> + r.x[0] = readl(map->virt + ofs);
> #if BITS_PER_LONG >= 64
> else if (map_bankwidth_is_8(map))
> - r.x[0] = __raw_readq(map->virt + ofs);
> + r.x[0] = readq(map->virt + ofs);
> #endif
> else if (map_bankwidth_is_large(map))
> memcpy_fromio(r.x, map->virt+ofs, map->bankwidth);
> @@ -361,14 +361,14 @@
> static inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
> {
> if (map_bankwidth_is_1(map))
> - __raw_writeb(datum.x[0], map->virt + ofs);
> + writeb(datum.x[0], map->virt + ofs);
> else if (map_bankwidth_is_2(map))
> - __raw_writew(datum.x[0], map->virt + ofs);
> + writew(datum.x[0], map->virt + ofs);
> else if (map_bankwidth_is_4(map))
> - __raw_writel(datum.x[0], map->virt + ofs);
> + writel(datum.x[0], map->virt + ofs);
> #if BITS_PER_LONG >= 64
> else if (map_bankwidth_is_8(map))
> - __raw_writeq(datum.x[0], map->virt + ofs);
> + writeq(datum.x[0], map->virt + ofs);
> #endif
> else if (map_bankwidth_is_large(map))
> memcpy_toio(map->virt+ofs, datum.x, map->bankwidth);
>
>
--
Herbert Valerio Riedel <hvr@inso.tuwien.ac.at>
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH] I/O helpers rework
2005-01-10 14:49 ` Herbert Valerio Riedel
@ 2005-01-14 20:07 ` Maciej W. Rozycki
0 siblings, 0 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2005-01-14 20:07 UTC (permalink / raw)
To: Herbert Valerio Riedel; +Cc: Ralf Baechle, linux-mips, Maciej W. Rozycki
On Mon, 10 Jan 2005, Herbert Valerio Riedel wrote:
> On Mon, 2005-01-10 at 15:46 +0100, Herbert Valerio Riedel wrote:
> > so this means, the mtd subsystem should use them and that the patch
> > below is the way to fix it? (hoping it won't brake on other systems?)
>
> sorry, wrong patch... the patch below should have s/__raw_/bus_/g
> instead of s/__raw_//g;
Probably, although <linux/mtd/map.h> seems device-independent and that
may mean you might want to take the endianness of the bus an MTD is
connected to, to preserve data consistency when moving the MTD between
systems of different endiannesses (it may be non-volatile memory of some
sort).
> anyway, are the bus_# memory accessors defined for all archs at all?
Not at all, I'm afraid, and fixing that might be a good idea.
Unfortunately most platforms use a single endianness only and therefore
have a biased view on these accessory functions. Especially little-endian
folks may have troubles understanding what's this all about.
Maciej
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] I/O helpers rework
2004-12-15 21:13 [PATCH] I/O helpers rework Maciej W. Rozycki
2005-01-06 15:45 ` Atsushi Nemoto
2005-01-06 16:33 ` Herbert Valerio Riedel
@ 2005-01-13 22:18 ` Manish Lachwani
2 siblings, 0 replies; 23+ messages in thread
From: Manish Lachwani @ 2005-01-13 22:18 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Ralf Baechle, linux-mips, Maciej W. Rozycki
Hello Maciej,
Couple of things:
1. Have you tried this patch on 32-bit SMP Sibyte with
CONFIG_SIBYTE_DMA_PAGEOPS turned on. I tried it out with 2.6.11-rc1 and
the kernel crashes on bootup when doing a clear_page. The following code
in arch/mips/mm/pg-sb1.c:
while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu,
R_DM_DSCR_BASE_DEBUG)) &
M_DM_DSCR_BASE_INTERRUPT))))
in clear_page seems to be causing a problem. I need to investigate more
2. Secondly, the Sibyte MAC driver drivers/net/sb1250-mac.c still uses
__raw_readq and __raw_writeq calls. Those will also need to be converted
to bus_* calls
Thanks
Manish Lachwani
Maciej W. Rozycki wrote:
>Hello,
>
> While trying using an IDE interface driver with big-endian systems, I've
>noticed some of our port/mm I/O accessory functions/macros get endianness
>incorrectly. In particular a lot of drivers expect single I/O accesses to
>return correct numerical value of data as seen by the CPU while string I/O
>accesses to preserve byte ordering in memory.
>
> As the whole file seemed a bit messy to me I decided to rewrite these
>functions/macros completely. To ease long-term maintenance I created
>common templates for all classes of accesses which expand to appropriate
>code for different transfer unit width. I made all operations to be
>expressed as inline functions to catch dangerous/incorrect uses. The
>result are the following function classes:
>
>1. in*()/out*()/read*()/write*() perform single operations on data using
> little-endian ordering.
>
>2. __raw_in*()/__raw_out*()/__raw_read*()/__raw_write*() perform single
> operations on data using memory ordering.
>
>3. bus_read*()/bus_write*() perform single on data using CPU bus ordering
> (that is as it appears at the bus, regardless of any address or lane
> swappers that may modify it on the way between the CPU and a device).
>
>4. __bus_readq()/__bus_writeq() are hacks for 64-bit accesses avoiding
> interrupt masking when used with a 32-bit kernel and are otherwise the
> same as bus_readq()/bus_writeq().
>
>5. ins*()/outs*()/reads*()/writes*() perform string operations on data
> using memory ordering yielding the same result as a corresponding DMA
> transfer would.
>
>The naming of 1., 2. and perhaps 5. above is a bit unfortunate, but that's
>what much code elsewhere expects. These variants assume a ISA/EISA/PCI
>bus, little-endian. They perform minimum of swapping required -- they
>avoid swapping data back and forth to keep good performance. For
>buses/devices that follow CPU endianness use 3. or perhaps 4. if
>interrupts have already been masked.
>
> The changes have been verified with a Malta board for port I/O and with a
>SWARM one for memory-mapped I/O (with an updated driver; to be sent
>separately). Broadcom SiByte systems are the only ones utilizing current
>__raw_*() and ____raw_*() calls. I have a patch to convert them to
>bus_*() and __bus_*() ones as appropriate ready as well.
>
> OK to apply?
>
> Maciej
>
>patch-mips-2.6.10-rc2-20041124-mips-ide-27
>diff -up --recursive --new-file linux-mips-2.6.10-rc2-20041124.macro/include/asm-mips/io.h linux-mips-2.6.10-rc2-20041124/include/asm-mips/io.h
>--- linux-mips-2.6.10-rc2-20041124.macro/include/asm-mips/io.h 2004-11-22 14:27:59.000000000 +0000
>+++ linux-mips-2.6.10-rc2-20041124/include/asm-mips/io.h 2004-12-13 13:05:29.000000000 +0000
>@@ -6,21 +6,26 @@
> * Copyright (C) 1994, 1995 Waldorf GmbH
> * Copyright (C) 1994 - 2000 Ralf Baechle
> * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
>+ * Copyright (C) 2004 MIPS Technologies, Inc. All rights reserved.
>+ * Author: Maciej W. Rozycki <macro@mips.com>
> */
> #ifndef _ASM_IO_H
> #define _ASM_IO_H
>
> #include <linux/config.h>
> #include <linux/compiler.h>
>+#include <linux/kernel.h>
> #include <linux/types.h>
>
> #include <asm/addrspace.h>
>+#include <asm/bug.h>
>+#include <asm/byteorder.h>
> #include <asm/cpu.h>
> #include <asm/cpu-features.h>
> #include <asm/page.h>
> #include <asm/pgtable-bits.h>
> #include <asm/processor.h>
>-#include <asm/byteorder.h>
>+
> #include <mangle-port.h>
>
> /*
>@@ -29,34 +34,52 @@
> #undef CONF_SLOWDOWN_IO
>
> /*
>- * Sane hardware offers swapping of I/O space accesses in hardware; less
>- * sane hardware forces software to fiddle with this ...
>+ * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
>+ * less sane hardware forces software to fiddle with this...
> */
>-#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
>+#if defined(CONFIG_SWAP_IO_SPACE)
>
>-#define __ioswab8(x) (x)
>-
>-#ifdef CONFIG_SGI_IP22
>+# define ioswabb(x) (x)
>+# define __raw_ioswabb(x) (x)
>+# ifdef CONFIG_SGI_IP22
> /*
> * IP22 seems braindead enough to swap 16bits values in hardware, but
> * not 32bits. Go figure... Can't tell without documentation.
> */
>-#define __ioswab16(x) (x)
>-#else
>-#define __ioswab16(x) swab16(x)
>-#endif
>-#define __ioswab32(x) swab32(x)
>-#define __ioswab64(x) swab64(x)
>+# define ioswabw(x) (x)
>+# define __raw_ioswabw(x) le16_to_cpu(x)
>+# else
>+# define ioswabw(x) le16_to_cpu(x)
>+# define __raw_ioswabw(x) (x)
>+# endif
>+# define ioswabl(x) le32_to_cpu(x)
>+# define __raw_ioswabl(x) (x)
>+# define ioswabq(x) le64_to_cpu(x)
>+# define __raw_ioswabq(x) (x)
>
> #else
>
>-#define __ioswab8(x) (x)
>-#define __ioswab16(x) (x)
>-#define __ioswab32(x) (x)
>-#define __ioswab64(x) (x)
>+# define ioswabb(x) (x)
>+# define __raw_ioswabb(x) (x)
>+# define ioswabw(x) (x)
>+# define __raw_ioswabw(x) cpu_to_le16(x)
>+# define ioswabl(x) (x)
>+# define __raw_ioswabl(x) cpu_to_le32(x)
>+# define ioswabq(x) (x)
>+# define __raw_ioswabq(x) cpu_to_le64(x)
>
> #endif
>
>+/*
>+ * Native bus accesses never swapped.
>+ */
>+#define bus_ioswabb(x) (x)
>+#define bus_ioswabw(x) (x)
>+#define bus_ioswabl(x) (x)
>+#define bus_ioswabq(x) (x)
>+
>+#define __bus_ioswabq bus_ioswabq
>+
> #define IO_SPACE_LIMIT 0xffff
>
> /*
>@@ -245,108 +268,202 @@ static inline void iounmap(volatile void
> __iounmap(addr);
> }
>
>-#define __raw_readb(addr) \
>- (*(volatile unsigned char *) __swizzle_addr_b((unsigned long)(addr)))
>-#define __raw_readw(addr) \
>- (*(volatile unsigned short *) __swizzle_addr_w((unsigned long)(addr)))
>-#define __raw_readl(addr) \
>- (*(volatile unsigned int *) __swizzle_addr_l((unsigned long)(addr)))
>-#ifdef CONFIG_MIPS32
>-#define ____raw_readq(addr) \
>-({ \
>- u64 __res; \
>- \
>- __asm__ __volatile__ ( \
>- " .set mips3 # ____raw_readq \n" \
>- " ld %L0, (%1) \n" \
>- " dsra32 %M0, %L0, 0 \n" \
>- " sll %L0, %L0, 0 \n" \
>- " .set mips0 \n" \
>- : "=r" (__res) \
>- : "r" (__swizzle_addr_q((unsigned long)(addr)))); \
>- __res; \
>-})
>-#define __raw_readq(addr) \
>-({ \
>- unsigned long __flags; \
>- u64 __res; \
>- \
>- local_irq_save(__flags); \
>- __res = ____raw_readq(addr); \
>- local_irq_restore(__flags); \
>- __res; \
>-})
>-#endif
>-#ifdef CONFIG_MIPS64
>-#define ____raw_readq(addr) \
>- (*(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)))
>-#define __raw_readq(addr) ____raw_readq(addr)
>-#endif
>
>-#define readb(addr) __ioswab8(__raw_readb(addr))
>-#define readw(addr) __ioswab16(__raw_readw(addr))
>-#define readl(addr) __ioswab32(__raw_readl(addr))
>-#define readq(addr) __ioswab64(__raw_readq(addr))
>-#define readb_relaxed(addr) readb(addr)
>-#define readw_relaxed(addr) readw(addr)
>-#define readl_relaxed(addr) readl(addr)
>-#define readq_relaxed(addr) readq(addr)
>-
>-#define __raw_writeb(b,addr) \
>-do { \
>- ((*(volatile unsigned char *)__swizzle_addr_b((unsigned long)(addr))) = (b)); \
>-} while (0)
>-
>-#define __raw_writew(w,addr) \
>-do { \
>- ((*(volatile unsigned short *)__swizzle_addr_w((unsigned long)(addr))) = (w)); \
>-} while (0)
>-
>-#define __raw_writel(l,addr) \
>-do { \
>- ((*(volatile unsigned int *)__swizzle_addr_l((unsigned long)(addr))) = (l)); \
>-} while (0)
>-
>-#ifdef CONFIG_MIPS32
>-#define ____raw_writeq(val,addr) \
>-do { \
>- u64 __tmp; \
>- \
>- __asm__ __volatile__ ( \
>- " .set mips3 \n" \
>- " dsll32 %L0, %L0, 0 # ____raw_writeq\n" \
>- " dsrl32 %L0, %L0, 0 \n" \
>- " dsll32 %M0, %M0, 0 \n" \
>- " or %L0, %L0, %M0 \n" \
>- " sd %L0, (%2) \n" \
>- " .set mips0 \n" \
>- : "=r" (__tmp) \
>- : "0" ((unsigned long long)val), \
>- "r" (__swizzle_addr_q((unsigned long)(addr)))); \
>-} while (0)
>-
>-#define __raw_writeq(val,addr) \
>-do { \
>- unsigned long __flags; \
>- \
>- local_irq_save(__flags); \
>- ____raw_writeq(val, addr); \
>- local_irq_restore(__flags); \
>-} while (0)
>-#endif
>-#ifdef CONFIG_MIPS64
>-#define ____raw_writeq(q,addr) \
>-do { \
>- *(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)) = (q); \
>-} while (0)
>+#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
>+ \
>+static inline void pfx##write##bwlq(type val, void *mem) \
>+{ \
>+ volatile type *__mem; \
>+ type __val; \
>+ \
>+ __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
>+ \
>+ __val = pfx##ioswab##bwlq(val); \
>+ \
>+ if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
>+ *__mem = __val; \
>+ else if (cpu_has_64bits) { \
>+ unsigned long __flags; \
>+ type __tmp; \
>+ \
>+ if (irq) \
>+ local_irq_save(__flags); \
>+ __asm__ __volatile__( \
>+ ".set mips3" "\t\t# __writeq""\n\t" \
>+ "dsll32 %L0, %L0, 0" "\n\t" \
>+ "dsrl32 %L0, %L0, 0" "\n\t" \
>+ "dsll32 %M0, %M0, 0" "\n\t" \
>+ "or %L0, %L0, %M0" "\n\t" \
>+ "sd %L0, %2" "\n\t" \
>+ ".set mips0" "\n" \
>+ : "=r" (__tmp) \
>+ : "0" (__val), "m" (*__mem)); \
>+ if (irq) \
>+ local_irq_restore(__flags); \
>+ } else \
>+ BUG(); \
>+} \
>+ \
>+static inline type pfx##read##bwlq(void *mem) \
>+{ \
>+ volatile type *__mem; \
>+ type __val; \
>+ \
>+ __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
>+ \
>+ if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
>+ __val = *__mem; \
>+ else if (cpu_has_64bits) { \
>+ unsigned long __flags; \
>+ \
>+ local_irq_save(__flags); \
>+ __asm__ __volatile__( \
>+ ".set mips3" "\t\t# __readq" "\n\t" \
>+ "ld %L0, %1" "\n\t" \
>+ "dsra32 %M0, %L0, 0" "\n\t" \
>+ "sll %L0, %L0, 0" "\n\t" \
>+ ".set mips0" "\n" \
>+ : "=r" (__val) \
>+ : "m" (*__mem)); \
>+ local_irq_restore(__flags); \
>+ } else { \
>+ __val = 0; \
>+ BUG(); \
>+ } \
>+ \
>+ return pfx##ioswab##bwlq(__val); \
>+}
>
>-#define __raw_writeq(q,addr) ____raw_writeq(q, addr)
>-#endif
>+#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \
>+ \
>+static inline void pfx##out##bwlq##p(type val, unsigned long port) \
>+{ \
>+ volatile type *__addr; \
>+ type __val; \
>+ \
>+ port = __swizzle_addr_##bwlq(port); \
>+ __addr = (void *)(mips_io_port_base + port); \
>+ \
>+ __val = pfx##ioswab##bwlq(val); \
>+ \
>+ if (sizeof(type) != sizeof(u64)) { \
>+ *__addr = __val; \
>+ slow; \
>+ } else \
>+ BUILD_BUG(); \
>+} \
>+ \
>+static inline type pfx##in##bwlq##p(unsigned long port) \
>+{ \
>+ volatile type *__addr; \
>+ type __val; \
>+ \
>+ port = __swizzle_addr_##bwlq(port); \
>+ __addr = (void *)(mips_io_port_base + port); \
>+ \
>+ if (sizeof(type) != sizeof(u64)) { \
>+ __val = *__addr; \
>+ slow; \
>+ } else { \
>+ __val = 0; \
>+ BUILD_BUG(); \
>+ } \
>+ \
>+ return pfx##ioswab##bwlq(__val); \
>+}
>+
>+#define __BUILD_MEMORY_PFX(bus, bwlq, type) \
>+ \
>+__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
>+
>+#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
>+ \
>+__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
>+__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
>+
>+#define BUILDIO(bwlq, type) \
>+ \
>+__BUILD_MEMORY_PFX(, bwlq, type) \
>+__BUILD_MEMORY_PFX(__raw_, bwlq, type) \
>+__BUILD_MEMORY_PFX(bus_, bwlq, type) \
>+__BUILD_IOPORT_PFX(, bwlq, type) \
>+__BUILD_IOPORT_PFX(__raw_, bwlq, type)
>+
>+#define __BUILDIO(bwlq, type) \
>+ \
>+__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0)
>+
>+BUILDIO(b, u8)
>+BUILDIO(w, u16)
>+BUILDIO(l, u32)
>+BUILDIO(q, u64)
>+
>+__BUILDIO(q, u64)
>+
>+#define readb_relaxed readb
>+#define readw_relaxed readw
>+#define readl_relaxed readl
>+#define readq_relaxed readq
>+
>+
>+#define __BUILD_MEMORY_STRING(bwlq, type) \
>+ \
>+static inline void writes##bwlq(void *mem, void *addr, \
>+ unsigned int count) \
>+{ \
>+ volatile type *__addr = addr; \
>+ \
>+ while (count--) { \
>+ __raw_write##bwlq(*__addr, mem); \
>+ __addr++; \
>+ } \
>+} \
>+ \
>+static inline void reads##bwlq(void *mem, void *addr, \
>+ unsigned int count) \
>+{ \
>+ volatile type *__addr = addr; \
>+ \
>+ while (count--) { \
>+ *__addr = __raw_read##bwlq(mem); \
>+ __addr++; \
>+ } \
>+}
>+
>+#define __BUILD_IOPORT_STRING(bwlq, type) \
>+ \
>+static inline void outs##bwlq(unsigned long port, void *addr, \
>+ unsigned int count) \
>+{ \
>+ volatile type *__addr = addr; \
>+ \
>+ while (count--) { \
>+ __raw_out##bwlq(*__addr, port); \
>+ __addr++; \
>+ } \
>+} \
>+ \
>+static inline void ins##bwlq(unsigned long port, void *addr, \
>+ unsigned int count) \
>+{ \
>+ volatile type *__addr = addr; \
>+ \
>+ while (count--) { \
>+ *__addr = __raw_in##bwlq(port); \
>+ __addr++; \
>+ } \
>+}
>+
>+#define BUILDSTRING(bwlq, type) \
>+ \
>+__BUILD_MEMORY_STRING(bwlq, type) \
>+__BUILD_IOPORT_STRING(bwlq, type)
>+
>+BUILDSTRING(b, u8)
>+BUILDSTRING(w, u16)
>+BUILDSTRING(l, u32)
>+BUILDSTRING(q, u64)
>
>-#define writeb(b,addr) __raw_writeb(__ioswab8(b),(addr))
>-#define writew(w,addr) __raw_writew(__ioswab16(w),(addr))
>-#define writel(l,addr) __raw_writel(__ioswab32(l),(addr))
>-#define writeq(q,addr) __raw_writeq(__ioswab64(q),(addr))
>
> /* Depends on MIPS II instruction set */
> #define mmiowb() asm volatile ("sync" ::: "memory")
>@@ -394,7 +511,7 @@ do { \
> * address should have been obtained by ioremap.
> * Returns 1 on a match.
> */
>-static inline int check_signature(unsigned long io_addr,
>+static inline int check_signature(char __iomem *io_addr,
> const unsigned char *signature, int length)
> {
> int retval = 0;
>@@ -424,177 +541,6 @@ out:
> */
> #define isa_check_signature(io, s, l) check_signature(i,s,l)
>
>-static inline void __outb(unsigned char val, unsigned long port)
>-{
>- port = __swizzle_addr_b(port);
>-
>- *(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val);
>-}
>-
>-static inline void __outw(unsigned short val, unsigned long port)
>-{
>- port = __swizzle_addr_w(port);
>-
>- *(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val);
>-}
>-
>-static inline void __outl(unsigned int val, unsigned long port)
>-{
>- port = __swizzle_addr_l(port);
>-
>- *(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val);
>-}
>-
>-static inline void __outb_p(unsigned char val, unsigned long port)
>-{
>- port = __swizzle_addr_b(port);
>-
>- *(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val);
>- SLOW_DOWN_IO;
>-}
>-
>-static inline void __outw_p(unsigned short val, unsigned long port)
>-{
>- port = __swizzle_addr_w(port);
>-
>- *(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val);
>- SLOW_DOWN_IO;
>-}
>-
>-static inline void __outl_p(unsigned int val, unsigned long port)
>-{
>- port = __swizzle_addr_l(port);
>-
>- *(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val);
>- SLOW_DOWN_IO;
>-}
>-
>-#define outb(val, port) __outb(val, port)
>-#define outw(val, port) __outw(val, port)
>-#define outl(val, port) __outl(val, port)
>-#define outb_p(val, port) __outb_p(val, port)
>-#define outw_p(val, port) __outw_p(val, port)
>-#define outl_p(val, port) __outl_p(val, port)
>-
>-static inline unsigned char __inb(unsigned long port)
>-{
>- port = __swizzle_addr_b(port);
>-
>- return __ioswab8(*(volatile u8 *)(mips_io_port_base + port));
>-}
>-
>-static inline unsigned short __inw(unsigned long port)
>-{
>- port = __swizzle_addr_w(port);
>-
>- return __ioswab16(*(volatile u16 *)(mips_io_port_base + port));
>-}
>-
>-static inline unsigned int __inl(unsigned long port)
>-{
>- port = __swizzle_addr_l(port);
>-
>- return __ioswab32(*(volatile u32 *)(mips_io_port_base + port));
>-}
>-
>-static inline unsigned char __inb_p(unsigned long port)
>-{
>- u8 __val;
>-
>- port = __swizzle_addr_b(port);
>-
>- __val = *(volatile u8 *)(mips_io_port_base + port);
>- SLOW_DOWN_IO;
>-
>- return __ioswab8(__val);
>-}
>-
>-static inline unsigned short __inw_p(unsigned long port)
>-{
>- u16 __val;
>-
>- port = __swizzle_addr_w(port);
>-
>- __val = *(volatile u16 *)(mips_io_port_base + port);
>- SLOW_DOWN_IO;
>-
>- return __ioswab16(__val);
>-}
>-
>-static inline unsigned int __inl_p(unsigned long port)
>-{
>- u32 __val;
>-
>- port = __swizzle_addr_l(port);
>-
>- __val = *(volatile u32 *)(mips_io_port_base + port);
>- SLOW_DOWN_IO;
>-
>- return __ioswab32(__val);
>-}
>-
>-#define inb(port) __inb(port)
>-#define inw(port) __inw(port)
>-#define inl(port) __inl(port)
>-#define inb_p(port) __inb_p(port)
>-#define inw_p(port) __inw_p(port)
>-#define inl_p(port) __inl_p(port)
>-
>-static inline void __outsb(unsigned long port, void *addr, unsigned int count)
>-{
>- while (count--) {
>- outb(*(u8 *)addr, port);
>- addr++;
>- }
>-}
>-
>-static inline void __insb(unsigned long port, void *addr, unsigned int count)
>-{
>- while (count--) {
>- *(u8 *)addr = inb(port);
>- addr++;
>- }
>-}
>-
>-static inline void __outsw(unsigned long port, void *addr, unsigned int count)
>-{
>- while (count--) {
>- outw(*(u16 *)addr, port);
>- addr += 2;
>- }
>-}
>-
>-static inline void __insw(unsigned long port, void *addr, unsigned int count)
>-{
>- while (count--) {
>- *(u16 *)addr = inw(port);
>- addr += 2;
>- }
>-}
>-
>-static inline void __outsl(unsigned long port, void *addr, unsigned int count)
>-{
>- while (count--) {
>- outl(*(u32 *)addr, port);
>- addr += 4;
>- }
>-}
>-
>-static inline void __insl(unsigned long port, void *addr, unsigned int count)
>-{
>- while (count--) {
>- *(u32 *)addr = inl(port);
>- addr += 4;
>- }
>-}
>-
>-#define outsb(port, addr, count) __outsb(port, addr, count)
>-#define insb(port, addr, count) __insb(port, addr, count)
>-#define outsw(port, addr, count) __outsw(port, addr, count)
>-#define insw(port, addr, count) __insw(port, addr, count)
>-#define outsl(port, addr, count) __outsl(port, addr, count)
>-#define insl(port, addr, count) __insl(port, addr, count)
>-
> /*
> * The caches on some architectures aren't dma-coherent and have need to
> * handle this in software. There are three types of operations that
>diff -up --recursive --new-file linux-mips-2.6.10-rc2-20041124.macro/include/asm-mips/mach-generic/ide.h linux-mips-2.6.10-rc2-20041124/include/asm-mips/mach-generic/ide.h
>--- linux-mips-2.6.10-rc2-20041124.macro/include/asm-mips/mach-generic/ide.h 2004-11-24 21:37:52.000000000 +0000
>+++ linux-mips-2.6.10-rc2-20041124/include/asm-mips/mach-generic/ide.h 2004-12-14 17:25:36.000000000 +0000
>@@ -64,7 +64,17 @@ static __inline__ unsigned long ide_defa
> #define ide_init_default_irq(base) ide_default_irq(base)
> #endif
>
>-#include <asm-generic/ide_iops.h>
>+/* MIPS port and memory-mapped I/O string operations. */
>+
>+#define __ide_insw insw
>+#define __ide_insl insl
>+#define __ide_outsw outsw
>+#define __ide_outsl outsl
>+
>+#define __ide_mm_insw readsw
>+#define __ide_mm_insl readsl
>+#define __ide_mm_outsw writesw
>+#define __ide_mm_outsl writesl
>
> #endif /* __KERNEL__ */
>
>
>
>
>
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2005-02-18 19:44 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-15 21:13 [PATCH] I/O helpers rework Maciej W. Rozycki
2005-01-06 15:45 ` Atsushi Nemoto
2005-01-10 15:28 ` Maciej W. Rozycki
2005-01-10 17:21 ` Atsushi Nemoto
2005-01-10 18:11 ` Maciej W. Rozycki
2005-01-11 0:53 ` Atsushi Nemoto
2005-01-13 18:12 ` Richard Sandiford
2005-01-13 18:25 ` Maciej W. Rozycki
2005-01-13 21:48 ` Richard Sandiford
2005-01-14 1:52 ` Atsushi Nemoto
2005-01-14 11:05 ` Richard Sandiford
2005-01-14 19:57 ` Maciej W. Rozycki
2005-01-21 16:50 ` Atsushi Nemoto
2005-01-22 2:51 ` Maciej W. Rozycki
2005-01-25 1:09 ` Atsushi Nemoto
2005-02-17 1:34 ` Ralf Baechle
2005-02-18 19:44 ` Maciej W. Rozycki
2005-01-06 16:33 ` Herbert Valerio Riedel
2005-01-10 13:05 ` Maciej W. Rozycki
2005-01-10 14:46 ` Herbert Valerio Riedel
2005-01-10 14:49 ` Herbert Valerio Riedel
2005-01-14 20:07 ` Maciej W. Rozycki
2005-01-13 22:18 ` Manish Lachwani
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox