aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@SteelEye.com>2005-04-16 18:25:54 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:25:54 -0400
commitdae409a27788774adb810f7cdb771ba7cce7af8a (patch)
tree7fbbbe81527c5f321f374f958a82dfa30e170850
parentc41f5eb3b8feb8772561f0e34cfee4de1fa433ec (diff)
[PATCH] add Big Endian variants of ioread/iowrite
In the new io infrastructure, all of our operators are expecting the underlying device to be little endian (because the PCI bus, their main consumer, is LE). However, there are a fair few devices and busses in the world that are actually Big Endian. There's even evidence that some of these BE bus and chip types are attached to LE systems. Thus, there's a need for a BE equivalent of our io{read,write}{16,32} operations. The attached patch adds this as io{read,write}{16,32}be. When it's in, I'll add the first consume (the 53c700 SCSI chip driver). Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/parisc/lib/iomap.c68
-rw-r--r--include/asm-generic/iomap.h5
-rw-r--r--lib/iomap.c20
3 files changed, 93 insertions, 0 deletions
diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c
index 290a62e7120b..01bec8fcbd0d 100644
--- a/arch/parisc/lib/iomap.c
+++ b/arch/parisc/lib/iomap.c
@@ -43,10 +43,14 @@
43struct iomap_ops { 43struct iomap_ops {
44 unsigned int (*read8)(void __iomem *); 44 unsigned int (*read8)(void __iomem *);
45 unsigned int (*read16)(void __iomem *); 45 unsigned int (*read16)(void __iomem *);
46 unsigned int (*read16be)(void __iomem *);
46 unsigned int (*read32)(void __iomem *); 47 unsigned int (*read32)(void __iomem *);
48 unsigned int (*read32be)(void __iomem *);
47 void (*write8)(u8, void __iomem *); 49 void (*write8)(u8, void __iomem *);
48 void (*write16)(u16, void __iomem *); 50 void (*write16)(u16, void __iomem *);
51 void (*write16be)(u16, void __iomem *);
49 void (*write32)(u32, void __iomem *); 52 void (*write32)(u32, void __iomem *);
53 void (*write32be)(u32, void __iomem *);
50 void (*read8r)(void __iomem *, void *, unsigned long); 54 void (*read8r)(void __iomem *, void *, unsigned long);
51 void (*read16r)(void __iomem *, void *, unsigned long); 55 void (*read16r)(void __iomem *, void *, unsigned long);
52 void (*read32r)(void __iomem *, void *, unsigned long); 56 void (*read32r)(void __iomem *, void *, unsigned long);
@@ -122,9 +126,13 @@ static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n)
122static const struct iomap_ops ioport_ops = { 126static const struct iomap_ops ioport_ops = {
123 ioport_read8, 127 ioport_read8,
124 ioport_read16, 128 ioport_read16,
129 ioport_read16,
130 ioport_read32,
125 ioport_read32, 131 ioport_read32,
126 ioport_write8, 132 ioport_write8,
127 ioport_write16, 133 ioport_write16,
134 ioport_write16,
135 ioport_write32,
128 ioport_write32, 136 ioport_write32,
129 ioport_read8r, 137 ioport_read8r,
130 ioport_read16r, 138 ioport_read16r,
@@ -146,11 +154,21 @@ static unsigned int iomem_read16(void __iomem *addr)
146 return readw(addr); 154 return readw(addr);
147} 155}
148 156
157static unsigned int iomem_read16be(void __iomem *addr)
158{
159 return __raw_readw(addr);
160}
161
149static unsigned int iomem_read32(void __iomem *addr) 162static unsigned int iomem_read32(void __iomem *addr)
150{ 163{
151 return readl(addr); 164 return readl(addr);
152} 165}
153 166
167static unsigned int iomem_read32be(void __iomem *addr)
168{
169 return __raw_readl(addr);
170}
171
154static void iomem_write8(u8 datum, void __iomem *addr) 172static void iomem_write8(u8 datum, void __iomem *addr)
155{ 173{
156 writeb(datum, addr); 174 writeb(datum, addr);
@@ -161,11 +179,21 @@ static void iomem_write16(u16 datum, void __iomem *addr)
161 writew(datum, addr); 179 writew(datum, addr);
162} 180}
163 181
182static void iomem_write16be(u16 datum, void __iomem *addr)
183{
184 __raw_writew(datum, addr);
185}
186
164static void iomem_write32(u32 datum, void __iomem *addr) 187static void iomem_write32(u32 datum, void __iomem *addr)
165{ 188{
166 writel(datum, addr); 189 writel(datum, addr);
167} 190}
168 191
192static void iomem_write32be(u32 datum, void __iomem *addr)
193{
194 __raw_writel(datum, addr);
195}
196
169static void iomem_read8r(void __iomem *addr, void *dst, unsigned long count) 197static void iomem_read8r(void __iomem *addr, void *dst, unsigned long count)
170{ 198{
171 while (count--) { 199 while (count--) {
@@ -217,10 +245,14 @@ static void iomem_write32r(void __iomem *addr, const void *s, unsigned long n)
217static const struct iomap_ops iomem_ops = { 245static const struct iomap_ops iomem_ops = {
218 iomem_read8, 246 iomem_read8,
219 iomem_read16, 247 iomem_read16,
248 iomem_read16be,
220 iomem_read32, 249 iomem_read32,
250 iomem_read32be,
221 iomem_write8, 251 iomem_write8,
222 iomem_write16, 252 iomem_write16,
253 iomem_write16be,
223 iomem_write32, 254 iomem_write32,
255 iomem_write32be,
224 iomem_read8r, 256 iomem_read8r,
225 iomem_read16r, 257 iomem_read16r,
226 iomem_read32r, 258 iomem_read32r,
@@ -253,6 +285,13 @@ unsigned int ioread16(void __iomem *addr)
253 return le16_to_cpup((u16 *)addr); 285 return le16_to_cpup((u16 *)addr);
254} 286}
255 287
288unsigned int ioread16be(void __iomem *addr)
289{
290 if (unlikely(INDIRECT_ADDR(addr)))
291 return iomap_ops[ADDR_TO_REGION(addr)]->read16be(addr);
292 return *((u16 *)addr);
293}
294
256unsigned int ioread32(void __iomem *addr) 295unsigned int ioread32(void __iomem *addr)
257{ 296{
258 if (unlikely(INDIRECT_ADDR(addr))) 297 if (unlikely(INDIRECT_ADDR(addr)))
@@ -260,6 +299,13 @@ unsigned int ioread32(void __iomem *addr)
260 return le32_to_cpup((u32 *)addr); 299 return le32_to_cpup((u32 *)addr);
261} 300}
262 301
302unsigned int ioread32be(void __iomem *addr)
303{
304 if (unlikely(INDIRECT_ADDR(addr)))
305 return iomap_ops[ADDR_TO_REGION(addr)]->read32be(addr);
306 return *((u32 *)addr);
307}
308
263void iowrite8(u8 datum, void __iomem *addr) 309void iowrite8(u8 datum, void __iomem *addr)
264{ 310{
265 if (unlikely(INDIRECT_ADDR(addr))) { 311 if (unlikely(INDIRECT_ADDR(addr))) {
@@ -278,6 +324,15 @@ void iowrite16(u16 datum, void __iomem *addr)
278 } 324 }
279} 325}
280 326
327void iowrite16be(u16 datum, void __iomem *addr)
328{
329 if (unlikely(INDIRECT_ADDR(addr))) {
330 iomap_ops[ADDR_TO_REGION(addr)]->write16be(datum, addr);
331 } else {
332 *((u16 *)addr) = datum;
333 }
334}
335
281void iowrite32(u32 datum, void __iomem *addr) 336void iowrite32(u32 datum, void __iomem *addr)
282{ 337{
283 if (unlikely(INDIRECT_ADDR(addr))) { 338 if (unlikely(INDIRECT_ADDR(addr))) {
@@ -287,6 +342,15 @@ void iowrite32(u32 datum, void __iomem *addr)
287 } 342 }
288} 343}
289 344
345void iowrite32be(u32 datum, void __iomem *addr)
346{
347 if (unlikely(INDIRECT_ADDR(addr))) {
348 iomap_ops[ADDR_TO_REGION(addr)]->write32be(datum, addr);
349 } else {
350 *((u32 *)addr) = datum;
351 }
352}
353
290/* Repeating interfaces */ 354/* Repeating interfaces */
291 355
292void ioread8_rep(void __iomem *addr, void *dst, unsigned long count) 356void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
@@ -406,10 +470,14 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
406 470
407EXPORT_SYMBOL(ioread8); 471EXPORT_SYMBOL(ioread8);
408EXPORT_SYMBOL(ioread16); 472EXPORT_SYMBOL(ioread16);
473EXPORT_SYMBOL(ioread16be);
409EXPORT_SYMBOL(ioread32); 474EXPORT_SYMBOL(ioread32);
475EXPORT_SYMBOL(ioread32be);
410EXPORT_SYMBOL(iowrite8); 476EXPORT_SYMBOL(iowrite8);
411EXPORT_SYMBOL(iowrite16); 477EXPORT_SYMBOL(iowrite16);
478EXPORT_SYMBOL(iowrite16be);
412EXPORT_SYMBOL(iowrite32); 479EXPORT_SYMBOL(iowrite32);
480EXPORT_SYMBOL(iowrite32be);
413EXPORT_SYMBOL(ioread8_rep); 481EXPORT_SYMBOL(ioread8_rep);
414EXPORT_SYMBOL(ioread16_rep); 482EXPORT_SYMBOL(ioread16_rep);
415EXPORT_SYMBOL(ioread32_rep); 483EXPORT_SYMBOL(ioread32_rep);
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index 4991543d44c8..cde592fca441 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -2,6 +2,7 @@
2#define __GENERIC_IO_H 2#define __GENERIC_IO_H
3 3
4#include <linux/linkage.h> 4#include <linux/linkage.h>
5#include <asm/byteorder.h>
5 6
6/* 7/*
7 * These are the "generic" interfaces for doing new-style 8 * These are the "generic" interfaces for doing new-style
@@ -26,11 +27,15 @@
26 */ 27 */
27extern unsigned int fastcall ioread8(void __iomem *); 28extern unsigned int fastcall ioread8(void __iomem *);
28extern unsigned int fastcall ioread16(void __iomem *); 29extern unsigned int fastcall ioread16(void __iomem *);
30extern unsigned int fastcall ioread16be(void __iomem *);
29extern unsigned int fastcall ioread32(void __iomem *); 31extern unsigned int fastcall ioread32(void __iomem *);
32extern unsigned int fastcall ioread32be(void __iomem *);
30 33
31extern void fastcall iowrite8(u8, void __iomem *); 34extern void fastcall iowrite8(u8, void __iomem *);
32extern void fastcall iowrite16(u16, void __iomem *); 35extern void fastcall iowrite16(u16, void __iomem *);
36extern void fastcall iowrite16be(u16, void __iomem *);
33extern void fastcall iowrite32(u32, void __iomem *); 37extern void fastcall iowrite32(u32, void __iomem *);
38extern void fastcall iowrite32be(u32, void __iomem *);
34 39
35/* 40/*
36 * "string" versions of the above. Note that they 41 * "string" versions of the above. Note that they
diff --git a/lib/iomap.c b/lib/iomap.c
index 5e74390852b0..55689c5d3379 100644
--- a/lib/iomap.c
+++ b/lib/iomap.c
@@ -58,13 +58,23 @@ unsigned int fastcall ioread16(void __iomem *addr)
58{ 58{
59 IO_COND(addr, return inw(port), return readw(addr)); 59 IO_COND(addr, return inw(port), return readw(addr));
60} 60}
61unsigned int fastcall ioread16be(void __iomem *addr)
62{
63 IO_COND(addr, return inw(port), return be16_to_cpu(__raw_readw(addr)));
64}
61unsigned int fastcall ioread32(void __iomem *addr) 65unsigned int fastcall ioread32(void __iomem *addr)
62{ 66{
63 IO_COND(addr, return inl(port), return readl(addr)); 67 IO_COND(addr, return inl(port), return readl(addr));
64} 68}
69unsigned int fastcall ioread32be(void __iomem *addr)
70{
71 IO_COND(addr, return inl(port), return be32_to_cpu(__raw_readl(addr)));
72}
65EXPORT_SYMBOL(ioread8); 73EXPORT_SYMBOL(ioread8);
66EXPORT_SYMBOL(ioread16); 74EXPORT_SYMBOL(ioread16);
75EXPORT_SYMBOL(ioread16be);
67EXPORT_SYMBOL(ioread32); 76EXPORT_SYMBOL(ioread32);
77EXPORT_SYMBOL(ioread32be);
68 78
69void fastcall iowrite8(u8 val, void __iomem *addr) 79void fastcall iowrite8(u8 val, void __iomem *addr)
70{ 80{
@@ -74,13 +84,23 @@ void fastcall iowrite16(u16 val, void __iomem *addr)
74{ 84{
75 IO_COND(addr, outw(val,port), writew(val, addr)); 85 IO_COND(addr, outw(val,port), writew(val, addr));
76} 86}
87void fastcall iowrite16be(u16 val, void __iomem *addr)
88{
89 IO_COND(addr, outw(val,port), __raw_writew(cpu_to_be16(val), addr));
90}
77void fastcall iowrite32(u32 val, void __iomem *addr) 91void fastcall iowrite32(u32 val, void __iomem *addr)
78{ 92{
79 IO_COND(addr, outl(val,port), writel(val, addr)); 93 IO_COND(addr, outl(val,port), writel(val, addr));
80} 94}
95void fastcall iowrite32be(u32 val, void __iomem *addr)
96{
97 IO_COND(addr, outl(val,port), __raw_writel(cpu_to_be32(val), addr));
98}
81EXPORT_SYMBOL(iowrite8); 99EXPORT_SYMBOL(iowrite8);
82EXPORT_SYMBOL(iowrite16); 100EXPORT_SYMBOL(iowrite16);
101EXPORT_SYMBOL(iowrite16be);
83EXPORT_SYMBOL(iowrite32); 102EXPORT_SYMBOL(iowrite32);
103EXPORT_SYMBOL(iowrite32be);
84 104
85/* 105/*
86 * These are the "repeat MMIO read/write" functions. 106 * These are the "repeat MMIO read/write" functions.