1 /* 2 * mem_op.h 1.14 2001/08/24 12:16:13 3 * 4 * The contents of this file are subject to the Mozilla Public License 5 * Version 1.1 (the "License"); you may not use this file except in 6 * compliance with the License. You may obtain a copy of the License 7 * at http://www.mozilla.org/MPL/ 8 * 9 * Software distributed under the License is distributed on an "AS IS" 10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11 * the License for the specific language governing rights and 12 * limitations under the License. 13 * 14 * The initial developer of the original code is David A. Hinds 15 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 16 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 17 * 18 * Alternatively, the contents of this file may be used under the 19 * terms of the GNU General Public License version 2 (the "GPL"), in 20 * which case the provisions of the GPL are applicable instead of the 21 * above. If you wish to allow the use of your version of this file 22 * only under the terms of the GPL and not to allow others to use 23 * your version of this file under the MPL, indicate your decision by 24 * deleting the provisions above and replace them with the notice and 25 * other provisions required by the GPL. If you do not delete the 26 * provisions above, a recipient may use your version of this file 27 * under either the MPL or the GPL. 28 */ 29 30 #ifndef _LINUX_MEM_OP_H 31 #define _LINUX_MEM_OP_H 32 33 #include <asm/uaccess.h> 34 35 /* 36 If UNSAFE_MEMCPY is defined, we use the (optimized) system routines 37 to copy between a card and kernel memory. These routines do 32-bit 38 operations which may not work with all PCMCIA controllers. The 39 safe versions defined here will do only 8-bit and 16-bit accesses. 40 */ 41 42 #ifdef UNSAFE_MEMCPY 43 44 #define copy_from_pc memcpy_fromio 45 #define copy_to_pc memcpy_toio 46 47 static inline void copy_pc_to_user(void *to, const void *from, size_t n) 48 { 49 size_t odd = (n & 3); 50 n -= odd; 51 while (n) { 52 put_user(readl_ns(from), (int *)to); 53 (char *)from += 4; (char *)to += 4; n -= 4; 54 } 55 while (odd--) 56 put_user(readb((char *)from++), (char *)to++); 57 } 58 59 static inline void copy_user_to_pc(void *to, const void *from, size_t n) 60 { 61 int l; 62 char c; 63 size_t odd = (n & 3); 64 n -= odd; 65 while (n) { 66 get_user(l, (int *)from); 67 writel_ns(l, to); 68 (char *)to += 4; (char *)from += 4; n -= 4; 69 } 70 while (odd--) { 71 get_user(c, (char *)from++); 72 writeb(c, (char *)to++); 73 } 74 } 75 76 #else /* UNSAFE_MEMCPY */ 77 78 static inline void copy_from_pc(void *to, const void *from, size_t n) 79 { 80 size_t odd = (n & 1); 81 n -= odd; 82 while (n) { 83 *(u_short *)to = readw_ns(from); 84 (char *)to += 2; (char *)from += 2; n -= 2; 85 } 86 if (odd) 87 *(u_char *)to = readb(from); 88 } 89 90 static inline void copy_to_pc(void *to, const void *from, size_t n) 91 { 92 size_t odd = (n & 1); 93 n -= odd; 94 while (n) { 95 writew_ns(*(u_short *)from, to); 96 (char *)to += 2; (char *)from += 2; n -= 2; 97 } 98 if (odd) 99 writeb(*(u_char *)from, to); 100 } 101 102 static inline void copy_pc_to_user(void *to, const void *from, size_t n) 103 { 104 size_t odd = (n & 1); 105 n -= odd; 106 while (n) { 107 put_user(readw_ns(from), (short *)to); 108 (char *)to += 2; (char *)from += 2; n -= 2; 109 } 110 if (odd) 111 put_user(readb(from), (char *)to); 112 } 113 114 static inline void copy_user_to_pc(void *to, const void *from, size_t n) 115 { 116 short s; 117 char c; 118 size_t odd = (n & 1); 119 n -= odd; 120 while (n) { 121 get_user(s, (short *)from); 122 writew_ns(s, to); 123 (char *)to += 2; (char *)from += 2; n -= 2; 124 } 125 if (odd) { 126 get_user(c, (char *)from); 127 writeb(c, to); 128 } 129 } 130 131 #endif /* UNSAFE_MEMCPY */ 132 133 #endif /* _LINUX_MEM_OP_H */ 134