1#ifndef _ASM_IO_H
2#define _ASM_IO_H
3
4#include <linux/config.h>
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#define IO_SPACE_LIMIT 0xffff
40
41#define XQUAD_PORTIO_BASE 0xfe400000
42#define XQUAD_PORTIO_QUAD 0x40000
43
44#ifdef __KERNEL__
45
46#include <linux/vmalloc.h>
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61static inline unsigned long virt_to_phys(volatile void * address)
62{
63 return __pa(address);
64}
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79static inline void * phys_to_virt(unsigned long address)
80{
81 return __va(address);
82}
83
84
85
86
87#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
88
89extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
90
91
92
93
94
95
96
97
98
99
100
101
102
103static inline void * ioremap (unsigned long offset, unsigned long size)
104{
105 return __ioremap(offset, size, 0);
106}
107
108extern void * ioremap_nocache (unsigned long offset, unsigned long size);
109extern void iounmap(void *addr);
110
111
112
113
114
115
116extern void *bt_ioremap(unsigned long offset, unsigned long size);
117extern void bt_iounmap(void *addr, unsigned long size);
118
119
120
121
122#define isa_virt_to_bus virt_to_phys
123#define isa_page_to_bus page_to_phys
124#define isa_bus_to_virt phys_to_virt
125
126
127
128
129
130
131
132#define virt_to_bus virt_to_phys
133#define bus_to_virt phys_to_virt
134
135
136
137
138
139
140
141
142#define readb(addr) (*(volatile unsigned char *) (addr))
143#define readw(addr) (*(volatile unsigned short *) (addr))
144#define readl(addr) (*(volatile unsigned int *) (addr))
145#define readb_relaxed(addr) readb(addr)
146#define readw_relaxed(addr) readw(addr)
147#define readl_relaxed(addr) readl(addr)
148#define __raw_readb readb
149#define __raw_readw readw
150#define __raw_readl readl
151
152#define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b))
153#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b))
154#define writel(b,addr) (*(volatile unsigned int *) (addr) = (b))
155#define __raw_writeb writeb
156#define __raw_writew writew
157#define __raw_writel writel
158
159#define memset_io(a,b,c) memset((void *)(a),(b),(c))
160#define memcpy_fromio(a,b,c) __memcpy((a),(void *)(b),(c))
161#define memcpy_toio(a,b,c) __memcpy((void *)(a),(b),(c))
162
163
164
165
166
167
168
169
170
171#define __ISA_IO_base ((char *)(PAGE_OFFSET))
172
173#define isa_readb(a) readb(__ISA_IO_base + (a))
174#define isa_readw(a) readw(__ISA_IO_base + (a))
175#define isa_readl(a) readl(__ISA_IO_base + (a))
176#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
177#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
178#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
179#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c))
180#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c))
181#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c))
182
183
184
185
186
187
188#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void *)(b),(c),(d))
189#define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void *)(__ISA_IO_base + (b)),(c),(d))
190
191
192
193
194
195
196
197
198
199
200
201
202static inline int check_signature(unsigned long io_addr,
203 const unsigned char *signature, int length)
204{
205 int retval = 0;
206 do {
207 if (readb(io_addr) != *signature)
208 goto out;
209 io_addr++;
210 signature++;
211 length--;
212 } while (length);
213 retval = 1;
214out:
215 return retval;
216}
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232static inline int isa_check_signature(unsigned long io_addr,
233 const unsigned char *signature, int length)
234{
235 int retval = 0;
236 do {
237 if (isa_readb(io_addr) != *signature)
238 goto out;
239 io_addr++;
240 signature++;
241 length--;
242 } while (length);
243 retval = 1;
244out:
245 return retval;
246}
247
248
249
250
251
252
253
254
255
256#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
257
258static inline void flush_write_buffers(void)
259{
260 __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
261}
262
263#define dma_cache_inv(_start,_size) flush_write_buffers()
264#define dma_cache_wback(_start,_size) flush_write_buffers()
265#define dma_cache_wback_inv(_start,_size) flush_write_buffers()
266
267#else
268
269
270
271#define dma_cache_inv(_start,_size) do { } while (0)
272#define dma_cache_wback(_start,_size) do { } while (0)
273#define dma_cache_wback_inv(_start,_size) do { } while (0)
274#define flush_write_buffers()
275
276#endif
277
278#endif
279
280#ifdef SLOW_IO_BY_JUMPING
281#define __SLOW_DOWN_IO "jmp 1f; 1: jmp 1f; 1:"
282#else
283#define __SLOW_DOWN_IO "outb %%al,$0x80;"
284#endif
285
286static inline void slow_down_io(void) {
287 __asm__ __volatile__(
288 __SLOW_DOWN_IO
289#ifdef REALLY_SLOW_IO
290 __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
291#endif
292 : : );
293}
294
295#ifdef CONFIG_X86_NUMAQ
296extern void *xquad_portio;
297#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
298#define __BUILDIO(bwl,bw,type) \
299static inline void out##bwl##_quad(unsigned type value, int port, int quad) { \
300 if (xquad_portio) \
301 write##bwl(value, XQUAD_PORT_ADDR(port, quad)); \
302 else \
303 out##bwl##_local(value, port); \
304} \
305static inline void out##bwl(unsigned type value, int port) { \
306 out##bwl##_quad(value, port, 0); \
307} \
308static inline unsigned type in##bwl##_quad(int port, int quad) { \
309 if (xquad_portio) \
310 return read##bwl(XQUAD_PORT_ADDR(port, quad)); \
311 else \
312 return in##bwl##_local(port); \
313} \
314static inline unsigned type in##bwl(int port) { \
315 return in##bwl##_quad(port, 0); \
316}
317#else
318#define __BUILDIO(bwl,bw,type) \
319static inline void out##bwl(unsigned type value, int port) { \
320 out##bwl##_local(value, port); \
321} \
322static inline unsigned type in##bwl(int port) { \
323 return in##bwl##_local(port); \
324}
325#endif
326
327
328#define BUILDIO(bwl,bw,type) \
329static inline void out##bwl##_local(unsigned type value, int port) { \
330 __asm__ __volatile__("out" #bwl " %" #bw "0, %w1" : : "a"(value), "Nd"(port)); \
331} \
332static inline unsigned type in##bwl##_local(int port) { \
333 unsigned type value; \
334 __asm__ __volatile__("in" #bwl " %w1, %" #bw "0" : "=a"(value) : "Nd"(port)); \
335 return value; \
336} \
337static inline void out##bwl##_local_p(unsigned type value, int port) { \
338 out##bwl##_local(value, port); \
339 slow_down_io(); \
340} \
341static inline unsigned type in##bwl##_local_p(int port) { \
342 unsigned type value = in##bwl##_local(port); \
343 slow_down_io(); \
344 return value; \
345} \
346__BUILDIO(bwl,bw,type) \
347static inline void out##bwl##_p(unsigned type value, int port) { \
348 out##bwl(value, port); \
349 slow_down_io(); \
350} \
351static inline unsigned type in##bwl##_p(int port) { \
352 unsigned type value = in##bwl(port); \
353 slow_down_io(); \
354 return value; \
355} \
356static inline void outs##bwl(int port, const void *addr, unsigned long count) { \
357 __asm__ __volatile__("rep; outs" #bwl : "+S"(addr), "+c"(count) : "d"(port)); \
358} \
359static inline void ins##bwl(int port, void *addr, unsigned long count) { \
360 __asm__ __volatile__("rep; ins" #bwl : "+D"(addr), "+c"(count) : "d"(port)); \
361}
362
363BUILDIO(b,b,char)
364BUILDIO(w,w,short)
365BUILDIO(l,,int)
366
367#endif
368