patch-1.3.7 linux/arch/i386/lib/checksum.c

Next file: linux/drivers/block/Makefile
Previous file: linux/arch/i386/config.in
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.6/linux/arch/i386/lib/checksum.c linux/arch/i386/lib/checksum.c
@@ -101,7 +101,7 @@
  * copy from fs while checksumming, otherwise like csum_partial
  */
 
-unsigned int csum_partial_copyffs( char *src, char *dst, 
+unsigned int csum_partial_copy_fromuser( char *src, char *dst, 
 				  int len, int sum) {
     __asm__("
 	testl $2, %%edi		# Check alignment.
@@ -175,15 +175,15 @@
 	jz 7f
 	cmpl $2, %%ecx
 	jb 5f
-	movw %%fs:(%%esi), %%dx
+	movw %%fs:(%%esi), %%cx
 	leal 2(%%esi), %%esi
-	movw %%dx, (%%edi)
+	movw %%cx, (%%edi)
 	leal 2(%%edi), %%edi
 	je 6f
 	shll $16,%%edx
-5:	movb %%fs:(%%esi), %%dl
-	movb %%dl, (%%edi)
-6:	addl %%edx, %%eax
+5:	movb %%fs:(%%esi), %%cl
+	movb %%cl, (%%edi)
+6:	addl %%ecx, %%eax
 	adcl $0, %%eax
 7:
 	"
@@ -192,6 +192,98 @@
 	: "bx", "cx", "dx", "si", "di" );
     return(sum);
 }
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
 
+unsigned int csum_partial_copy( char *src, char *dst, 
+				  int len, int sum) {
+    __asm__("
+	testl $2, %%edi		# Check alignment.
+	jz 2f			# Jump if alignment is ok.
+	subl $2, %%ecx		# Alignment uses up two bytes.
+	jae 1f			# Jump if we had at least two bytes.
+	addl $2, %%ecx		# ecx was < 2.  Deal with it.
+	jmp 4f
+1:	movw (%%esi), %%bx
+	addl $2, %%esi
+	movw %%bx, (%%edi)
+	addl $2, %%edi
+	addw %%bx, %%ax
+	adcl $0, %%eax
+2:
+	movl %%ecx, %%edx
+	shrl $5, %%ecx
+	jz 2f
+	testl %%esi, %%esi
+1:	movl (%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, (%%edi)
+
+	movl 4(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 4(%%edi)
+
+	movl 8(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 8(%%edi)
+
+	movl 12(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 12(%%edi)
 
+	movl 16(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 16(%%edi)
+
+	movl 20(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 20(%%edi)
+
+	movl 24(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 24(%%edi)
 
+	movl 28(%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, 28(%%edi)
+
+	lea 32(%%esi), %%esi
+	lea 32(%%edi), %%edi
+	dec %%ecx
+	jne 1b
+	adcl $0, %%eax
+2:	movl %%edx, %%ecx
+	andl $28, %%edx
+	je 4f
+	shrl $2, %%edx
+	testl %%esi, %%esi
+3:	movl (%%esi), %%ebx
+	adcl %%ebx, %%eax
+	movl %%ebx, (%%edi)
+	lea 4(%%esi), %%esi
+	lea 4(%%edi), %%edi
+	dec %%edx
+	jne 3b
+	adcl $0, %%eax
+4:	andl $3, %%ecx
+	jz 7f
+	cmpl $2, %%ecx
+	jb 5f
+	movw (%%esi), %%cx
+	leal 2(%%esi), %%esi
+	movw %%cx, (%%edi)
+	leal 2(%%edi), %%edi
+	je 6f
+	shll $16,%%edx
+5:	movb (%%esi), %%cl
+	movb %%cl, (%%edi)
+6:	addl %%ecx, %%eax
+	adcl $0, %%eax
+7:
+	"
+	: "=a" (sum)
+	: "0"(sum), "c"(len), "S"(src), "D" (dst)
+	: "bx", "cx", "dx", "si", "di" );
+    return(sum);
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this