diff options
Diffstat (limited to 'include/pcmcia/mem_op.h')
-rw-r--r-- | include/pcmcia/mem_op.h | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/include/pcmcia/mem_op.h b/include/pcmcia/mem_op.h new file mode 100644 index 000000000000..8d19b9401a5b --- /dev/null +++ b/include/pcmcia/mem_op.h | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * mem_op.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * The initial developer of the original code is David A. Hinds | ||
9 | * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | ||
10 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | ||
11 | * | ||
12 | * (C) 1999 David A. Hinds | ||
13 | */ | ||
14 | |||
15 | #ifndef _LINUX_MEM_OP_H | ||
16 | #define _LINUX_MEM_OP_H | ||
17 | |||
18 | #include <asm/uaccess.h> | ||
19 | #include <asm/io.h> | ||
20 | |||
21 | /* | ||
22 | If UNSAFE_MEMCPY is defined, we use the (optimized) system routines | ||
23 | to copy between a card and kernel memory. These routines do 32-bit | ||
24 | operations which may not work with all PCMCIA controllers. The | ||
25 | safe versions defined here will do only 8-bit and 16-bit accesses. | ||
26 | */ | ||
27 | |||
28 | #ifdef UNSAFE_MEMCPY | ||
29 | |||
30 | #define copy_from_pc memcpy_fromio | ||
31 | #define copy_to_pc memcpy_toio | ||
32 | |||
33 | static inline void copy_pc_to_user(void *to, const void *from, size_t n) | ||
34 | { | ||
35 | size_t odd = (n & 3); | ||
36 | n -= odd; | ||
37 | while (n) { | ||
38 | put_user(__raw_readl(from), (int *)to); | ||
39 | (char *)from += 4; (char *)to += 4; n -= 4; | ||
40 | } | ||
41 | while (odd--) | ||
42 | put_user(readb((char *)from++), (char *)to++); | ||
43 | } | ||
44 | |||
45 | static inline void copy_user_to_pc(void *to, const void *from, size_t n) | ||
46 | { | ||
47 | int l; | ||
48 | char c; | ||
49 | size_t odd = (n & 3); | ||
50 | n -= odd; | ||
51 | while (n) { | ||
52 | get_user(l, (int *)from); | ||
53 | __raw_writel(l, to); | ||
54 | (char *)to += 4; (char *)from += 4; n -= 4; | ||
55 | } | ||
56 | while (odd--) { | ||
57 | get_user(c, (char *)from++); | ||
58 | writeb(c, (char *)to++); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | #else /* UNSAFE_MEMCPY */ | ||
63 | |||
64 | static inline void copy_from_pc(void *to, void __iomem *from, size_t n) | ||
65 | { | ||
66 | __u16 *t = to; | ||
67 | __u16 __iomem *f = from; | ||
68 | size_t odd = (n & 1); | ||
69 | for (n >>= 1; n; n--) | ||
70 | *t++ = __raw_readw(f++); | ||
71 | if (odd) | ||
72 | *(__u8 *)t = readb(f); | ||
73 | } | ||
74 | |||
75 | static inline void copy_to_pc(void __iomem *to, const void *from, size_t n) | ||
76 | { | ||
77 | __u16 __iomem *t = to; | ||
78 | const __u16 *f = from; | ||
79 | size_t odd = (n & 1); | ||
80 | for (n >>= 1; n ; n--) | ||
81 | __raw_writew(*f++, t++); | ||
82 | if (odd) | ||
83 | writeb(*(__u8 *)f, t); | ||
84 | } | ||
85 | |||
86 | static inline void copy_pc_to_user(void __user *to, void __iomem *from, size_t n) | ||
87 | { | ||
88 | __u16 __user *t = to; | ||
89 | __u16 __iomem *f = from; | ||
90 | size_t odd = (n & 1); | ||
91 | for (n >>= 1; n ; n--) | ||
92 | put_user(__raw_readw(f++), t++); | ||
93 | if (odd) | ||
94 | put_user(readb(f), (char __user *)t); | ||
95 | } | ||
96 | |||
97 | static inline void copy_user_to_pc(void __iomem *to, void __user *from, size_t n) | ||
98 | { | ||
99 | __u16 __user *f = from; | ||
100 | __u16 __iomem *t = to; | ||
101 | short s; | ||
102 | char c; | ||
103 | size_t odd = (n & 1); | ||
104 | for (n >>= 1; n; n--) { | ||
105 | get_user(s, f++); | ||
106 | __raw_writew(s, t++); | ||
107 | } | ||
108 | if (odd) { | ||
109 | get_user(c, (char __user *)f); | ||
110 | writeb(c, t); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | #endif /* UNSAFE_MEMCPY */ | ||
115 | |||
116 | #endif /* _LINUX_MEM_OP_H */ | ||