[SCSI] scsi_dh: add generic SPC-3 alua handler
[linux-2.6] / include / asm-arm / arch-rpc / io.h
1 /*
2  *  linux/include/asm-arm/arch-rpc/io.h
3  *
4  *  Copyright (C) 1997 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Modifications:
11  *  06-Dec-1997 RMK     Created.
12  */
13 #ifndef __ASM_ARM_ARCH_IO_H
14 #define __ASM_ARM_ARCH_IO_H
15
16 #include <asm/hardware.h>
17
18 #define IO_SPACE_LIMIT 0xffffffff
19
20 /*
21  * GCC is totally crap at loading/storing data.  We try to persuade it
22  * to do the right thing by using these whereever possible instead of
23  * the above.
24  */
25 #define __arch_base_getb(b,o)                   \
26  ({                                             \
27         unsigned int __v, __r = (b);            \
28         __asm__ __volatile__(                   \
29                 "ldrb   %0, [%1, %2]"           \
30                 : "=r" (__v)                    \
31                 : "r" (__r), "Ir" (o));         \
32         __v;                                    \
33  })
34
35 #define __arch_base_getl(b,o)                   \
36  ({                                             \
37         unsigned int __v, __r = (b);            \
38         __asm__ __volatile__(                   \
39                 "ldr    %0, [%1, %2]"           \
40                 : "=r" (__v)                    \
41                 : "r" (__r), "Ir" (o));         \
42         __v;                                    \
43  })
44
45 #define __arch_base_putb(v,b,o)                 \
46  ({                                             \
47         unsigned int __r = (b);                 \
48         __asm__ __volatile__(                   \
49                 "strb   %0, [%1, %2]"           \
50                 :                               \
51                 : "r" (v), "r" (__r), "Ir" (o));\
52  })
53
54 #define __arch_base_putl(v,b,o)                 \
55  ({                                             \
56         unsigned int __r = (b);                 \
57         __asm__ __volatile__(                   \
58                 "str    %0, [%1, %2]"           \
59                 :                               \
60                 : "r" (v), "r" (__r), "Ir" (o));\
61  })
62
63 /*
64  * We use two different types of addressing - PC style addresses, and ARM
65  * addresses.  PC style accesses the PC hardware with the normal PC IO
66  * addresses, eg 0x3f8 for serial#1.  ARM addresses are 0x80000000+
67  * and are translated to the start of IO.  Note that all addresses are
68  * shifted left!
69  */
70 #define __PORT_PCIO(x)  (!((x) & 0x80000000))
71
72 /*
73  * Dynamic IO functions.
74  */
75 static inline void __outb (unsigned int value, unsigned int port)
76 {
77         unsigned long temp;
78         __asm__ __volatile__(
79         "tst    %2, #0x80000000\n\t"
80         "mov    %0, %4\n\t"
81         "addeq  %0, %0, %3\n\t"
82         "strb   %1, [%0, %2, lsl #2]    @ outb"
83         : "=&r" (temp)
84         : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
85         : "cc");
86 }
87
88 static inline void __outw (unsigned int value, unsigned int port)
89 {
90         unsigned long temp;
91         __asm__ __volatile__(
92         "tst    %2, #0x80000000\n\t"
93         "mov    %0, %4\n\t"
94         "addeq  %0, %0, %3\n\t"
95         "str    %1, [%0, %2, lsl #2]    @ outw"
96         : "=&r" (temp)
97         : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
98         : "cc");
99 }
100
101 static inline void __outl (unsigned int value, unsigned int port)
102 {
103         unsigned long temp;
104         __asm__ __volatile__(
105         "tst    %2, #0x80000000\n\t"
106         "mov    %0, %4\n\t"
107         "addeq  %0, %0, %3\n\t"
108         "str    %1, [%0, %2, lsl #2]    @ outl"
109         : "=&r" (temp)
110         : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
111         : "cc");
112 }
113
114 #define DECLARE_DYN_IN(sz,fnsuffix,instr)                                       \
115 static inline unsigned sz __in##fnsuffix (unsigned int port)            \
116 {                                                                               \
117         unsigned long temp, value;                                              \
118         __asm__ __volatile__(                                                   \
119         "tst    %2, #0x80000000\n\t"                                            \
120         "mov    %0, %4\n\t"                                                     \
121         "addeq  %0, %0, %3\n\t"                                                 \
122         "ldr" instr "   %1, [%0, %2, lsl #2]    @ in" #fnsuffix                 \
123         : "=&r" (temp), "=r" (value)                                            \
124         : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)                \
125         : "cc");                                                                \
126         return (unsigned sz)value;                                              \
127 }
128
129 static inline void __iomem *__deprecated __ioaddr(unsigned int port)
130 {
131         void __iomem *ret;
132         if (__PORT_PCIO(port))
133                 ret = PCIO_BASE;
134         else
135                 ret = IO_BASE;
136         return ret + (port << 2);
137 }
138
139 #define DECLARE_IO(sz,fnsuffix,instr)   \
140         DECLARE_DYN_IN(sz,fnsuffix,instr)
141
142 DECLARE_IO(char,b,"b")
143 DECLARE_IO(short,w,"")
144 DECLARE_IO(int,l,"")
145
146 #undef DECLARE_IO
147 #undef DECLARE_DYN_IN
148
149 /*
150  * Constant address IO functions
151  *
152  * These have to be macros for the 'J' constraint to work -
153  * +/-4096 immediate operand.
154  */
155 #define __outbc(value,port)                                                     \
156 ({                                                                              \
157         if (__PORT_PCIO((port)))                                                \
158                 __asm__ __volatile__(                                           \
159                 "strb   %0, [%1, %2]    @ outbc"                                \
160                 : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2));          \
161         else                                                                    \
162                 __asm__ __volatile__(                                           \
163                 "strb   %0, [%1, %2]    @ outbc"                                \
164                 : : "r" (value), "r" (IO_BASE), "r" ((port) << 2));             \
165 })
166
167 #define __inbc(port)                                                            \
168 ({                                                                              \
169         unsigned char result;                                                   \
170         if (__PORT_PCIO((port)))                                                \
171                 __asm__ __volatile__(                                           \
172                 "ldrb   %0, [%1, %2]    @ inbc"                                 \
173                 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
174         else                                                                    \
175                 __asm__ __volatile__(                                           \
176                 "ldrb   %0, [%1, %2]    @ inbc"                                 \
177                 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
178         result;                                                                 \
179 })
180
181 #define __outwc(value,port)                                                     \
182 ({                                                                              \
183         unsigned long __v = value;                                              \
184         if (__PORT_PCIO((port)))                                                \
185                 __asm__ __volatile__(                                           \
186                 "str    %0, [%1, %2]    @ outwc"                                \
187                 : : "r" (__v|__v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2));    \
188         else                                                                    \
189                 __asm__ __volatile__(                                           \
190                 "str    %0, [%1, %2]    @ outwc"                                \
191                 : : "r" (__v|__v<<16), "r" (IO_BASE), "r" ((port) << 2));               \
192 })
193
194 #define __inwc(port)                                                            \
195 ({                                                                              \
196         unsigned short result;                                                  \
197         if (__PORT_PCIO((port)))                                                \
198                 __asm__ __volatile__(                                           \
199                 "ldr    %0, [%1, %2]    @ inwc"                                 \
200                 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
201         else                                                                    \
202                 __asm__ __volatile__(                                           \
203                 "ldr    %0, [%1, %2]    @ inwc"                                 \
204                 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
205         result & 0xffff;                                                        \
206 })
207
208 #define __outlc(value,port)                                                     \
209 ({                                                                              \
210         unsigned long __v = value;                                              \
211         if (__PORT_PCIO((port)))                                                \
212                 __asm__ __volatile__(                                           \
213                 "str    %0, [%1, %2]    @ outlc"                                \
214                 : : "r" (__v), "r" (PCIO_BASE), "Jr" ((port) << 2));            \
215         else                                                                    \
216                 __asm__ __volatile__(                                           \
217                 "str    %0, [%1, %2]    @ outlc"                                \
218                 : : "r" (__v), "r" (IO_BASE), "r" ((port) << 2));               \
219 })
220
221 #define __inlc(port)                                                            \
222 ({                                                                              \
223         unsigned long result;                                                   \
224         if (__PORT_PCIO((port)))                                                \
225                 __asm__ __volatile__(                                           \
226                 "ldr    %0, [%1, %2]    @ inlc"                                 \
227                 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
228         else                                                                    \
229                 __asm__ __volatile__(                                           \
230                 "ldr    %0, [%1, %2]    @ inlc"                                 \
231                 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
232         result;                                                                 \
233 })
234
235 #define __ioaddrc(port)         __ioaddr(port)
236
237 #define inb(p)          (__builtin_constant_p((p)) ? __inbc(p)    : __inb(p))
238 #define inw(p)          (__builtin_constant_p((p)) ? __inwc(p)    : __inw(p))
239 #define inl(p)          (__builtin_constant_p((p)) ? __inlc(p)    : __inl(p))
240 #define outb(v,p)       (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
241 #define outw(v,p)       (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
242 #define outl(v,p)       (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
243 #define __ioaddr(p)     (__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
244 /* the following macro is deprecated */
245 #define ioaddr(port)    ((unsigned long)__ioaddr((port)))
246
247 #define insb(p,d,l)     __raw_readsb(__ioaddr(p),d,l)
248 #define insw(p,d,l)     __raw_readsw(__ioaddr(p),d,l)
249
250 #define outsb(p,d,l)    __raw_writesb(__ioaddr(p),d,l)
251 #define outsw(p,d,l)    __raw_writesw(__ioaddr(p),d,l)
252
253 /*
254  * 1:1 mapping for ioremapped regions.
255  */
256 #define __mem_pci(x)    (x)
257
258 #endif