Rev 1618 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
629 | giacomo | 1 | #ifndef __IO__ |
2 | #define __IO__ |
||
3 | |||
4 | #include <linux/compatib.h> |
||
1621 | fabio | 5 | #include <arch/sys/cdefs.h> |
629 | giacomo | 6 | |
7 | __BEGIN_DECLS |
||
8 | |||
9 | /* |
||
10 | * Thanks to James van Artsdalen for a better timing-fix than |
||
11 | * the two short jumps: using outb's to a nonexistent port seems |
||
12 | * to guarantee better timings even on fast machines. |
||
13 | * |
||
14 | * On the other hand, I'd like to be sure of a non-existent port: |
||
15 | * I feel a bit unsafe about using 0x80 (should be safe, though) |
||
16 | * |
||
17 | * Linus |
||
18 | */ |
||
19 | |||
20 | #ifdef SLOW_IO_BY_JUMPING |
||
21 | #define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:") |
||
22 | #else |
||
23 | #define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80") |
||
24 | #endif |
||
25 | |||
26 | #ifdef REALLY_SLOW_IO |
||
27 | #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; } |
||
28 | #else |
||
29 | #define SLOW_DOWN_IO __SLOW_DOWN_IO |
||
30 | #endif |
||
31 | |||
32 | |||
33 | #define __INS(s) \ |
||
34 | extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \ |
||
35 | { __asm__ __volatile__ ("cld ; rep ; ins" #s \ |
||
36 | : "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } |
||
37 | __INS(b) |
||
38 | __INS(w) |
||
39 | __INS(l) |
||
40 | |||
41 | #define __OUTS(s) \ |
||
42 | extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \ |
||
43 | { __asm__ __volatile__ ("cld ; rep ; outs" #s \ |
||
44 | : "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } |
||
45 | __OUTS(b) |
||
46 | __OUTS(w) |
||
47 | __OUTS(l) |
||
48 | |||
49 | /* Traslation from virtual to phisical address...*/ |
||
50 | /* from asm/io.h */ |
||
51 | |||
52 | #define __io_virt(x) ((void *)(x)) |
||
53 | |||
54 | extern inline void * phys_to_virt(unsigned long address) |
||
55 | { |
||
56 | return __io_virt(address); |
||
57 | } |
||
58 | |||
59 | |||
60 | extern __inline__ DWORD virt_to_phys(volatile void * address) |
||
61 | { |
||
62 | return (DWORD)address; |
||
63 | } |
||
64 | |||
65 | #define bus_to_virt phys_to_virt |
||
66 | #define virt_to_bus virt_to_phys |
||
67 | |||
68 | |||
69 | #define readb(addr) (*(volatile unsigned char *) __io_virt(addr)) |
||
70 | #define readw(addr) (*(volatile unsigned short *) __io_virt(addr)) |
||
71 | #define readl(addr) (*(volatile unsigned int *) __io_virt(addr)) |
||
72 | |||
73 | #define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b)) |
||
74 | #define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b)) |
||
75 | #define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b)) |
||
76 | |||
77 | __END_DECLS |
||
78 | #endif |