patch-2.1.36 linux/arch/m68k/lib/checksum.c
Next file: linux/arch/m68k/lib/semaphore.S
Previous file: linux/arch/m68k/kernel/traps.c
Back to the patch index
Back to the overall index
- Lines: 99
- Date:
Thu Apr 17 13:20:43 1997
- Orig file:
v2.1.35/linux/arch/m68k/lib/checksum.c
- Orig date:
Fri Jan 3 08:48:37 1997
diff -u --recursive --new-file v2.1.35/linux/arch/m68k/lib/checksum.c linux/arch/m68k/lib/checksum.c
@@ -19,8 +19,8 @@
* (%1). Thanks to Roman Hodek for pointing this out.
* B: GCC seems to mess up if one uses too many
* data-registers to hold input values and one tries to
- * specify d0 and d1 as scratch registers. Letting gcc choose these
- * registers itself solves the problem.
+ * specify d0 and d1 as scratch registers. Letting gcc
+ * choose these registers itself solves the problem.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -124,13 +124,20 @@
/*
- * copy from user space while checksumming, otherwise like csum_partial
+ * copy from user space while checksumming, with exception handling.
*/
unsigned int
-csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
+csum_partial_copy_from_user(const char *src, char *dst, int len,
+ int sum, int *csum_err)
{
+ /*
+ * GCC doesn't like more than 10 operands for the asm
+ * statements so we have to use tmp2 for the error
+ * code.
+ */
unsigned long tmp1, tmp2;
+
__asm__("movel %2,%4\n\t"
"btst #1,%4\n\t" /* Check alignment */
"jeq 2f\n\t"
@@ -226,27 +233,49 @@
"6:\t"
"addl %5,%0\n\t" /* now add rest long to sum */
"clrl %5\n\t"
- "addxl %5,%0\n" /* add X bit */
- "7:\n"
+ "addxl %5,%0\n\t" /* add X bit */
+ "7:\t"
+ "clrl %5\n" /* no error - clear return value */
+ "8:\n"
+ ".section .fixup,\"ax\"\n"
+ ".even\n"
+ "9:\t"
+ "moveq #-14,%5\n\t" /* -EFAULT, out of inputs to asm ;( */
+ "jra 8b\n"
+ ".previous\n"
".section __ex_table,\"a\"\n"
- ".long 10b,7b\n"
- ".long 11b,7b\n"
- ".long 12b,7b\n"
- ".long 13b,7b\n"
- ".long 14b,7b\n"
- ".long 15b,7b\n"
- ".long 16b,7b\n"
- ".long 17b,7b\n"
- ".long 18b,7b\n"
- ".long 19b,7b\n"
- ".long 20b,7b\n"
- ".long 21b,7b\n"
+ ".long 10b,9b\n"
+ ".long 11b,9b\n"
+ ".long 12b,9b\n"
+ ".long 13b,9b\n"
+ ".long 14b,9b\n"
+ ".long 15b,9b\n"
+ ".long 16b,9b\n"
+ ".long 17b,9b\n"
+ ".long 18b,9b\n"
+ ".long 19b,9b\n"
+ ".long 20b,9b\n"
+ ".long 21b,9b\n"
".previous"
: "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),
- "=&d" (tmp1), "=&d" (tmp2)
+ "=&d" (tmp1), "=d" (tmp2)
: "0" (sum), "1" (len), "2" (src), "3" (dst)
);
+
+ *csum_err = tmp2;
+
return(sum);
+}
+
+/*
+ * This one will go away soon.
+ */
+unsigned int
+csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
+{
+ int dummy;
+
+ return csum_partial_copy_from_user(src, dst, len, sum, &dummy);
}
/*
* copy from kernel space while checksumming, otherwise like csum_partial
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov