diff options
Diffstat (limited to 'arch/frv/lib')
-rw-r--r-- | arch/frv/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/frv/lib/__ucmpdi2.S | 45 | ||||
-rw-r--r-- | arch/frv/lib/checksum.c | 31 |
3 files changed, 71 insertions, 7 deletions
diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile index 19be2626d5e6..08be305c9f44 100644 --- a/arch/frv/lib/Makefile +++ b/arch/frv/lib/Makefile | |||
@@ -3,6 +3,6 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y := \ | 5 | lib-y := \ |
6 | __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o \ | 6 | __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \ |
7 | checksum.o memcpy.o memset.o atomic-ops.o \ | 7 | checksum.o memcpy.o memset.o atomic-ops.o \ |
8 | outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o | 8 | outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o |
diff --git a/arch/frv/lib/__ucmpdi2.S b/arch/frv/lib/__ucmpdi2.S new file mode 100644 index 000000000000..d892f16ffaa9 --- /dev/null +++ b/arch/frv/lib/__ucmpdi2.S | |||
@@ -0,0 +1,45 @@ | |||
1 | /* __ucmpdi2.S: 64-bit unsigned compare | ||
2 | * | ||
3 | * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | .text | ||
14 | .p2align 4 | ||
15 | |||
16 | ############################################################################### | ||
17 | # | ||
18 | # int __ucmpdi2(unsigned long long a [GR8:GR9], | ||
19 | # unsigned long long b [GR10:GR11]) | ||
20 | # | ||
21 | # - returns 0, 1, or 2 as a <, =, > b respectively. | ||
22 | # | ||
23 | ############################################################################### | ||
24 | .globl __ucmpdi2 | ||
25 | .type __ucmpdi2,@function | ||
26 | __ucmpdi2: | ||
27 | or.p gr8,gr0,gr4 | ||
28 | subcc gr8,gr10,gr0,icc0 | ||
29 | setlos.p #0,gr8 | ||
30 | bclr icc0,#2 ; a.msw < b.msw | ||
31 | |||
32 | setlos.p #2,gr8 | ||
33 | bhilr icc0,#0 ; a.msw > b.msw | ||
34 | |||
35 | subcc.p gr9,gr11,gr0,icc1 | ||
36 | setlos #0,gr8 | ||
37 | setlos.p #2,gr9 | ||
38 | setlos #1,gr7 | ||
39 | cknc icc1,cc6 | ||
40 | cor.p gr9,gr0,gr8, cc6,#1 | ||
41 | cckls icc1,cc4, cc6,#1 | ||
42 | andcr cc6,cc4,cc4 | ||
43 | cor gr7,gr0,gr8, cc4,#1 | ||
44 | bralr | ||
45 | .size __ucmpdi2, .-__ucmpdi2 | ||
diff --git a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c index 7bf5bd6cac8a..20e7dfc474ef 100644 --- a/arch/frv/lib/checksum.c +++ b/arch/frv/lib/checksum.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include <net/checksum.h> | 34 | #include <net/checksum.h> |
35 | #include <asm/checksum.h> | 35 | #include <asm/checksum.h> |
36 | #include <linux/module.h> | ||
36 | 37 | ||
37 | static inline unsigned short from32to16(unsigned long x) | 38 | static inline unsigned short from32to16(unsigned long x) |
38 | { | 39 | { |
@@ -115,34 +116,52 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) | |||
115 | return result; | 116 | return result; |
116 | } | 117 | } |
117 | 118 | ||
119 | EXPORT_SYMBOL(csum_partial); | ||
120 | |||
118 | /* | 121 | /* |
119 | * this routine is used for miscellaneous IP-like checksums, mainly | 122 | * this routine is used for miscellaneous IP-like checksums, mainly |
120 | * in icmp.c | 123 | * in icmp.c |
121 | */ | 124 | */ |
122 | unsigned short ip_compute_csum(const unsigned char * buff, int len) | 125 | unsigned short ip_compute_csum(const unsigned char * buff, int len) |
123 | { | 126 | { |
124 | return ~do_csum(buff,len); | 127 | return ~do_csum(buff, len); |
125 | } | 128 | } |
126 | 129 | ||
130 | EXPORT_SYMBOL(ip_compute_csum); | ||
131 | |||
127 | /* | 132 | /* |
128 | * copy from fs while checksumming, otherwise like csum_partial | 133 | * copy from fs while checksumming, otherwise like csum_partial |
129 | */ | 134 | */ |
130 | |||
131 | unsigned int | 135 | unsigned int |
132 | csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err) | 136 | csum_partial_copy_from_user(const char __user *src, char *dst, |
137 | int len, int sum, int *csum_err) | ||
133 | { | 138 | { |
134 | if (csum_err) *csum_err = 0; | 139 | int rem; |
135 | memcpy(dst, src, len); | 140 | |
141 | if (csum_err) | ||
142 | *csum_err = 0; | ||
143 | |||
144 | rem = copy_from_user(dst, src, len); | ||
145 | if (rem != 0) { | ||
146 | if (csum_err) | ||
147 | *csum_err = -EFAULT; | ||
148 | memset(dst + len - rem, 0, rem); | ||
149 | len = rem; | ||
150 | } | ||
151 | |||
136 | return csum_partial(dst, len, sum); | 152 | return csum_partial(dst, len, sum); |
137 | } | 153 | } |
138 | 154 | ||
155 | EXPORT_SYMBOL(csum_partial_copy_from_user); | ||
156 | |||
139 | /* | 157 | /* |
140 | * copy from ds while checksumming, otherwise like csum_partial | 158 | * copy from ds while checksumming, otherwise like csum_partial |
141 | */ | 159 | */ |
142 | |||
143 | unsigned int | 160 | unsigned int |
144 | csum_partial_copy(const char *src, char *dst, int len, int sum) | 161 | csum_partial_copy(const char *src, char *dst, int len, int sum) |
145 | { | 162 | { |
146 | memcpy(dst, src, len); | 163 | memcpy(dst, src, len); |
147 | return csum_partial(dst, len, sum); | 164 | return csum_partial(dst, len, sum); |
148 | } | 165 | } |
166 | |||
167 | EXPORT_SYMBOL(csum_partial_copy); | ||