diff -u --recursive --new-file v2.1.25/linux/CREDITS linux/CREDITS --- v2.1.25/linux/CREDITS Thu Feb 6 12:41:58 1997 +++ linux/CREDITS Thu Feb 6 14:57:24 1997 @@ -960,11 +960,8 @@ S: LS2 7PS, UK N: Craig Metz -E: cmetz@tjhsst.edu -D: Some of PAS 16 mixer & PCM support -S: 12305 Country Ridge Lane -S: Fairfax, Virginia 22033 -S: USA +E: cmetz@inner.net +D: Some of PAS 16 mixer & PCM support, inet6-apps N: William (Bill) Metzenthen E: billm@suburbia.net @@ -1099,6 +1096,10 @@ S: Albuquerque, NM 87131 S: USA +N: David Parsons +E: orc@pell.chi.il.us +D: improved memory detection code. + N: Avery Pennarun E: apenwarr@foxnet.net D: ARCnet driver @@ -1384,9 +1385,9 @@ W: http://www.cs.helsinki.fi/~torvalds/ P: 1024/A86B35C5 96 54 50 29 EC 11 44 7A BE 67 3C 24 03 13 62 C8 D: Original kernel hacker -S: Kalevankatu 55 B 37 -S: 00180 Helsinki -S: Finland +S: 3665 Benton Street #36 +S: Santa Clara, California 95051 +S: USA N: Jeff Tranter E: Jeff_Tranter@Mitel.COM diff -u --recursive --new-file v2.1.25/linux/Documentation/Changes linux/Documentation/Changes --- v2.1.25/linux/Documentation/Changes Thu Jan 23 21:06:45 1997 +++ linux/Documentation/Changes Mon Feb 3 13:06:10 1997 @@ -19,7 +19,14 @@ generated by texinfo so a diff is useless anyway (though I can incorporate one by hand if you insist upon sending it that way ;-). -Last updated: January 9, 1997. + Check out http://www.cviog.uga.edu/Misc/info/LinuxBleed.html for an +HTML-ized shopping list. + + For those of you in Europe, +http://www.datanet.hu/generations/linux/Changes2.html is an +English-language HTML version. + +Last updated: January 29, 1997. Current Author: Chris Ricker (gt1355b@prism.gatech.edu). Current Minimal Requirements @@ -28,7 +35,7 @@ Upgrade to at *least* these software revisions before thinking you've encountered a bug! -- Kernel modules modutils-970104 +- Kernel modules modutils-2.1.23 - Gnu C 2.7.2.1 - Binutils 2.7.0.3 - Linux C Library 5.4.17 @@ -39,6 +46,7 @@ - Mount 2.5p - Net-tools 1.32-alpha - Kbd 0.91 +- Loadlin 1.6a Upgrade notes ************* @@ -49,8 +57,8 @@ now performs a cold reboot instead of a warm reboot for increased hardware compatibility. If you want a warm reboot and know it works on your hardware, add a "reboot=warm" command line option -in Lilo. A small number of machines need "reboot=bios" to reboot via the -BIOS. +in Lilo. A small number of machines need "reboot=bios" to reboot via +the BIOS. Libc ==== @@ -75,7 +83,7 @@ Modules ======= - You need to upgrade to modutils-970104 for kernels 2.1.8 and later. + You need to upgrade to modutils-2.1.23 for kernels 2.1.18 and later. Gnu C ===== @@ -120,7 +128,13 @@ ====== A new "stable" version of DOSEMU is available for 2.1.x kernels. -Upgrade to 0.64.2 or later. +Upgrade to 0.64.3 or later. + +Loadlin +======= + + Linux 2.1.22 and later releases use a new method of memory size +detection, requiring loadlin users to upgrade to loadlin-1.6a. How to know the version of the installed programs ************************************************* @@ -132,15 +146,14 @@ Binutils: ld -v Gnu C: gcc -v or gcc --version Kbd: loadkeys -h -Ld.so: ldd -v +Ld.so: ldd -v Libc: ls -l /lib/libc.so.* Libc++: ls -l /usr/lib/libg++.so.* -modules: /sbin/insmod -V -mount: mount --version -procps: ps --version -SysVinit: (must be logged in as root) - strings `egrep -li INIT_VERSION=sysvinit- /proc/*/environ | head -1` | \ - egrep -i INIT_VERSION=sysvinit- +Modutils: insmod -V +Mount: mount --version +Procps: ps --version +SysVinit: strings `egrep -li INIT_VERSION=sysvinit- /proc/*/environ | head +-1` | egrep -i INIT_VERSION=sysvinit- RPM: rpm --version Where to get the files @@ -196,8 +209,9 @@ Modules utilities ================= -The 970104 release: -ftp://ftp.redhat.com/pub/alphabits/modutils-970104.tar.gz +The 2.1.23 release: +ftp://tsx-11.mit.edu/pub/linux/sources/system/v2.1/modutils-2.1.23.tar.gz +ftp://sunsite.unc.edu/pub/Linux/kernel/v2.1/modutils-2.1.23.tar.gz Procps utilities ================ @@ -229,9 +243,16 @@ DOSEMU ====== -The 0.64.2 release: -ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu0.64.2.tgz -ftp://sunsite.unc.edu/pub/Linux/system/Emulators/dosemu0.64.2.tgz +The 0.64.3.1 release: +ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu0.64.3.1.tgz +ftp://sunsite.unc.edu/pub/Linux/system/Emulators/dosemu0.64.3.1.tgz + +Loadlin +======= + +The 1.6a release: +ftp://ftp.suse.com/pub/loadlin/update-1.6a/loadlin.exe.gz +ftp://elserv.ffm.fgan.de/pub/linux/loadlin-1.6/update-1.6a/loadlin.exe.gz Other Info ========== diff -u --recursive --new-file v2.1.25/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.25/linux/Documentation/Configure.help Thu Feb 6 12:41:58 1997 +++ linux/Documentation/Configure.help Tue Feb 4 16:44:24 1997 @@ -2364,17 +2364,17 @@ distances with data transfer rates significantly higher than those achievable with commonly used asynchronous modem connections. Usually, a quite expensive external device called `WAN router' is - needed to connect to WAN. - As an alternative, WAN router can be build into Linux kernel. + needed to connect to a WAN. + As an alternative, WAN routing can be built into the Linux kernel. With relatively inexpensive WAN interface cards available on the - market, a perfectly usable router can be built for less than half a + market, a perfectly usable router can be built for less than half the price of an external router. If you have one of those cards (with appropriate WAN Link Driver) and wish to use your Linux box as a WAN router, you may say 'Y' to this option. You will also need a wan-tools package available via FTP (user: anonymous) from ftp.sangoma.com. Read Documentation/networking/wan-router.txt for more information. - WAN router is always built as a module ( = code which can be + WAN routing is always built as a module ( = code which can be inserted in and removed from the running kernel whenever you want). For general information about modules read Documentation/modules.txt. @@ -2390,7 +2390,7 @@ Sangoma WANPIPE(tm) multiprotocol cards CONFIG_VENDOR_SANGOMA WANPIPE from Sangoma Technologies Inc. (http://www.sangoma.com) - is a family of intelligent multiprotocol WAN adapter with data + is a family of intelligent multiprotocol WAN adapters with data transfer rates up to T1 (1.544 Mbps). They are also known as Synchronous Data Link Adapters (SDLA) and designated S502E(A), S503 or S508. If you have one of these cards, say 'Y' to this option. diff -u --recursive --new-file v2.1.25/linux/MAINTAINERS linux/MAINTAINERS --- v2.1.25/linux/MAINTAINERS Thu Feb 6 12:41:59 1997 +++ linux/MAINTAINERS Fri Feb 7 15:54:53 1997 @@ -351,6 +351,11 @@ M: boldt@math.ucsb.edu S: Maintained +PCI ID DATABASE +P: Jens Maurer +M: jmaurer@cck.uni-kl.de +S: Maintained + LANCE AND LANCE32 NETWORK DRIVER P: Thomas Bogendoerfer M: tsbogend@bigbug.franken.de diff -u --recursive --new-file v2.1.25/linux/Makefile linux/Makefile --- v2.1.25/linux/Makefile Thu Feb 6 12:41:59 1997 +++ linux/Makefile Fri Feb 7 16:30:55 1997 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 25 +SUBLEVEL = 26 ARCH = i386 diff -u --recursive --new-file v2.1.25/linux/arch/alpha/Makefile linux/arch/alpha/Makefile --- v2.1.25/linux/arch/alpha/Makefile Sun Aug 4 13:37:59 1996 +++ linux/arch/alpha/Makefile Thu Feb 6 14:42:34 1997 @@ -24,7 +24,7 @@ CFLAGS := $(CFLAGS) -pipe endif -CFLAGS := $(CFLAGS) -mno-fp-regs +CFLAGS := $(CFLAGS) -mno-fp-regs -ffixed-8 HEAD := arch/alpha/kernel/head.o diff -u --recursive --new-file v2.1.25/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S --- v2.1.25/linux/arch/alpha/kernel/entry.S Tue Jan 28 18:49:45 1997 +++ linux/arch/alpha/kernel/entry.S Thu Feb 6 14:42:35 1997 @@ -127,8 +127,8 @@ addq $1,1,$1 stq $1,0($0) /* set up the arguments to the C interrupt handler */ - lda $27,do_entInt - jsr $26,($27),do_entInt + ldq $8,current_set + jsr $26,do_entInt /* ok, return */ lda $0,intr_count ldq $1,0($0) @@ -153,6 +153,7 @@ stq $15,48($30) addq $30,56,$19 /* handle the fault */ + ldq $8,current_set jsr $26,do_page_fault /* reload the registers after the exception code played. */ ldq $9,0($30) @@ -172,6 +173,9 @@ .ent entArith entArith: SAVE_ALL + ldq $8,current_set + /* How much of a win is this clockwise? We are, after all, messing + up the call/return prefetch stack. -- rth */ lda $27,do_entArith lda $26,ret_from_sys_call jsr $31,($27),do_entArith @@ -182,6 +186,7 @@ .ent entIF entIF: SAVE_ALL + ldq $8,current_set lda $27,do_entIF lda $26,ret_from_sys_call jsr $31,($27),do_entIF @@ -210,8 +215,7 @@ stq $18,40($30) bis $31,2,$0 /* Register v0: syscall nr for fork() */ SAVE_ALL - lda $27,sys_clone - jsr $26,($27),sys_clone + jsr $26,sys_clone stq $0,0($30) br $31,ret_from_sys_call .end kernel_clone @@ -240,11 +244,13 @@ ret $31,($26),1 /* this is in child: look out as we don't have any stack here.. */ 1: bis $9,$9,$27 /* get fn */ + br $29,2f +2: ldgp $29,0($29) bis $10,$10,$16 /* get arg */ + ldq $8,current_set jsr $26,($27) bis $0,$0,$16 - lda $27,sys_exit - jsr $26,($27),sys_exit + jsr $26,sys_exit call_pal PAL_halt .end __kernel_thread @@ -382,8 +388,8 @@ stq $29,232($30) stq $30,240($30) stq $31,248($30) - lda $27,do_entUna - jsr $26,($27),do_entUna + ldq $8,current_set + jsr $26,do_entUna ldq $0,0($30) ldq $1,8($30) ldq $2,16($30) @@ -431,9 +437,9 @@ stq $13,32($30) stq $14,40($30) stq $15,48($30) - lda $27,do_entUnaUser bis $31,$30,$19 - jsr $26,($27),do_entUnaUser + ldq $8,current_set + jsr $26,do_entUnaUser ldq $9,0($30) ldq $10,8($30) ldq $11,16($30) @@ -457,8 +463,7 @@ bis $31,SIGCHLD,$16 bis $31,$31,$17 bis $30,$30,$18 - lda $27,alpha_clone - jsr $26,($27),alpha_clone + jsr $26,alpha_clone bsr $1,undo_switch_stack ret $31,($26),1 .end sys_fork @@ -470,8 +475,7 @@ bsr $1,do_switch_stack /* arg1 and arg2 come from the user */ bis $30,$30,$18 - lda $27,alpha_clone - jsr $26,($27),alpha_clone + jsr $26,alpha_clone bsr $1,undo_switch_stack ret $31,($26),1 .end sys_clone @@ -499,14 +503,13 @@ .ent entSys entSys: SAVE_ALL - lda $1,current_set + ldq $8,current_set lda $4,NR_SYSCALLS($31) stq $16,SP_OFF+24($30) lda $5,sys_call_table - ldq $2,0($1) lda $27,do_entSys cmpult $0,$4,$4 - ldq $3,TASK_FLAGS($2) + ldq $3,TASK_FLAGS($8) stq $17,SP_OFF+32($30) s8addq $0,$5,$5 and $3,PF_PTRACED,$3 @@ -539,15 +542,13 @@ beq $0,restore_all ret_from_reschedule: lda $0,need_resched - lda $1,current_set ldl $2,0($0) lda $4,init_task - ldq $3,0($1) bne $2,reschedule - subq $4,$3,$4 + xor $4,$8,$4 beq $4,restore_all - ldq $4,TASK_SIGNAL($3) - ldq $16,TASK_BLOCKED($3) + ldq $4,TASK_SIGNAL($8) + ldq $16,TASK_BLOCKED($8) bic $4,$16,$4 bne $4,signal_return restore_all: @@ -560,8 +561,7 @@ strace: /* set up signal stack, call syscall_trace */ bsr $1,do_switch_stack - lda $27,syscall_trace - jsr $26,($27),syscall_trace + jsr $26,syscall_trace bsr $1,undo_switch_stack /* get the system call number and the arguments back.. */ @@ -590,8 +590,7 @@ stq $0,0($30) /* save return value */ bsr $1,do_switch_stack - lda $27,syscall_trace - jsr $26,($27),syscall_trace + jsr $26,syscall_trace bsr $1,undo_switch_stack br $31,ret_from_sys_call @@ -609,8 +608,7 @@ bsr $1,do_switch_stack bis $19,$19,$9 /* save old syscall number */ bis $20,$20,$10 /* save old a3 */ - lda $27,syscall_trace - jsr $26,($27),syscall_trace + jsr $26,syscall_trace bis $9,$9,$19 bis $10,$10,$20 bsr $1,undo_switch_stack @@ -628,8 +626,7 @@ subq $30,16,$30 stq $19,0($30) /* save syscall nr */ stq $20,8($30) /* and error indication (a3) */ - lda $27,do_bottom_half - jsr $26,($27),do_bottom_half + jsr $26,do_bottom_half lda $0,intr_count ldq $19,0($30) ldq $20,8($30) @@ -667,8 +664,7 @@ bis $30,$30,$17 br $1,do_switch_stack bis $30,$30,$18 - lda $27,do_signal - jsr $26,($27),do_signal + jsr $26,do_signal lda $30,SWITCH_STACK_SIZE($30) br $31,restore_all .end entSys @@ -679,8 +675,7 @@ subq $30,16,$30 stq $19,0($30) /* save syscall nr */ stq $20,8($30) /* and error indication (a3) */ - lda $27,schedule - jsr $26,($27),schedule + jsr $26,schedule ldq $19,0($30) ldq $20,8($30) addq $30,16,$30 @@ -693,8 +688,7 @@ bis $30,$30,$17 lda $30,-SWITCH_STACK_SIZE($30) bis $30,$30,$18 - lda $27,do_sigreturn - jsr $26,($27),do_sigreturn + jsr $26,do_sigreturn br $1,undo_switch_stack br $31,ret_from_sys_call .end sys_sigreturn @@ -705,8 +699,7 @@ bis $30,$30,$17 br $1,do_switch_stack bis $30,$30,$18 - lda $27,do_sigsuspend - jsr $26,($27),do_sigsuspend + jsr $26,do_sigsuspend lda $30,SWITCH_STACK_SIZE($30) br $31,ret_from_sys_call .end sys_sigsuspend diff -u --recursive --new-file v2.1.25/linux/arch/alpha/kernel/head.S linux/arch/alpha/kernel/head.S --- v2.1.25/linux/arch/alpha/kernel/head.S Sat Oct 19 10:07:28 1996 +++ linux/arch/alpha/kernel/head.S Thu Feb 6 14:42:35 1997 @@ -23,8 +23,11 @@ __start: br $27,1f 1: ldgp $29,0($27) - lda $27,start_kernel - jsr $26,($27),start_kernel + /* We need to get current loaded up with our first task. */ + lda $8,init_task + stq $8,current_set + /* And then we can start the kernel. */ + jsr $26,start_kernel halt .end __start diff -u --recursive --new-file v2.1.25/linux/arch/alpha/lib/copy_user.S linux/arch/alpha/lib/copy_user.S --- v2.1.25/linux/arch/alpha/lib/copy_user.S Wed Jan 15 19:45:39 1997 +++ linux/arch/alpha/lib/copy_user.S Thu Feb 6 14:42:35 1997 @@ -17,7 +17,6 @@ * length in $0 * destination address in $6 * source address in $7 - * exception pointer in $8 * return address in $28 * * Outputs: diff -u --recursive --new-file v2.1.25/linux/arch/alpha/lib/csum_ipv6_magic.S linux/arch/alpha/lib/csum_ipv6_magic.S --- v2.1.25/linux/arch/alpha/lib/csum_ipv6_magic.S Tue Nov 12 15:56:02 1996 +++ linux/arch/alpha/lib/csum_ipv6_magic.S Thu Feb 6 12:44:41 1997 @@ -61,8 +61,8 @@ extwl $0,2,$1 # e0 : zapnot $0,3,$0 # .. e1 : addq $0,$1,$0 # e0 : - unop # : - not $0,$0 # e0 : + not $0,$0 # e1 : + zapnot $0,3,$0 # e0 : ret # .. e1 : .end csum_ipv6_magic diff -u --recursive --new-file v2.1.25/linux/arch/alpha/lib/csum_partial_copy.c linux/arch/alpha/lib/csum_partial_copy.c --- v2.1.25/linux/arch/alpha/lib/csum_partial_copy.c Wed Jul 17 14:39:21 1996 +++ linux/arch/alpha/lib/csum_partial_copy.c Thu Feb 6 12:44:41 1997 @@ -7,6 +7,11 @@ * we do for performance.. */ +#include +#include +#include + + #define ldq_u(x,y) \ __asm__ __volatile__("ldq_u %0,%1":"=r" (x):"m" (*(unsigned long *)(y))) @@ -31,17 +36,52 @@ #define insqh(x,y,z) \ __asm__ __volatile__("insqh %1,%2,%0":"=r" (z):"r" (x),"r" (y)) + +#define __get_user_u(x,ptr) \ +({ \ + long __guu_err; \ + __asm__ __volatile__( \ + "1: ldq_u %0,%2\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0,2b-1b(%1)\n" \ + ".previous" \ + : "=r"(x), "=r"(__guu_err) \ + : "m"(__m(ptr)), "1"(0)); \ + __guu_err; \ +}) + +#define __put_user_u(x,ptr) \ +({ \ + long __puu_err; \ + __asm__ __volatile__( \ + "1: stq_u %2,%1\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b" \ + " lda $31,2b-1b(%0)\n" \ + ".previous" \ + : "=r"(__puu_err) \ + : "m"(__m(addr)), "rJ"(x), "0"(0)); \ + __puu_err; \ +}) + + /* * Ok. This isn't fun, but this is the EASY case. */ -static inline unsigned long csum_partial_copy_aligned( - unsigned long *src, unsigned long *dst, - long len, unsigned long checksum) +static inline unsigned long +csum_partial_cfu_aligned(unsigned long *src, unsigned long *dst, + long len, unsigned long checksum, + int *errp) { unsigned long carry = 0; + int err = 0; while (len >= 0) { - unsigned long word = *src; + unsigned long word; + err |= __get_user(word, src); checksum += carry; src++; checksum += word; @@ -54,7 +94,7 @@ checksum += carry; if (len) { unsigned long word, tmp; - word = *src; + err |= __get_user(word, src); tmp = *dst; mskql(word, len, word); checksum += word; @@ -63,28 +103,31 @@ *dst = word | tmp; checksum += carry; } - return checksum; + if (err) *errp = err; + return checksum; } /* * This is even less fun, but this is still reasonably * easy. */ -static inline unsigned long csum_partial_copy_dest_aligned( - unsigned long *src, unsigned long *dst, - unsigned long soff, - long len, unsigned long checksum) +static inline unsigned long +csum_partial_cfu_dest_aligned(unsigned long *src, unsigned long *dst, + unsigned long soff, + long len, unsigned long checksum, + int *errp) { unsigned long first; unsigned long word, carry; unsigned long lastsrc = 7+len+(unsigned long)src; + int err = 0; - ldq_u(first,src); + err |= __get_user_u(first,src); carry = 0; while (len >= 0) { unsigned long second; - ldq_u(second, src+1); + err |= __get_user_u(second, src+1); extql(first, soff, word); len -= 8; src++; @@ -102,7 +145,7 @@ if (len) { unsigned long tmp; unsigned long second; - ldq_u(second, lastsrc); + err |= __get_user_u(second, lastsrc); tmp = *dst; extql(first, soff, word); extqh(second, soff, first); @@ -114,25 +157,28 @@ *dst = word | tmp; checksum += carry; } + if (err) *errp = err; return checksum; } /* * This is slightly less fun than the above.. */ -static inline unsigned long csum_partial_copy_src_aligned( - unsigned long *src, unsigned long *dst, - unsigned long doff, - long len, unsigned long checksum, - unsigned long partial_dest) +static inline unsigned long +csum_partial_cfu_src_aligned(unsigned long *src, unsigned long *dst, + unsigned long doff, + long len, unsigned long checksum, + unsigned long partial_dest, + int *errp) { unsigned long carry = 0; unsigned long word; + int err = 0; mskql(partial_dest, doff, partial_dest); while (len >= 0) { unsigned long second_dest; - word = *src; + err |= __get_user(word, src); len -= 8; insql(word, doff, second_dest); checksum += carry; @@ -147,7 +193,7 @@ checksum += carry; if (len >= 0) { unsigned long second_dest; - word = *src; + err |= __get_user(word, src); mskql(word, len-doff, word); checksum += word; insql(word, doff, second_dest); @@ -162,7 +208,7 @@ checksum += carry; } else if (len & 7) { unsigned long second_dest; - word = *src; + err |= __get_user(word, src); ldq_u(second_dest, dst); mskql(word, len-doff, word); checksum += word; @@ -172,6 +218,7 @@ stq_u(partial_dest | word | second_dest, dst); checksum += carry; } + if (err) *errp = err; return checksum; } @@ -179,24 +226,26 @@ * This is so totally un-fun that it's frightening. Don't * look at this too closely, you'll go blind. */ -static inline unsigned long csum_partial_copy_unaligned( - unsigned long * src, unsigned long * dst, - unsigned long soff, unsigned long doff, - long len, unsigned long checksum, - unsigned long partial_dest) +static inline unsigned long +csum_partial_cfu_unaligned(unsigned long * src, unsigned long * dst, + unsigned long soff, unsigned long doff, + long len, unsigned long checksum, + unsigned long partial_dest, + int *errp) { unsigned long carry = 0; unsigned long first; unsigned long lastsrc; + int err = 0; - ldq_u(first, src); + err |= __get_user_u(first, src); lastsrc = 7+len+(unsigned long)src; mskql(partial_dest, doff, partial_dest); while (len >= 0) { unsigned long second, word; unsigned long second_dest; - ldq_u(second, src+1); + err |= __get_user_u(second, src+1); extql(first, soff, word); checksum += carry; len -= 8; @@ -216,8 +265,8 @@ if (len >= 0) { unsigned long second, word; unsigned long second_dest; - - ldq_u(second, lastsrc); + + err |= __get_user_u(second, lastsrc); extql(first, soff, word); extqh(second, soff, first); word |= first; @@ -233,12 +282,12 @@ mskqh(second_dest, len, second_dest); stq_u(partial_dest | second_dest, dst+1); } - checksum += carry; + checksum += carry; } else if (len & 7) { unsigned long second, word; unsigned long second_dest; - ldq_u(second, lastsrc); + err |= __get_user_u(second, lastsrc); extql(first, soff, word); extqh(second, soff, first); word |= first; @@ -251,42 +300,51 @@ stq_u(partial_dest | word | second_dest, dst); checksum += carry; } + if (err) *errp = err; return checksum; } -unsigned int csum_partial_copy(char *src, char *dst, int len, int sum) +unsigned int +csum_partial_copy_from_user(int *errp, char *src, char *dst, + int len, unsigned int sum) { unsigned long checksum = (unsigned) sum; unsigned long soff = 7 & (unsigned long) src; unsigned long doff = 7 & (unsigned long) dst; + if (!access_ok(src, len, VERIFY_READ)) { + *errp = -EFAULT; + memset(dst, 0, len); + return checksum; + } + if (len) { if (!doff) { if (!soff) - checksum = csum_partial_copy_aligned( + checksum = csum_partial_cfu_aligned( (unsigned long *) src, (unsigned long *) dst, - len-8, checksum); + len-8, checksum, errp); else - checksum = csum_partial_copy_dest_aligned( + checksum = csum_partial_cfu_dest_aligned( (unsigned long *) src, (unsigned long *) dst, - soff, len-8, checksum); + soff, len-8, checksum, errp); } else { unsigned long partial_dest; ldq_u(partial_dest, dst); if (!soff) - checksum = csum_partial_copy_src_aligned( + checksum = csum_partial_cfu_src_aligned( (unsigned long *) src, (unsigned long *) dst, doff, len-8, checksum, - partial_dest); + partial_dest, errp); else - checksum = csum_partial_copy_unaligned( + checksum = csum_partial_cfu_unaligned( (unsigned long *) src, (unsigned long *) dst, soff, doff, len-8, checksum, - partial_dest); + partial_dest, errp); } /* 64 -> 33 bits */ checksum = (checksum & 0xffffffff) + (checksum >> 32); @@ -297,4 +355,17 @@ checksum = (checksum & 0xffff) + (checksum >> 16); } return checksum; +} + +unsigned int +csum_partial_copy (const char *src, char *dst, int len, unsigned int sum) +{ + unsigned int ret; + int error = 0; + + ret = csum_partial_copy_from_user(&error, src, dst, len, sum); + if (error) + printk("csum_partial_copy_old(): tell mingo to convert me!\n"); + + return ret; } diff -u --recursive --new-file v2.1.25/linux/arch/alpha/lib/strncat.S linux/arch/alpha/lib/strncat.S --- v2.1.25/linux/arch/alpha/lib/strncat.S Sat Oct 19 10:07:28 1996 +++ linux/arch/alpha/lib/strncat.S Thu Feb 6 14:42:35 1997 @@ -56,11 +56,11 @@ /* Worry about the null termination. */ - zapnot $1, $22, $2 # was last byte a null? + zapnot $1, $27, $2 # was last byte a null? bne $2, 0f ret -0: cmplt $22, $24, $2 # did we fill the buffer completely? +0: cmplt $27, $24, $2 # did we fill the buffer completely? or $2, $18, $2 bne $2, 2f diff -u --recursive --new-file v2.1.25/linux/arch/alpha/lib/strncpy_from_user.S linux/arch/alpha/lib/strncpy_from_user.S --- v2.1.25/linux/arch/alpha/lib/strncpy_from_user.S Wed Jan 15 19:45:39 1997 +++ linux/arch/alpha/lib/strncpy_from_user.S Thu Feb 6 14:48:45 1997 @@ -44,10 +44,10 @@ mskqh t1, a1, t3 # e0 : ornot t1, t2, t2 # .. e1 : mskql t0, a1, t0 # e0 : assemble the first output word - cmpbge zero, t2, t7 # .. e1 : bits set iff null found + cmpbge zero, t2, t8 # .. e1 : bits set iff null found or t0, t3, t0 # e0 : beq a2, $a_eoc # .. e1 : - bne t7, $a_eos # .. e1 : + bne t8, $a_eos # .. e1 : /* On entry to this basic block: t0 == a source word not containing a null. */ @@ -58,34 +58,34 @@ EX( ldq_u t0, 0(a1) ) # e0 : addq a1, 8, a1 # .. e1 : subq a2, 1, a2 # e0 : - cmpbge zero, t0, t7 # .. e1 (stall) + cmpbge zero, t0, t8 # .. e1 (stall) beq a2, $a_eoc # e1 : - beq t7, $a_loop # e1 : + beq t8, $a_loop # e1 : /* Take care of the final (partial) word store. At this point - the end-of-count bit is set in t7 iff it applies. + the end-of-count bit is set in t8 iff it applies. On entry to this basic block we have: t0 == the source word containing the null - t7 == the cmpbge mask that found it. */ + t8 == the cmpbge mask that found it. */ $a_eos: - negq t7, t8 # e0 : find low bit set - and t7, t8, t8 # e1 (stall) + negq t8, t12 # e0 : find low bit set + and t8, t12, t12 # e1 (stall) /* For the sake of the cache, don't read a destination word if we're not going to need it. */ - and t8, 0x80, t6 # e0 : + and t12, 0x80, t6 # e0 : bne t6, 1f # .. e1 (zdb) /* We're doing a partial word store and so need to combine our source and original destination words. */ ldq_u t1, 0(a0) # e0 : - subq t8, 1, t6 # .. e1 : - or t8, t6, t7 # e0 : + subq t12, 1, t6 # .. e1 : + or t12, t6, t8 # e0 : unop # - zapnot t0, t7, t0 # e0 : clear src bytes > null - zap t1, t7, t1 # .. e1 : clear dst bytes <= null + zapnot t0, t8, t0 # e0 : clear src bytes > null + zap t1, t8, t1 # .. e1 : clear dst bytes <= null or t0, t1, t0 # e1 : 1: stq_u t0, 0(a0) @@ -93,7 +93,7 @@ /* Add the end-of-count bit to the eos detection bitmask. */ $a_eoc: - or t10, t7, t7 + or t10, t8, t8 br $a_eos /*** The Function Entry Point ***/ @@ -148,18 +148,18 @@ mskqh t1, a0, t1 # e0 : mask leading garbage in src or t0, t1, t0 # e0 : first output word complete or t0, t6, t6 # e1 : mask original data for zero test - cmpbge zero, t6, t7 # e0 : + cmpbge zero, t6, t8 # e0 : beq a2, $u_eocfin # .. e1 : - bne t7, $u_final # e1 : + bne t8, $u_final # e1 : lda t6, -1 # e1 : mask out the bits we have mskql t6, a1, t6 # e0 : already seen stq_u t0, 0(a0) # e0 : store first output word or t6, t2, t2 # .. e1 : - cmpbge zero, t2, t7 # e0 : find nulls in second partial + cmpbge zero, t2, t8 # e0 : find nulls in second partial addq a0, 8, a0 # .. e1 : subq a2, 1, a2 # e0 : - bne t7, $u_late_head_exit # .. e1 : + bne t8, $u_late_head_exit # .. e1 : /* Finally, we've got all the stupid leading edge cases taken care of and we can set up to enter the main loop. */ @@ -167,9 +167,9 @@ extql t2, a1, t1 # e0 : position hi-bits of lo word EX( ldq_u t2, 8(a1) ) # .. e1 : read next high-order source word addq a1, 8, a1 # e0 : - cmpbge zero, t2, t7 # e1 (stall) + cmpbge zero, t2, t8 # e1 (stall) beq a2, $u_eoc # e1 : - bne t7, $u_eos # e1 : + bne t8, $u_eos # e1 : /* Unaligned copy main loop. In order to avoid reading too much, the loop is structured to detect zeros in aligned source words. @@ -195,9 +195,9 @@ stq_u t0, -8(a0) # e0 : save the current word mov t3, t1 # .. e1 : subq a2, 1, a2 # e0 : - cmpbge zero, t2, t7 # .. e1 : test new word for eos + cmpbge zero, t2, t8 # .. e1 : test new word for eos beq a2, $u_eoc # e1 : - beq t7, $u_loop # e1 : + beq t8, $u_loop # e1 : /* We've found a zero somewhere in the source word we just read. If it resides in the lower half, we have one (probably partial) @@ -211,8 +211,8 @@ extqh t2, a1, t0 # e0 : or t0, t1, t0 # e1 : first (partial) source word complete - cmpbge zero, t0, t7 # e0 : is the null in this first bit? - bne t7, $u_final # .. e1 (zdb) + cmpbge zero, t0, t8 # e0 : is the null in this first bit? + bne t8, $u_final # .. e1 (zdb) stq_u t0, 0(a0) # e0 : the null was in the high-order bits addq a0, 8, a0 # .. e1 : @@ -220,27 +220,27 @@ $u_late_head_exit: extql t2, a1, t0 # .. e0 : - cmpbge zero, t0, t7 # e0 : - or t7, t10, t6 # e1 : - cmoveq a2, t6, t7 # e0 : + cmpbge zero, t0, t8 # e0 : + or t8, t10, t6 # e1 : + cmoveq a2, t6, t8 # e0 : nop # .. e1 : /* Take care of a final (probably partial) result word. On entry to this basic block: t0 == assembled source word - t7 == cmpbge mask that found the null. */ + t8 == cmpbge mask that found the null. */ $u_final: - negq t7, t6 # e0 : isolate low bit set - and t6, t7, t8 # e1 : + negq t8, t6 # e0 : isolate low bit set + and t6, t8, t12 # e1 : - and t8, 0x80, t6 # e0 : avoid dest word load if we can + and t12, 0x80, t6 # e0 : avoid dest word load if we can bne t6, 1f # .. e1 (zdb) ldq_u t1, 0(a0) # e0 : - subq t8, 1, t6 # .. e1 : - or t6, t8, t7 # e0 : - zapnot t0, t7, t0 # .. e1 : kill source bytes > null - zap t1, t7, t1 # e0 : kill dest bytes <= null + subq t12, 1, t6 # .. e1 : + or t6, t12, t8 # e0 : + zapnot t0, t8, t0 # .. e1 : kill source bytes > null + zap t1, t8, t1 # e0 : kill dest bytes <= null or t0, t1, t0 # e1 : 1: stq_u t0, 0(a0) # e0 : @@ -249,10 +249,10 @@ $u_eoc: # end-of-count extqh t2, a1, t0 or t0, t1, t0 - cmpbge zero, t0, t7 + cmpbge zero, t0, t8 $u_eocfin: # end-of-count, final word - or t10, t7, t7 + or t10, t8, t8 br $u_final /* Unaligned copy entry point. */ @@ -279,19 +279,19 @@ /* If source misalignment is larger than dest misalignment, we need extra startup checks to avoid SEGV. */ - cmplt t4, t5, t8 # e1 : + cmplt t4, t5, t12 # e1 : extql t1, a1, t1 # .. e0 : shift src into place lda t2, -1 # e0 : for creating masks later - beq t8, $u_head # e1 : + beq t12, $u_head # e1 : mskqh t2, t5, t2 # e0 : begin src byte validity mask - cmpbge zero, t1, t7 # .. e1 : is there a zero? + cmpbge zero, t1, t8 # .. e1 : is there a zero? extql t2, a1, t2 # e0 : - or t7, t10, t6 # .. e1 : test for end-of-count too + or t8, t10, t5 # .. e1 : test for end-of-count too cmpbge zero, t2, t3 # e0 : - cmoveq a2, t6, t7 # .. e1 : - andnot t7, t3, t7 # e0 : - beq t7, $u_head # .. e1 (zdb) + cmoveq a2, t5, t8 # .. e1 : + andnot t8, t3, t8 # e0 : + beq t8, $u_head # .. e1 (zdb) /* At this point we've found a zero in the first partial word of the source. We need to isolate the valid source data and mask @@ -299,26 +299,26 @@ that we'll need at least one byte of that original dest word.) */ ldq_u t0, 0(a0) # e0 : - negq t7, t6 # .. e1 : build bitmask of bytes <= zero + negq t8, t6 # .. e1 : build bitmask of bytes <= zero mskqh t1, t4, t1 # e0 : - and t6, t7, t8 # .. e1 : - subq t8, 1, t6 # e0 : - or t6, t8, t7 # e1 : + and t6, t8, t12 # .. e1 : + subq t12, 1, t6 # e0 : + or t6, t12, t8 # e1 : - zapnot t2, t7, t2 # e0 : prepare source word; mirror changes - zapnot t1, t7, t1 # .. e1 : to source validity mask + zapnot t2, t8, t2 # e0 : prepare source word; mirror changes + zapnot t1, t8, t1 # .. e1 : to source validity mask andnot t0, t2, t0 # e0 : zero place for source to reside or t0, t1, t0 # e1 : and put it there stq_u t0, 0(a0) # e0 : $finish_up: - zapnot t0, t8, t4 # was last byte written null? + zapnot t0, t12, t4 # was last byte written null? cmovne t4, 1, t4 - and t8, 0xf0, t3 # binary search for the address of the - and t8, 0xcc, t2 # last byte written - and t8, 0xaa, t1 + and t12, 0xf0, t3 # binary search for the address of the + and t12, 0xcc, t2 # last byte written + and t12, 0xaa, t1 bic a0, 7, t0 cmovne t3, 4, t3 cmovne t2, 2, t2 diff -u --recursive --new-file v2.1.25/linux/arch/alpha/lib/stxcpy.S linux/arch/alpha/lib/stxcpy.S --- v2.1.25/linux/arch/alpha/lib/stxcpy.S Sat Oct 19 10:07:28 1996 +++ linux/arch/alpha/lib/stxcpy.S Thu Feb 6 14:42:35 1997 @@ -13,7 +13,7 @@ * a1 = SRC * * On output: - * t8 = bitmask (with one bit set) indicating the last byte written + * t12 = bitmask (with one bit set) indicating the last byte written * a0 = unaligned address of the last *word* written * * Furthermore, v0, a3-a5, t11, and t12 are untouched. @@ -47,9 +47,9 @@ mskqh t1, a1, t3 # e0 : ornot t1, t2, t2 # .. e1 : mskql t0, a1, t0 # e0 : assemble the first output word - cmpbge zero, t2, t7 # .. e1 : bits set iff null found + cmpbge zero, t2, t8 # .. e1 : bits set iff null found or t0, t3, t1 # e0 : - bne t7, $a_eos # .. e1 : + bne t8, $a_eos # .. e1 : /* On entry to this basic block: t0 == the first destination word for masking back in @@ -60,29 +60,29 @@ addq a0, 8, a0 # .. e1 : ldq_u t1, 0(a1) # e0 : addq a1, 8, a1 # .. e1 : - cmpbge zero, t1, t7 # e0 (stall) - beq t7, $a_loop # .. e1 (zdb) + cmpbge zero, t1, t8 # e0 (stall) + beq t8, $a_loop # .. e1 (zdb) /* Take care of the final (partial) word store. On entry to this basic block we have: t1 == the source word containing the null - t7 == the cmpbge mask that found it. */ + t8 == the cmpbge mask that found it. */ $a_eos: - negq t7, t6 # e0 : find low bit set - and t7, t6, t8 # e1 (stall) + negq t8, t6 # e0 : find low bit set + and t8, t6, t12 # e1 (stall) /* For the sake of the cache, don't read a destination word if we're not going to need it. */ - and t8, 0x80, t6 # e0 : + and t12, 0x80, t6 # e0 : bne t6, 1f # .. e1 (zdb) /* We're doing a partial word store and so need to combine our source and original destination words. */ ldq_u t0, 0(a0) # e0 : - subq t8, 1, t6 # .. e1 : + subq t12, 1, t6 # .. e1 : zapnot t1, t6, t1 # e0 : clear src bytes >= null - or t8, t6, t7 # .. e1 : - zap t0, t7, t0 # e0 : clear dst bytes <= null + or t12, t6, t8 # .. e1 : + zap t0, t8, t0 # e0 : clear dst bytes <= null or t0, t1, t1 # e1 : 1: stq_u t1, 0(a0) # e0 : @@ -138,14 +138,14 @@ or t0, t1, t1 # e1 : or t1, t6, t6 # e0 : - cmpbge zero, t6, t7 # .. e1 : + cmpbge zero, t6, t8 # .. e1 : lda t6, -1 # e0 : for masking just below - bne t7, $u_final # .. e1 : + bne t8, $u_final # .. e1 : mskql t6, a1, t6 # e0 : mask out the bits we have or t6, t2, t2 # e1 : already extracted before - cmpbge zero, t2, t7 # e0 : testing eos - bne t7, $u_late_head_exit # .. e1 (zdb) + cmpbge zero, t2, t8 # e0 : testing eos + bne t8, $u_late_head_exit # .. e1 (zdb) /* Finally, we've got all the stupid leading edge cases taken care of and we can set up to enter the main loop. */ @@ -155,9 +155,9 @@ extql t2, a1, t0 # e0 : position ho-bits of lo word ldq_u t2, 8(a1) # .. e1 : read next high-order source word addq a1, 8, a1 # e0 : - cmpbge zero, t2, t7 # .. e1 : + cmpbge zero, t2, t8 # .. e1 : nop # e0 : - bne t7, $u_eos # .. e1 : + bne t8, $u_eos # .. e1 : /* Unaligned copy main loop. In order to avoid reading too much, the loop is structured to detect zeros in aligned source words. @@ -182,8 +182,8 @@ ldq_u t2, 0(a1) # .. e1 : load high word for next time stq_u t1, -8(a0) # e0 : save the current word mov t3, t0 # .. e1 : - cmpbge zero, t2, t7 # e0 : test new word for eos - beq t7, $u_loop # .. e1 : + cmpbge zero, t2, t8 # e0 : test new word for eos + beq t8, $u_loop # .. e1 : /* We've found a zero somewhere in the source word we just read. If it resides in the lower half, we have one (probably partial) @@ -197,31 +197,31 @@ extqh t2, a1, t1 # e0 : or t0, t1, t1 # e1 : first (partial) source word complete - cmpbge zero, t1, t7 # e0 : is the null in this first bit? - bne t7, $u_final # .. e1 (zdb) + cmpbge zero, t1, t8 # e0 : is the null in this first bit? + bne t8, $u_final # .. e1 (zdb) $u_late_head_exit: stq_u t1, 0(a0) # e0 : the null was in the high-order bits addq a0, 8, a0 # .. e1 : extql t2, a1, t1 # e0 : - cmpbge zero, t1, t7 # .. e1 : + cmpbge zero, t1, t8 # .. e1 : /* Take care of a final (probably partial) result word. On entry to this basic block: t1 == assembled source word - t7 == cmpbge mask that found the null. */ + t8 == cmpbge mask that found the null. */ $u_final: - negq t7, t6 # e0 : isolate low bit set - and t6, t7, t8 # e1 : + negq t8, t6 # e0 : isolate low bit set + and t6, t8, t12 # e1 : - and t8, 0x80, t6 # e0 : avoid dest word load if we can + and t12, 0x80, t6 # e0 : avoid dest word load if we can bne t6, 1f # .. e1 (zdb) ldq_u t0, 0(a0) # e0 : - subq t8, 1, t6 # .. e1 : - or t6, t8, t7 # e0 : + subq t12, 1, t6 # .. e1 : + or t6, t12, t8 # e0 : zapnot t1, t6, t1 # .. e1 : kill source bytes >= null - zap t0, t7, t0 # e0 : kill dest bytes <= null + zap t0, t8, t0 # e0 : kill dest bytes <= null or t0, t1, t1 # e1 : 1: stq_u t1, 0(a0) # e0 : @@ -251,15 +251,15 @@ /* If source misalignment is larger than dest misalignment, we need extra startup checks to avoid SEGV. */ - cmplt t4, t5, t8 # e0 : - beq t8, $u_head # .. e1 (zdb) + cmplt t4, t5, t12 # e0 : + beq t12, $u_head # .. e1 (zdb) lda t2, -1 # e1 : mask out leading garbage in source mskqh t2, t5, t2 # e0 : nop # e0 : ornot t1, t2, t3 # .. e1 : - cmpbge zero, t3, t7 # e0 : is there a zero? - beq t7, $u_head # .. e1 (zdb) + cmpbge zero, t3, t8 # e0 : is there a zero? + beq t8, $u_head # .. e1 (zdb) /* At this point we've found a zero in the first partial word of the source. We need to isolate the valid source data and mask @@ -268,14 +268,14 @@ ldq_u t0, 0(a0) # e0 : - negq t7, t6 # .. e1 : build bitmask of bytes <= zero - and t6, t7, t8 # e0 : + negq t8, t6 # .. e1 : build bitmask of bytes <= zero + and t6, t8, t12 # e0 : and a1, 7, t5 # .. e1 : - subq t8, 1, t6 # e0 : - or t6, t8, t7 # e1 : - srl t8, t5, t8 # e0 : adjust final null return value + subq t12, 1, t6 # e0 : + or t6, t12, t8 # e1 : + srl t12, t5, t12 # e0 : adjust final null return value - zapnot t2, t7, t2 # .. e1 : prepare source word; mirror changes + zapnot t2, t8, t2 # .. e1 : prepare source word; mirror changes and t1, t2, t1 # e1 : to source validity mask extql t2, a1, t2 # .. e0 : extql t1, a1, t1 # e0 : diff -u --recursive --new-file v2.1.25/linux/arch/alpha/lib/stxncpy.S linux/arch/alpha/lib/stxncpy.S --- v2.1.25/linux/arch/alpha/lib/stxncpy.S Sat Oct 19 10:07:28 1996 +++ linux/arch/alpha/lib/stxncpy.S Thu Feb 6 14:51:09 1997 @@ -18,9 +18,9 @@ * * On output: * t0 = last word written - * t8 = bitmask (with one bit set) indicating the last byte written * t10 = bitmask (with one bit set) indicating the byte position of * the end of the range specified by COUNT + * t12 = bitmask (with one bit set) indicating the last byte written * a0 = unaligned address of the last *word* written * a2 = the number of full words left in COUNT * @@ -55,10 +55,10 @@ mskqh t1, a1, t3 # e0 : ornot t1, t2, t2 # .. e1 : mskql t0, a1, t0 # e0 : assemble the first output word - cmpbge zero, t2, t7 # .. e1 : bits set iff null found + cmpbge zero, t2, t8 # .. e1 : bits set iff null found or t0, t3, t0 # e0 : beq a2, $a_eoc # .. e1 : - bne t7, $a_eos # .. e1 : + bne t8, $a_eos # .. e1 : /* On entry to this basic block: t0 == a source word not containing a null. */ @@ -69,34 +69,34 @@ ldq_u t0, 0(a1) # e0 : addq a1, 8, a1 # .. e1 : subq a2, 1, a2 # e0 : - cmpbge zero, t0, t7 # .. e1 (stall) + cmpbge zero, t0, t8 # .. e1 (stall) beq a2, $a_eoc # e1 : - beq t7, $a_loop # e1 : + beq t8, $a_loop # e1 : /* Take care of the final (partial) word store. At this point - the end-of-count bit is set in t7 iff it applies. + the end-of-count bit is set in t8 iff it applies. On entry to this basic block we have: t0 == the source word containing the null - t7 == the cmpbge mask that found it. */ + t8 == the cmpbge mask that found it. */ $a_eos: - negq t7, t8 # e0 : find low bit set - and t7, t8, t8 # e1 (stall) + negq t8, t12 # e0 : find low bit set + and t8, t12, t12 # e1 (stall) /* For the sake of the cache, don't read a destination word if we're not going to need it. */ - and t8, 0x80, t6 # e0 : + and t12, 0x80, t6 # e0 : bne t6, 1f # .. e1 (zdb) /* We're doing a partial word store and so need to combine our source and original destination words. */ ldq_u t1, 0(a0) # e0 : - subq t8, 1, t6 # .. e1 : - or t8, t6, t7 # e0 : + subq t12, 1, t6 # .. e1 : + or t12, t6, t8 # e0 : unop # - zapnot t0, t7, t0 # e0 : clear src bytes > null - zap t1, t7, t1 # .. e1 : clear dst bytes <= null + zapnot t0, t8, t0 # e0 : clear src bytes > null + zap t1, t8, t1 # .. e1 : clear dst bytes <= null or t0, t1, t0 # e1 : 1: stq_u t0, 0(a0) # e0 : @@ -104,7 +104,7 @@ /* Add the end-of-count bit to the eos detection bitmask. */ $a_eoc: - or t10, t7, t7 + or t10, t8, t8 br $a_eos .end stxncpy_aligned @@ -161,18 +161,18 @@ mskqh t1, a0, t1 # e0 : mask leading garbage in src or t0, t1, t0 # e0 : first output word complete or t0, t6, t6 # e1 : mask original data for zero test - cmpbge zero, t6, t7 # e0 : + cmpbge zero, t6, t8 # e0 : beq a2, $u_eocfin # .. e1 : - bne t7, $u_final # e1 : + bne t8, $u_final # e1 : lda t6, -1 # e1 : mask out the bits we have mskql t6, a1, t6 # e0 : already seen stq_u t0, 0(a0) # e0 : store first output word or t6, t2, t2 # .. e1 : - cmpbge zero, t2, t7 # e0 : find nulls in second partial + cmpbge zero, t2, t8 # e0 : find nulls in second partial addq a0, 8, a0 # .. e1 : subq a2, 1, a2 # e0 : - bne t7, $u_late_head_exit # .. e1 : + bne t8, $u_late_head_exit # .. e1 : /* Finally, we've got all the stupid leading edge cases taken care of and we can set up to enter the main loop. */ @@ -180,9 +180,9 @@ extql t2, a1, t1 # e0 : position hi-bits of lo word ldq_u t2, 8(a1) # .. e1 : read next high-order source word addq a1, 8, a1 # e0 : - cmpbge zero, t2, t7 # e1 (stall) + cmpbge zero, t2, t8 # e1 (stall) beq a2, $u_eoc # e1 : - bne t7, $u_eos # e1 : + bne t8, $u_eos # e1 : /* Unaligned copy main loop. In order to avoid reading too much, the loop is structured to detect zeros in aligned source words. @@ -208,9 +208,9 @@ stq_u t0, -8(a0) # e0 : save the current word mov t3, t1 # .. e1 : subq a2, 1, a2 # e0 : - cmpbge zero, t2, t7 # .. e1 : test new word for eos + cmpbge zero, t2, t8 # .. e1 : test new word for eos beq a2, $u_eoc # e1 : - beq t7, $u_loop # e1 : + beq t8, $u_loop # e1 : /* We've found a zero somewhere in the source word we just read. If it resides in the lower half, we have one (probably partial) @@ -224,8 +224,8 @@ extqh t2, a1, t0 # e0 : or t0, t1, t0 # e1 : first (partial) source word complete - cmpbge zero, t0, t7 # e0 : is the null in this first bit? - bne t7, $u_final # .. e1 (zdb) + cmpbge zero, t0, t8 # e0 : is the null in this first bit? + bne t8, $u_final # .. e1 (zdb) stq_u t0, 0(a0) # e0 : the null was in the high-order bits addq a0, 8, a0 # .. e1 : @@ -233,27 +233,27 @@ $u_late_head_exit: extql t2, a1, t0 # .. e0 : - cmpbge zero, t0, t7 # e0 : - or t7, t10, t6 # e1 : - cmoveq a2, t6, t7 # e0 : + cmpbge zero, t0, t8 # e0 : + or t8, t10, t6 # e1 : + cmoveq a2, t6, t8 # e0 : nop # .. e1 : /* Take care of a final (probably partial) result word. On entry to this basic block: t0 == assembled source word - t7 == cmpbge mask that found the null. */ + t8 == cmpbge mask that found the null. */ $u_final: - negq t7, t6 # e0 : isolate low bit set - and t6, t7, t8 # e1 : + negq t8, t6 # e0 : isolate low bit set + and t6, t8, t12 # e1 : - and t8, 0x80, t6 # e0 : avoid dest word load if we can + and t12, 0x80, t6 # e0 : avoid dest word load if we can bne t6, 1f # .. e1 (zdb) ldq_u t1, 0(a0) # e0 : - subq t8, 1, t6 # .. e1 : - or t6, t8, t7 # e0 : - zapnot t0, t7, t0 # .. e1 : kill source bytes > null - zap t1, t7, t1 # e0 : kill dest bytes <= null + subq t12, 1, t6 # .. e1 : + or t6, t12, t8 # e0 : + zapnot t0, t8, t0 # .. e1 : kill source bytes > null + zap t1, t8, t1 # e0 : kill dest bytes <= null or t0, t1, t0 # e1 : 1: stq_u t0, 0(a0) # e0 : @@ -262,10 +262,10 @@ $u_eoc: # end-of-count extqh t2, a1, t0 or t0, t1, t0 - cmpbge zero, t0, t7 + cmpbge zero, t0, t8 $u_eocfin: # end-of-count, final word - or t10, t7, t7 + or t10, t8, t8 br $u_final /* Unaligned copy entry point. */ @@ -292,19 +292,19 @@ /* If source misalignment is larger than dest misalignment, we need extra startup checks to avoid SEGV. */ - cmplt t4, t5, t8 # e1 : + cmplt t4, t5, t12 # e1 : extql t1, a1, t1 # .. e0 : shift src into place lda t2, -1 # e0 : for creating masks later - beq t8, $u_head # e1 : + beq t12, $u_head # e1 : mskqh t2, t5, t2 # e0 : begin src byte validity mask - cmpbge zero, t1, t7 # .. e1 : is there a zero? + cmpbge zero, t1, t8 # .. e1 : is there a zero? extql t2, a1, t2 # e0 : - or t7, t10, t6 # .. e1 : test for end-of-count too + or t8, t10, t5 # .. e1 : test for end-of-count too cmpbge zero, t2, t3 # e0 : - cmoveq a2, t6, t7 # .. e1 : - andnot t7, t3, t7 # e0 : - beq t7, $u_head # .. e1 (zdb) + cmoveq a2, t5, t8 # .. e1 : + andnot t8, t3, t8 # e0 : + beq t8, $u_head # .. e1 (zdb) /* At this point we've found a zero in the first partial word of the source. We need to isolate the valid source data and mask @@ -312,14 +312,14 @@ that we'll need at least one byte of that original dest word.) */ ldq_u t0, 0(a0) # e0 : - negq t7, t6 # .. e1 : build bitmask of bytes <= zero + negq t8, t6 # .. e1 : build bitmask of bytes <= zero mskqh t1, t4, t1 # e0 : - and t6, t7, t8 # .. e1 : - subq t8, 1, t6 # e0 : - or t6, t8, t7 # e1 : + and t6, t8, t12 # .. e1 : + subq t12, 1, t6 # e0 : + or t6, t12, t8 # e1 : - zapnot t2, t7, t2 # e0 : prepare source word; mirror changes - zapnot t1, t7, t1 # .. e1 : to source validity mask + zapnot t2, t8, t2 # e0 : prepare source word; mirror changes + zapnot t1, t8, t1 # .. e1 : to source validity mask andnot t0, t2, t0 # e0 : zero place for source to reside or t0, t1, t0 # e1 : and put it there diff -u --recursive --new-file v2.1.25/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.1.25/linux/arch/i386/defconfig Thu Jan 23 21:06:46 1997 +++ linux/arch/i386/defconfig Fri Feb 7 16:49:49 1997 @@ -68,9 +68,10 @@ # CONFIG_FIREWALL is not set # CONFIG_NET_ALIAS is not set CONFIG_INET=y -# CONFIG_IP_FORWARD is not set # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ACCT is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set # # (it is safe to leave these untouched) @@ -116,9 +117,9 @@ # CONFIG_PLIP is not set # CONFIG_PPP is not set # CONFIG_NET_RADIO is not set -# CONFIG_LAPBETHER is not set # CONFIG_SLIP is not set # CONFIG_TR is not set +# CONFIG_LAPBETHER is not set # # ISDN subsystem diff -u --recursive --new-file v2.1.25/linux/arch/i386/kernel/ioport.c linux/arch/i386/kernel/ioport.c --- v2.1.25/linux/arch/i386/kernel/ioport.c Tue Jan 28 18:49:46 1997 +++ linux/arch/i386/kernel/ioport.c Tue Feb 4 16:44:24 1997 @@ -53,19 +53,13 @@ */ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on) { - int ret = -EINVAL; - - lock_kernel(); if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32)) - goto out; - ret = -EPERM; + return -EINVAL; if (!suser()) - goto out; + return -EPERM; + set_bitmap((unsigned long *)current->tss.io_bitmap, from, num, !turn_on); - ret = 0; -out: - unlock_kernel(); - return ret; + return 0; } unsigned int *stack; @@ -80,23 +74,18 @@ * on system-call entry - see also fork() and the signal handling * code. */ + asmlinkage int sys_iopl(long ebx,long ecx,long edx, long esi, long edi, long ebp, long eax, long ds, long es, long orig_eax, long eip, long cs, long eflags, long esp, long ss) { unsigned int level = ebx; - int ret = -EINVAL; - lock_kernel(); if (level > 3) - goto out; - ret = -EPERM; + return -EINVAL; if (!suser()) - goto out; + return -EPERM; *(&eflags) = (eflags & 0xffffcfff) | (level << 12); - ret = 0; -out: - unlock_kernel(); - return ret; + return 0; } diff -u --recursive --new-file v2.1.25/linux/arch/i386/kernel/sys_i386.c linux/arch/i386/kernel/sys_i386.c --- v2.1.25/linux/arch/i386/kernel/sys_i386.c Tue Jan 28 18:49:47 1997 +++ linux/arch/i386/kernel/sys_i386.c Fri Feb 7 15:54:53 1997 @@ -32,11 +32,11 @@ lock_kernel(); error = do_pipe(fd); + unlock_kernel(); if (!error) { if (copy_to_user(fildes, fd, 2*sizeof(int))) error = -EFAULT; } - unlock_kernel(); return error; } @@ -46,6 +46,7 @@ * 4 system call parameters, so these system calls used a memory * block for parameter passing.. */ + struct mmap_arg_struct { unsigned long addr; unsigned long len; @@ -87,13 +88,12 @@ asmlinkage int old_select(struct sel_arg_struct *arg) { struct sel_arg_struct a; - int ret = -EFAULT; + int ret; - lock_kernel(); if (copy_from_user(&a, arg, sizeof(a))) - goto out; + return -EFAULT; + lock_kernel(); ret = sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); -out: unlock_kernel(); return ret; } diff -u --recursive --new-file v2.1.25/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- v2.1.25/linux/arch/i386/kernel/time.c Thu Dec 12 19:36:58 1996 +++ linux/arch/i386/kernel/time.c Fri Feb 7 15:54:54 1997 @@ -41,38 +41,33 @@ unsigned long high; } init_timer_cc, last_timer_cc; -/* - * This is more assembly than C, but it's also rather - * timing-critical and we have to use assembler to get - * reasonable 64-bit arithmetic - */ +extern volatile unsigned long lost_ticks; + +/* change this if you have some constant time drift */ +#define USECS_PER_JIFFY (1000020/HZ) + static unsigned long do_fast_gettimeoffset(void) { register unsigned long eax asm("ax"); register unsigned long edx asm("dx"); - unsigned long tmp, quotient, low_timer, missing_time; + unsigned long tmp, quotient, low_timer; - /* Last jiffy when do_fast_gettimeoffset() was called.. */ + /* Last jiffy when do_fast_gettimeoffset() was called. */ static unsigned long last_jiffies=0; - /* Cached "clocks per usec" value.. */ + /* + * Cached "1/(clocks per usec)*2^32" value. + * It has to be recalculated once each jiffy. + */ static unsigned long cached_quotient=0; - /* The "clocks per usec" value is calculated once each jiffy */ tmp = jiffies; + quotient = cached_quotient; low_timer = last_timer_cc.low; - missing_time = 0; + if (last_jiffies != tmp) { last_jiffies = tmp; - /* - * test for hanging bottom handler (this means xtime is not - * updated yet) - */ - if (test_bit(TIMER_BH, &bh_active) ) - { - missing_time = 1000020/HZ; - } /* Get last timer tick in absolute kernel time */ eax = low_timer; @@ -86,14 +81,16 @@ * Divide the 64-bit time with the 32-bit jiffy counter, * getting the quotient in clocks. * - * Giving quotient = "average internal clocks per usec" + * Giving quotient = "1/(average internal clocks per usec)*2^32" + * we do this '1/...' trick to get the 'mull' into the critical + * path. 'mull' is much faster than divl (10 vs. 41 clocks) */ __asm__("divl %2" :"=a" (eax), "=d" (edx) :"r" (tmp), "0" (eax), "1" (edx)); - edx = 1000020/HZ; + edx = USECS_PER_JIFFY; tmp = eax; eax = 0; @@ -114,7 +111,7 @@ eax -= low_timer; /* - * Time offset = (1000020/HZ * time_low) / quotient. + * Time offset = (USECS_PER_JIFFY * time_low) * quotient. */ __asm__("mull %2" @@ -123,15 +120,13 @@ "0" (eax), "1" (edx)); /* - * Due to rounding errors (and jiffies inconsistencies), - * we need to check the result so that we'll get a timer - * that is monotonic. + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. */ - if (edx >= 1000020/HZ) - edx = 1000020/HZ-1; + if (edx >= USECS_PER_JIFFY) + edx = USECS_PER_JIFFY-1; - eax = edx + missing_time; - return eax; + return edx; } #endif @@ -172,8 +167,8 @@ static unsigned long do_slow_gettimeoffset(void) { int count; - static int count_p = 0; - unsigned long offset = 0; + + static int count_p = LATCH; /* for the first call after boot */ static unsigned long jiffies_p = 0; /* @@ -183,53 +178,69 @@ /* timer count may underflow right here */ outb_p(0x00, 0x43); /* latch the count ASAP */ + count = inb_p(0x40); /* read the latched count */ - count |= inb(0x40) << 8; + /* + * We do this guaranteed double memory access instead of a _p + * postfix in the previous port access. Wheee, hackady hack + */ jiffies_t = jiffies; + count |= inb_p(0x40) << 8; + /* * avoiding timer inconsistencies (they are rare, but they happen)... - * there are three kinds of problems that must be avoided here: + * there are two kinds of problems that must be avoided here: * 1. the timer counter underflows * 2. hardware problem with the timer, not giving us continuous time, * the counter does small "jumps" upwards on some Pentium systems, - * thus causes time warps - * 3. we are after the timer interrupt, but the bottom half handler - * hasn't executed yet. - */ - if( count > count_p ) { - if( jiffies_t == jiffies_p ) { - if( count > LATCH-LATCH/100 ) - offset = TICK_SIZE; - else + * (see c't 95/10 page 335 for Neptun bug.) + */ + +/* you can safely undefine this if you dont have the Neptun chipset */ + +#define BUGGY_NEPTUN_TIMER + + if( jiffies_t == jiffies_p ) { + if( count > count_p ) { + /* the nutcase */ + + outb_p(0x0A, 0x20); + + /* assumption about timer being IRQ1 */ + if( inb(0x20) & 0x01 ) { /* - * argh, the timer is bugging we cant do nothing - * but to give the previous clock value. + * We cannot detect lost timer interrupts ... + * well, thats why we call them lost, dont we? :) + * [hmm, on the Pentium and Alpha we can ... sort of] */ - count = count_p; - } else { - if( test_bit(TIMER_BH, &bh_active) ) { - /* - * we have detected a counter underflow. - */ - offset = TICK_SIZE; - count_p = count; + count -= LATCH; } else { - count_p = count; - jiffies_p = jiffies_t; +#ifdef BUGGY_NEPTUN_TIMER + /* + * for the Neptun bug we know that the 'latch' + * command doesnt latch the high and low value + * of the counter atomically. Thus we have to + * substract 256 from the counter + * ... funny, isnt it? :) + */ + + count -= 256; +#else + printk("do_slow_gettimeoffset(): hardware timer problem?\n"); +#endif } } - } else { - count_p = count; + } else jiffies_p = jiffies_t; - } + count_p = count; count = ((LATCH-1) - count) * TICK_SIZE; count = (count + LATCH/2) / LATCH; - return offset + count; + return count; } /* @@ -253,11 +264,20 @@ cli(); *tv = xtime; tv->tv_usec += do_gettimeoffset(); + + /* + * xtime is atomically updated in timer_bh. lost_ticks is + * nonzero if the timer bottom half hasnt executed yet. + */ + if (lost_ticks) + tv->tv_usec += USECS_PER_JIFFY; + + restore_flags(flags); + if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } - restore_flags(flags); } void do_settimeofday(struct timeval *tv) diff -u --recursive --new-file v2.1.25/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c --- v2.1.25/linux/arch/i386/kernel/traps.c Tue Jan 28 18:49:47 1997 +++ linux/arch/i386/kernel/traps.c Fri Feb 7 15:54:54 1997 @@ -198,6 +198,21 @@ DO_ERROR(12, SIGBUS, "stack segment", stack_segment, current) DO_ERROR(17, SIGSEGV, "alignment check", alignment_check, current) DO_ERROR(18, SIGSEGV, "reserved", reserved, current) +/* I don't have documents for this but it does seem to cover the cache + flush from user space exception some people get. */ +DO_ERROR(19, SIGSEGV, "cache flush denied", cache_flush_denied, current) + +asmlinkage void cache_flush_denied(struct pt_regs * regs, long error_code) +{ + if (regs->eflags & VM_MASK) { + handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); + return; + } + die_if_kernel("cache flush denied",regs,error_code); + current->tss.error_code = error_code; + current->tss.trap_no = 19; + force_sig(SIGSEGV, current); +} asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) { diff -u --recursive --new-file v2.1.25/linux/arch/i386/lib/checksum.c linux/arch/i386/lib/checksum.c --- v2.1.25/linux/arch/i386/lib/checksum.c Thu Feb 6 12:41:59 1997 +++ linux/arch/i386/lib/checksum.c Fri Feb 7 15:54:54 1997 @@ -100,225 +100,162 @@ /* * Copy from ds while checksumming, otherwise like csum_partial * - * The macros SRC and DST specify wether there should be exception handling - * for the source and/or the destination addresses. + * The macros SRC and DST specify the type of access for the instruction. + * thus we can call a custom exception handler for all access types. * * FIXME: could someone double check wether i havent mixed up some SRC and * DST definitions? It's damn hard to trigger all cases, i hope i got * them all but theres no guarantee ... */ -#define csum_partial_copy_type(type) \ -unsigned int csum_partial_copy ##type (int * __csum_err, const char *src, char *dst, \ - int len, int sum) { \ - __asm__( \ -" testl $2, %%edi # Check alignment. \n" \ -" jz 2f # Jump if alignment is ok. \n" \ -" subl $2, %%ecx # Alignment uses up two bytes. \n" \ -" jae 1f # Jump if we had at least two bytes. \n" \ -" addl $2, %%ecx # ecx was < 2. Deal with it. \n" \ -" jmp 4f \n" \ -" 1000: \n" \ -" 1: movw (%%esi), %%bx \n" \ -" addl $2, %%esi \n" \ -" 1001: \n" \ -" movw %%bx, (%%edi) \n" \ -" addl $2, %%edi \n" \ -" addw %%bx, %%ax \n" \ -" adcl $0, %%eax \n" \ -" 2: \n" \ -" pushl %%ecx \n" \ -" shrl $5, %%ecx \n" \ -" jz 2f \n" \ -" testl %%esi, %%esi \n" \ -" 1002: \n" \ -" 1: movl (%%esi), %%ebx \n" \ -" 1003: \n" \ -" movl 4(%%esi), %%edx \n" \ -" adcl %%ebx, %%eax \n" \ -" 1004: \n" \ -" movl %%ebx, (%%edi) \n" \ -" adcl %%edx, %%eax \n" \ -" 1005: \n" \ -" movl %%edx, 4(%%edi) \n" \ -" \n" \ -" 1006: \n" \ -" movl 8(%%esi), %%ebx \n" \ -" 1007: \n" \ -" movl 12(%%esi), %%edx \n" \ -" adcl %%ebx, %%eax \n" \ -" 1008: \n" \ -" movl %%ebx, 8(%%edi) \n" \ -" adcl %%edx, %%eax \n" \ -" 1009: \n" \ -" movl %%edx, 12(%%edi) \n" \ -" \n" \ -" 1010: \n" \ -" movl 16(%%esi), %%ebx \n" \ -" 1011: \n" \ -" movl 20(%%esi), %%edx \n" \ -" adcl %%ebx, %%eax \n" \ -" 1012: \n" \ -" movl %%ebx, 16(%%edi) \n" \ -" adcl %%edx, %%eax \n" \ -" 1013: \n" \ -" movl %%edx, 20(%%edi) \n" \ -" \n" \ -" 1014: \n" \ -" movl 24(%%esi), %%ebx \n" \ -" 1015: \n" \ -" movl 28(%%esi), %%edx \n" \ -" adcl %%ebx, %%eax \n" \ -" 1016: \n" \ -" movl %%ebx, 24(%%edi) \n" \ -" adcl %%edx, %%eax \n" \ -" 1017: \n" \ -" movl %%edx, 28(%%edi) \n" \ -" \n" \ -" 1018: \n" \ -" lea 32(%%esi), %%esi \n" \ -" 1019: \n" \ -" lea 32(%%edi), %%edi \n" \ -" dec %%ecx \n" \ -" jne 1b \n" \ -" adcl $0, %%eax \n" \ -" 2: popl %%edx \n" \ -" movl %%edx, %%ecx \n" \ -" andl $0x1c, %%edx \n" \ -" je 4f \n" \ -" shrl $2, %%edx # This clears CF \n" \ -" 1020: \n" \ -" 3: movl (%%esi), %%ebx \n" \ -" adcl %%ebx, %%eax \n" \ -" 1021: \n" \ -" movl %%ebx, (%%edi) \n" \ -" 1022: \n" \ -" lea 4(%%esi), %%esi \n" \ -" 1023: \n" \ -" lea 4(%%edi), %%edi \n" \ -" dec %%edx \n" \ -" jne 3b \n" \ -" adcl $0, %%eax \n" \ -" 4: andl $3, %%ecx \n" \ -" jz 7f \n" \ -" cmpl $2, %%ecx \n" \ -" jb 5f \n" \ -" 1024: \n" \ -" movw (%%esi), %%cx \n" \ -" 1025: \n" \ -" leal 2(%%esi), %%esi \n" \ -" 1026: \n" \ -" movw %%cx, (%%edi) \n" \ -" 1027: \n" \ -" leal 2(%%edi), %%edi \n" \ -" je 6f \n" \ -" shll $16,%%ecx \n" \ -" 1028: \n" \ -" 5: movb (%%esi), %%cl \n" \ -" 1029: \n" \ -" movb %%cl, (%%edi) \n" \ -" 6: addl %%ecx, %%eax \n" \ -" adcl $0, %%eax \n" \ -" 7: \n" \ -" 2000: \n" \ -" .section .fixup,\"ax\" \n" \ -" 3000: movl %7,%1 \n" \ -/* FIXME: zero out the rest of the buffer here !!!!!! */ \ -" jmp 2000b \n" \ -" .previous \n" \ -" .section __ex_table,\"a\" \n" \ -" .align 4 \n" \ -" \n" \ -SRC( " .long 1000b,3000b \n " ) \ -DST( " .long 1001b,3000b \n " ) \ -SRC( " .long 1002b,3000b \n " ) \ -SRC( " .long 1003b,3000b \n " ) \ -DST( " .long 1004b,3000b \n " ) \ -DST( " .long 1005b,3000b \n " ) \ -SRC( " .long 1006b,3000b \n " ) \ -SRC( " .long 1007b,3000b \n " ) \ -DST( " .long 1008b,3000b \n " ) \ -DST( " .long 1009b,3000b \n " ) \ -SRC( " .long 1010b,3000b \n " ) \ -SRC( " .long 1011b,3000b \n " ) \ -DST( " .long 1012b,3000b \n " ) \ -DST( " .long 1013b,3000b \n " ) \ -SRC( " .long 1014b,3000b \n " ) \ -SRC( " .long 1015b,3000b \n " ) \ -DST( " .long 1016b,3000b \n " ) \ -DST( " .long 1017b,3000b \n " ) \ -SRC( " .long 1018b,3000b \n " ) \ -DST( " .long 1019b,3000b \n " ) \ -SRC( " .long 1020b,3000b \n " ) \ -DST( " .long 1021b,3000b \n " ) \ -SRC( " .long 1022b,3000b \n " ) \ -DST( " .long 1023b,3000b \n " ) \ -SRC( " .long 1024b,3000b \n " ) \ -SRC( " .long 1025b,3000b \n " ) \ -DST( " .long 1026b,3000b \n " ) \ -DST( " .long 1027b,3000b \n " ) \ -SRC( " .long 1028b,3000b \n " ) \ -DST( " .long 1029b,3000b \n " ) \ -" .previous \n " \ - : "=a" (sum), "=r" (*__csum_err) \ - : "0" (sum), "c" (len), "S" (src), "D" (dst), \ - "1" (*__csum_err), "i" (-EFAULT) \ - : "bx", "cx", "dx", "si", "di" ); \ - \ - return(sum); \ -} +#define SRC(y...) \ +" 9999: "#y"; \n \ + .section __ex_table, \"a\"; \n \ + .long 9999b, src_access_fault \n \ + .previous" + +#define DST(y...) \ +" 9999: "#y"; \n \ + .section __ex_table, \"a\"; \n \ + .long 9999b, dst_access_fault \n \ + .previous" -/* - * Currently we need only 2 out of the 4 possible type combinations: - */ - -/* - * Generate 'csum_partial_copy_from_user()', we need to do exception - * handling for source addresses. - */ - -#define SRC(x) x -#define DST(x) -csum_partial_copy_type(_from_user) -#undef SRC -#undef DST +unsigned int csum_partial_copy_generic (const char *src, char *dst, + int len, int sum, int *src_err_ptr, int *dst_err_ptr) +{ + __asm__ __volatile__ ( " + 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 +"SRC( 1: movw (%%esi), %%bx )" + addl $2, %%esi +"DST( movw %%bx, (%%edi) )" + addl $2, %%edi + addw %%bx, %%ax + adcl $0, %%eax + 2: + pushl %%ecx + shrl $5, %%ecx + jz 2f + testl %%esi, %%esi +"SRC( 1: movl (%%esi), %%ebx )" +"SRC( movl 4(%%esi), %%edx )" + adcl %%ebx, %%eax +"DST( movl %%ebx, (%%edi) )" + adcl %%edx, %%eax +"DST( movl %%edx, 4(%%edi) )" + +"SRC( movl 8(%%esi), %%ebx )" +"SRC( movl 12(%%esi), %%edx )" + adcl %%ebx, %%eax +"DST( movl %%ebx, 8(%%edi) )" + adcl %%edx, %%eax +"DST( movl %%edx, 12(%%edi) )" + +"SRC( movl 16(%%esi), %%ebx )" +"SRC( movl 20(%%esi), %%edx )" + adcl %%ebx, %%eax +"DST( movl %%ebx, 16(%%edi) )" + adcl %%edx, %%eax +"DST( movl %%edx, 20(%%edi) )" + +"SRC( movl 24(%%esi), %%ebx )" +"SRC( movl 28(%%esi), %%edx )" + adcl %%ebx, %%eax +"DST( movl %%ebx, 24(%%edi) )" + adcl %%edx, %%eax +"DST( movl %%edx, 28(%%edi) )" + +"SRC( lea 32(%%esi), %%esi )" +"DST( lea 32(%%edi), %%edi )" + dec %%ecx + jne 1b + adcl $0, %%eax + 2: popl %%edx + movl %%edx, %%ecx + andl $0x1c, %%edx + je 4f + shrl $2, %%edx # This clears CF +"SRC( 3: movl (%%esi), %%ebx )" + adcl %%ebx, %%eax +"DST( movl %%ebx, (%%edi) )" +"SRC( lea 4(%%esi), %%esi )" +"DST( lea 4(%%edi), %%edi )" + dec %%edx + jne 3b + adcl $0, %%eax + 4: andl $3, %%ecx + jz 7f + cmpl $2, %%ecx + jb 5f +"SRC( movw (%%esi), %%cx )" +"SRC( leal 2(%%esi), %%esi )" +"DST( movw %%cx, (%%edi) )" +"DST( leal 2(%%edi), %%edi )" + je 6f + shll $16,%%ecx +"SRC( 5: movb (%%esi), %%cl )" +"DST( movb %%cl, (%%edi) )" + 6: addl %%ecx, %%eax + adcl $0, %%eax + 7: + +end_of_body: + +# Exception handler: +################################################ + # +.section .fixup, \"a\" # + # +common_fixup: # + # + movl %7, (%%ebx) # + # +# FIXME: do zeroing of rest of the buffer here. # + # + jmp end_of_body # + # +src_access_fault: # + movl %1, %%ebx # + jmp common_fixup # + # +dst_access_fault: # + movl %2, %%ebx # + jmp common_fixup # + # +.previous # + # +################################################ + +" + : "=a" (sum), "=m" (src_err_ptr), "=m" (dst_err_ptr) + : "0" (sum), "c" (len), "S" (src), "D" (dst), + "i" (-EFAULT) + : "bx", "cx", "dx", "si", "di" ); -/* - * Generate 'csum_partial_copy_nocheck()', no need to do exception - * handling. - */ + return(sum); +} -#define SRC(x) -#define DST(x) -csum_partial_copy_type(_nocheck_generic) #undef SRC #undef DST /* - * Generate 'csum_partial_copy_old()', old and slow compability stuff, - * full checking. - * - * tell us if you see something printk-ing on this. This function will be - * removed soon. + * FIXME: old compatibility stuff, will be removed soon. */ -#define SRC(x) x -#define DST(x) x -csum_partial_copy_type(_old) -#undef SRC -#undef DST - -unsigned int csum_partial_copy ( const char *src, char *dst, - int len, int sum) +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum) { - int ret; - int error = 0; + int src_err=0, dst_err=0; - ret = csum_partial_copy_old (&error, src, dst, len, sum); + sum = csum_partial_copy_generic ( src, dst, len, sum, &src_err, &dst_err); - if (error) - printk("csum_partial_copy_old(): tell mingo to convert me!\n"); + if (src_err || dst_err) + printk("old csum_partial_copy_fromuser(), tell mingo to convert me.\n"); - return ret; + return sum; } + diff -u --recursive --new-file v2.1.25/linux/drivers/ap1000/apfddi.c linux/drivers/ap1000/apfddi.c --- v2.1.25/linux/drivers/ap1000/apfddi.c Tue Jan 28 18:49:52 1997 +++ linux/drivers/ap1000/apfddi.c Fri Feb 7 15:54:54 1997 @@ -126,7 +126,7 @@ static u_char apfddi_saddr[6] = { 0x42, 0x9a, 0x08, 0x6e, 0x11, 0x41 }; struct device *apfddi_device = NULL; -struct enet_statistics *apfddi_stats = NULL; +struct net_device_stats *apfddi_stats = NULL; volatile struct apfddi_queue *apfddi_queue_top = NULL; @@ -254,7 +254,7 @@ static void apfddi_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int apfddi_xmit(struct sk_buff *skb, struct device *dev); int apfddi_rx(struct mac_buf *mbuf); -static struct enet_statistics *apfddi_get_stats(struct device *dev); +static struct net_device_stats *apfddi_get_stats(struct device *dev); #if APFDDI_DEBUG void dump_packet(char *action, char *buf, int len, int seq); #endif @@ -496,11 +496,11 @@ dev->stop = apfddi_stop; dev->hard_start_xmit = apfddi_xmit; dev->get_stats = apfddi_get_stats; - dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_ATOMIC); + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_ATOMIC); if (dev->priv == NULL) return -ENOMEM; - memset(dev->priv, 0, sizeof(struct enet_statistics)); - apfddi_stats = (struct enet_statistics *)apfddi_device->priv; + memset(dev->priv, 0, sizeof(struct net_device_stats)); + apfddi_stats = (struct net_device_stats *)apfddi_device->priv; /* Initialise the fddi device structure */ for (i = 0; i < DEV_NUMBUFFS; i++) @@ -692,9 +692,9 @@ /* * Return statistics of fddi driver. */ -static struct enet_statistics *apfddi_get_stats(struct device *dev) +static struct net_device_stats *apfddi_get_stats(struct device *dev) { - return((struct enet_statistics *)dev->priv); + return((struct net_device_stats *)dev->priv); } diff -u --recursive --new-file v2.1.25/linux/drivers/ap1000/apfddi.h linux/drivers/ap1000/apfddi.h --- v2.1.25/linux/drivers/ap1000/apfddi.h Tue Jan 28 18:49:52 1997 +++ linux/drivers/ap1000/apfddi.h Fri Feb 7 15:54:54 1997 @@ -138,5 +138,5 @@ void set_cf_join(int on); extern struct device *apfddi_device; -extern struct enet_statistics *apfddi_stats; +extern struct net_device_stats *apfddi_stats; diff -u --recursive --new-file v2.1.25/linux/drivers/ap1000/bif.c linux/drivers/ap1000/bif.c --- v2.1.25/linux/drivers/ap1000/bif.c Tue Jan 28 18:49:52 1997 +++ linux/drivers/ap1000/bif.c Fri Feb 7 15:54:54 1997 @@ -46,14 +46,14 @@ #define BIF_MTU 10240 static struct device *bif_device = 0; -static struct enet_statistics *bif_stats = 0; +static struct net_device_stats *bif_stats = 0; int bif_init(struct device *dev); int bif_open(struct device *dev); static int bif_xmit(struct sk_buff *skb, struct device *dev); int bif_rx(struct sk_buff *skb); int bif_stop(struct device *dev); -static struct enet_statistics *bif_get_stats(struct device *dev); +static struct net_device_stats *bif_get_stats(struct device *dev); static int bif_hard_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, @@ -128,11 +128,11 @@ dev->open = bif_open; dev->flags = IFF_NOARP; /* Don't use ARP on this device */ dev->family = AF_INET; - dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL); + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); if (dev->priv == NULL) return -ENOMEM; - memset(dev->priv, 0, sizeof(struct enet_statistics)); - bif_stats = (struct enet_statistics *)bif_device->priv; + memset(dev->priv, 0, sizeof(struct net_device_stats)); + bif_stats = (struct net_device_stats *)bif_device->priv; dev->stop = bif_stop; @@ -282,8 +282,8 @@ /* * Return statistics of bif driver. */ -static struct enet_statistics *bif_get_stats(struct device *dev) +static struct net_device_stats *bif_get_stats(struct device *dev) { - return((struct enet_statistics *)dev->priv); + return((struct net_device_stats *)dev->priv); } diff -u --recursive --new-file v2.1.25/linux/drivers/char/esp.c linux/drivers/char/esp.c --- v2.1.25/linux/drivers/char/esp.c Thu Jan 2 15:55:16 1997 +++ linux/drivers/char/esp.c Wed Feb 5 13:49:56 1997 @@ -29,19 +29,17 @@ * by Chris Faylor. * * Most recent changes: (Andrew J. Robinson) - * Remove all references to tty->hw_stopped. - * Request a single region for multiple ports if possible. - * Stop a DMA transfer on a port when it is closed. - * Rename esp_init() to espserial_init(). - * Improve validation of IRQ (only accept those allowed by the ESP card). - * Return if a signal is received while wait for a break to start. - * Split NEED_DMA logic into NEED_DMA_RX and NEED_DMA_TX. + * Don't cause a kernel panic if memory could not be allocated or if the + * device couldn't be registered. + * Always set RTS when transitioning away from B0 status (since the + * flow is really being handled by the ESP card). * * This module exports the following rs232 io functions: * * int espserial_init(void); */ +#include #include #include #include @@ -51,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -95,7 +92,7 @@ #define WAKEUP_CHARS 1024 static char *serial_name = "ESP serial driver"; -static char *serial_version = "1.3"; +static char *serial_version = "1.5"; DECLARE_TASK_QUEUE(tq_esp); @@ -1851,9 +1848,7 @@ /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) { - info->MCR |= UART_MCR_DTR; - if (!(tty->termios->c_cflag & CRTSCTS)) - info->MCR |= UART_MCR_RTS; + info->MCR |= (UART_MCR_DTR | UART_MCR_RTS); cli(); serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); serial_out(info, UART_ESI_CMD2, UART_MCR); @@ -2460,14 +2455,29 @@ esp_callout_driver.subtype = SERIAL_TYPE_CALLOUT; if (tty_register_driver(&esp_driver)) - panic("Couldn't register serial driver\n"); + { + printk(KERN_ERR "Couldn't register esp serial driver"); + return 1; + } + if (tty_register_driver(&esp_callout_driver)) - panic("Couldn't register callout driver\n"); + { + printk(KERN_ERR "Couldn't register esp callout driver"); + tty_unregister_driver(&esp_driver); + return 1; + } info = (struct esp_struct *)kmalloc(sizeof(struct esp_struct), GFP_KERNEL); + if (!info) - panic("Could not allocate memory for device information\n"); + { + printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); + tty_unregister_driver(&esp_driver); + tty_unregister_driver(&esp_callout_driver); + return 1; + } + memset((void *)info, 0, sizeof(struct esp_struct)); i = 0; @@ -2515,7 +2525,13 @@ info = (struct esp_struct *)kmalloc(sizeof(struct esp_struct), GFP_KERNEL); if (!info) - panic("Could not allocate memory for device information\n"); + { + printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); + + /* allow use of the already detected ports */ + return 0; + } + memset((void *)info, 0, sizeof(struct esp_struct)); if (offset == 56) { diff -u --recursive --new-file v2.1.25/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c --- v2.1.25/linux/drivers/net/dgrs.c Thu Feb 6 12:42:03 1997 +++ linux/drivers/net/dgrs.c Mon Feb 3 13:05:51 1997 @@ -509,7 +509,7 @@ /* * There are three modes here for doing the packet copy. * If we have DMA, and the packet is "long", we use the - * chaining mode of DMA. If its shorter, we use single + * chaining mode of DMA. If it's shorter, we use single * DMA's. Otherwise, we use memcpy(). */ if (priv0->use_dma && priv0->dmadesc_h && len > 64) diff -u --recursive --new-file v2.1.25/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c --- v2.1.25/linux/drivers/net/ibmtr.c Thu Feb 6 12:42:04 1997 +++ linux/drivers/net/ibmtr.c Fri Feb 7 15:54:54 1997 @@ -175,19 +175,10 @@ static int tok_close(struct device *dev); static int tok_send_packet(struct sk_buff *skb, struct device *dev); static struct net_device_stats * tok_get_stats(struct device *dev); -void tr_readlog(struct device *dev); +void ibmtr_readlog(struct device *dev); +void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev); -/* FIXME: Should use init_timer and friends not assume the structure - is constant! */ - -static struct timer_list tr_timer = -{ - NULL, - NULL, - 0, - 0L, - tok_open_adapter -}; +static struct timer_list tr_timer; static unsigned int ibmtr_portlist[] = { 0xa20, 0xa24, 0 @@ -793,7 +784,7 @@ ti->current_skb=NULL; } dev->tbusy=0; - if (ti->readlog_pending) tr_readlog(dev); + if (ti->readlog_pending) ibmtr_readlog(dev); } } break; @@ -810,7 +801,7 @@ ti->current_skb=NULL; } dev->tbusy=0; - if (ti->readlog_pending) tr_readlog(dev); + if (ti->readlog_pending) ibmtr_readlog(dev); } } break; @@ -867,10 +858,7 @@ open_ret_code); if (ti->open_status != FAILURE) { - tr_timer.expires=jiffies+TR_RETRY_INTERVAL; - tr_timer.data=(unsigned long)dev; - tr_timer.next=tr_timer.prev=NULL; - add_timer(&tr_timer); + ibmtr_reset_timer(&tr_timer, dev); } } @@ -884,10 +872,7 @@ if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) { DPRINTK("open_sap failed: ret_code = %02X,retrying\n", (int)readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))); - tr_timer.expires=jiffies+TR_RETRY_INTERVAL; - tr_timer.data=(unsigned long)dev; - tr_timer.next=tr_timer.prev=NULL; - add_timer(&tr_timer); + ibmtr_reset_timer(&tr_timer, dev); } else { ti->exsap_station_id= readw(ti->srb+offsetof(struct dlc_open_sap, station_id)); @@ -998,11 +983,7 @@ DPRINTK("Signal loss/Lobe fault\n"); DPRINTK("We try to reopen the adapter.\n"); - tr_timer.expires=jiffies+TR_RETRY_INTERVAL; - tr_timer.data=(unsigned long)dev; - tr_timer.next=tr_timer.prev=NULL; - add_timer(&tr_timer); - + ibmtr_reset_timer(&tr_timer, dev); } else if (ring_status & (HARD_ERROR | XMIT_BEACON | AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER)) DPRINTK("New ring status: %02X\n", ring_status); @@ -1011,7 +992,7 @@ if (dev->tbusy) ti->readlog_pending = 1; else - tr_readlog(dev); + ibmtr_readlog(dev); } } break; @@ -1124,7 +1105,8 @@ DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr, ntohs(hw_encoded_addr), encoded_addr); #else - DPRINTK("Initial interrupt : shared RAM located at %08x.\n", ti->sram); + DPRINTK("Initial interrupt : %s Mbps, shared RAM base %08x.\n", + (readb(ti->init_srb+offsetof(struct srb_init_response, init_status)) & 0x01) ? "16" : "4", ti->sram); #endif ti->auto_ringspeedsave=readb(ti->init_srb @@ -1342,7 +1324,7 @@ dev_kfree_skb(ti->current_skb,FREE_WRITE); ti->current_skb=NULL; mark_bh(NET_BH); - if (ti->readlog_pending) tr_readlog(dev); + if (ti->readlog_pending) ibmtr_readlog(dev); } static void tr_rx(struct device *dev) @@ -1545,7 +1527,15 @@ return 0; } -void tr_readlog(struct device *dev) { +void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev) { + tmr->expires = jiffies + TR_RETRY_INTERVAL; + tmr->data = (unsigned long) dev; + tmr->function = tok_open_adapter; + init_timer(tmr); + add_timer(tmr); +} + +void ibmtr_readlog(struct device *dev) { struct tok_info *ti; ti=(struct tok_info *) dev->priv; diff -u --recursive --new-file v2.1.25/linux/drivers/net/pi2.h linux/drivers/net/pi2.h --- v2.1.25/linux/drivers/net/pi2.h Thu Feb 6 12:42:05 1997 +++ linux/drivers/net/pi2.h Fri Feb 7 15:54:54 1997 @@ -82,7 +82,7 @@ /* Information that needs to be kept for each channel. */ struct pi_local { - struct netstats stats; /* %%%dp*/ + struct net_device_stats stats; long open_time; /* Useless example local info. */ unsigned long xtal; diff -u --recursive --new-file v2.1.25/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c --- v2.1.25/linux/drivers/net/seeq8005.c Thu Feb 6 12:42:06 1997 +++ linux/drivers/net/seeq8005.c Fri Feb 7 15:54:54 1997 @@ -64,7 +64,7 @@ /* Information that need to be kept for each board. */ struct net_local { - struct net_driver_stats stats; + struct net_device_stats stats; unsigned short receive_ptr; /* What address in packet memory do we expect a recv_pkt_header? */ long open_time; /* Useless example local info. */ }; @@ -84,7 +84,7 @@ static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void seeq8005_rx(struct device *dev); static int seeq8005_close(struct device *dev); -static struct net_driver_stats *seeq8005_get_stats(struct device *dev); +static struct net_device_stats *seeq8005_get_stats(struct device *dev); static void set_multicast_list(struct device *dev); /* Example routines you must write ;->. */ @@ -593,7 +593,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_driver_stats *seeq8005_get_stats(struct device *dev) +static struct net_device_stats *seeq8005_get_stats(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; diff -u --recursive --new-file v2.1.25/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c --- v2.1.25/linux/drivers/net/sk_g16.c Thu Feb 6 12:42:08 1997 +++ linux/drivers/net/sk_g16.c Fri Feb 7 15:54:54 1997 @@ -457,7 +457,7 @@ int tmdlast; /* last sent descriptor used for error handling, etc */ void *rmdbufs[RMDNUM]; /* pointer to the receive buffers */ void *tmdbufs[TMDNUM]; /* pointer to the transmit buffers */ - struct net_driver_stats stats; /* Device driver statistics */ + struct net_device_stats stats; /* Device driver statistics */ }; /* global variable declaration */ @@ -491,7 +491,7 @@ static void SK_txintr(struct device *dev); static int SK_close(struct device *dev); -static struct net_driver_stats *SK_get_stats(struct device *dev); +static struct net_device_stats *SK_get_stats(struct device *dev); unsigned int SK_rom_addr(void); @@ -1681,14 +1681,14 @@ * It is called by sprintf_stats (dev.c). * * Parameters : I : struct device *dev - our device structure - * Return Value : struct net_driver_stats * - our current statistics + * Return Value : struct net_device_stats * - our current statistics * Errors : None * Side Effects : None * Update History : * YY/MM/DD uid Description -*/ -static struct net_driver_stats *SK_get_stats(struct device *dev) +static struct net_device_stats *SK_get_stats(struct device *dev) { struct priv *p = (struct priv *) dev->priv; diff -u --recursive --new-file v2.1.25/linux/drivers/net/smc9194.c linux/drivers/net/smc9194.c --- v2.1.25/linux/drivers/net/smc9194.c Thu Feb 6 12:42:09 1997 +++ linux/drivers/net/smc9194.c Fri Feb 7 15:54:54 1997 @@ -175,7 +175,7 @@ can find out semi-useless statistics of how well the card is performing */ - struct net_driver_stats stats; + struct net_device_stats stats; /* If I have to wait until memory is available to send @@ -234,7 +234,7 @@ . This routine allows the proc file system to query the driver's . statistics. */ -static struct net_driver_stats * smc_query_statistics( struct device *dev); +static struct net_device_stats * smc_query_statistics( struct device *dev); /* . Finally, a call to set promiscuous mode ( for TCPDUMP and related @@ -1643,7 +1643,7 @@ . Get the current statistics. . This may be called with the card open or closed. .-------------------------------------------------------------*/ -static struct net_driver_stats* smc_query_statistics(struct device *dev) { +static struct net_device_stats* smc_query_statistics(struct device *dev) { struct smc_local *lp = (struct smc_local *)dev->priv; return &lp->stats; diff -u --recursive --new-file v2.1.25/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.1.25/linux/drivers/pci/pci.c Tue Jan 28 18:50:07 1997 +++ linux/drivers/pci/pci.c Fri Feb 7 14:36:07 1997 @@ -152,6 +152,7 @@ DEVICE( 3COM, 3COM_3C595T4, "3C595 100bT4"), DEVICE( 3COM, 3COM_3C595MII, "3C595 100b-MII"), DEVICE( 3COM, 3COM_3C900TPO, "3C900 10bTPO"), + DEVICE( 3COM, 3COM_3C905TX, "3C905 100bTX"), DEVICE( AL, AL_M1445, "M1445"), DEVICE( AL, AL_M1449, "M1449"), DEVICE( AL, AL_M1451, "M1451"), @@ -270,8 +271,9 @@ DEVICE( ADAPTEC, ADAPTEC_7883, "AIC-7883U"), DEVICE( ADAPTEC, ADAPTEC_7884, "AIC-7884U"), DEVICE( ATRONICS, ATRONICS_2015, "IDE-2015PL"), - DEVICE( HER, HER_STING, "Stingray"), - DEVICE( HER, HER_STINGARK, "Stingray ARK 2000PV") + DEVICE( ARK, ARK_STING, "Stingray"), + DEVICE( ARK, ARK_STINGARK, "Stingray ARK 2000PV"), + DEVICE( ARK, ARK_2000MT, "2000MT") }; @@ -546,7 +548,7 @@ case PCI_VENDOR_ID_INTEL: return "Intel"; case PCI_VENDOR_ID_ADAPTEC: return "Adaptec"; case PCI_VENDOR_ID_ATRONICS: return "Atronics"; - case PCI_VENDOR_ID_HER: return "Hercules"; + case PCI_VENDOR_ID_ARK: return "ARK Logic"; default: return "Unknown vendor"; } } diff -u --recursive --new-file v2.1.25/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.1.25/linux/drivers/scsi/scsi.c Thu Feb 6 12:42:10 1997 +++ linux/drivers/scsi/scsi.c Fri Feb 7 14:02:08 1997 @@ -238,7 +238,6 @@ {"MAXTOR","XT-4170S","B5A", BLIST_NOLUN}, /* Locks-up sometimes when LUN>0 polled. */ {"MAXTOR","XT-8760S","B7B", BLIST_NOLUN}, /* guess what? */ {"MEDIAVIS","RENO CD-ROMX2A","2.03",BLIST_NOLUN},/*Responds to all lun */ -{"HP", "C3725S", "*", BLIST_NOTQ}, /* Buggy Tagged Queuing */ {"MICROP", "4110", "*", BLIST_NOTQ}, /* Buggy Tagged Queuing */ {"NEC","CD-ROM DRIVE:841","1.0", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */ {"RODIME","RO3000S","2.33", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ diff -u --recursive --new-file v2.1.25/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c --- v2.1.25/linux/drivers/scsi/scsi_ioctl.c Thu Dec 12 19:37:07 1996 +++ linux/drivers/scsi/scsi_ioctl.c Fri Feb 7 14:34:19 1997 @@ -247,6 +247,7 @@ retries = 1; break; case START_STOP: + case MOVE_MEDIUM: timeout = 60 * HZ; /* 60 seconds */ retries = 1; break; diff -u --recursive --new-file v2.1.25/linux/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c --- v2.1.25/linux/fs/nfs/nfsroot.c Tue Jan 28 18:50:18 1997 +++ linux/fs/nfs/nfsroot.c Fri Feb 7 15:54:54 1997 @@ -598,6 +598,7 @@ iov.iov_base = buf; iov.iov_len = size; msg.msg_name = NULL; + msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; @@ -624,6 +625,7 @@ iov.iov_base = buf; iov.iov_len = size; msg.msg_name = NULL; + msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; diff -u --recursive --new-file v2.1.25/linux/fs/select.c linux/fs/select.c --- v2.1.25/linux/fs/select.c Tue Jan 28 18:50:22 1997 +++ linux/fs/select.c Thu Feb 6 12:51:45 1997 @@ -62,25 +62,31 @@ } /* - * Due to kernel stack usage, we use a _limited_ fd_set type here, and once - * we really start supporting >256 file descriptors we'll probably have to - * allocate the kernel fd_set copies dynamically.. (The kernel select routines - * are careful to touch only the defined low bits of any fd_set pointer, this - * is important for performance too). + * For the kernel fd_set we use a fixed set-size for allocation purposes. + * This set-size doesn't necessarily bear any relation to the size the user + * uses, but should preferably obviously be larger than any possible user + * size (NR_OPEN bits). + * + * We need 6 bitmaps (in/out/ex for both incoming and outgoing), and we + * allocate one page for all the bitmaps. Thus we have 8*PAGE_SIZE bits, + * to be divided by 6. And we'd better make sure we round to a full + * long-word (in fact, we'll round to 64 bytes). */ -typedef unsigned long limited_fd_set[NR_OPEN/(8*(sizeof(unsigned long)))]; +#define KFDS_64BLOCK ((PAGE_SIZE/(6*64))*64) +#define KFDS_NR (KFDS_64BLOCK*8 > NR_OPEN ? NR_OPEN : KFDS_64BLOCK*8) +typedef unsigned long kernel_fd_set[KFDS_NR/(8*sizeof(unsigned long))]; typedef struct { - limited_fd_set in, out, ex; - limited_fd_set res_in, res_out, res_ex; + kernel_fd_set in, out, ex; + kernel_fd_set res_in, res_out, res_ex; } fd_set_buffer; #define __IN(in) (in) -#define __OUT(in) (in + sizeof(limited_fd_set)/sizeof(unsigned long)) -#define __EX(in) (in + 2*sizeof(limited_fd_set)/sizeof(unsigned long)) -#define __RES_IN(in) (in + 3*sizeof(limited_fd_set)/sizeof(unsigned long)) -#define __RES_OUT(in) (in + 4*sizeof(limited_fd_set)/sizeof(unsigned long)) -#define __RES_EX(in) (in + 5*sizeof(limited_fd_set)/sizeof(unsigned long)) +#define __OUT(in) (in + sizeof(kernel_fd_set)/sizeof(unsigned long)) +#define __EX(in) (in + 2*sizeof(kernel_fd_set)/sizeof(unsigned long)) +#define __RES_IN(in) (in + 3*sizeof(kernel_fd_set)/sizeof(unsigned long)) +#define __RES_OUT(in) (in + 4*sizeof(kernel_fd_set)/sizeof(unsigned long)) +#define __RES_EX(in) (in + 5*sizeof(kernel_fd_set)/sizeof(unsigned long)) #define BITS(in) (*__IN(in)|*__OUT(in)|*__EX(in)) @@ -277,17 +283,20 @@ asmlinkage int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp) { int error = -EINVAL; - fd_set_buffer fds; + fd_set_buffer *fds; unsigned long timeout; lock_kernel(); + fds = (fd_set_buffer *) __get_free_page(GFP_KERNEL); + if (!fds) + goto out; if (n < 0) goto out; - if (n > NR_OPEN) - n = NR_OPEN; - if ((error = get_fd_set(n, inp, &fds.in)) || - (error = get_fd_set(n, outp, &fds.out)) || - (error = get_fd_set(n, exp, &fds.ex))) goto out; + if (n > KFDS_NR) + n = KFDS_NR; + if ((error = get_fd_set(n, inp, &fds->in)) || + (error = get_fd_set(n, outp, &fds->out)) || + (error = get_fd_set(n, exp, &fds->ex))) goto out; timeout = ~0UL; if (tvp) { error = verify_area(VERIFY_WRITE, tvp, sizeof(*tvp)); @@ -303,11 +312,11 @@ if (timeout) timeout += jiffies + 1; } - zero_fd_set(n, &fds.res_in); - zero_fd_set(n, &fds.res_out); - zero_fd_set(n, &fds.res_ex); + zero_fd_set(n, &fds->res_in); + zero_fd_set(n, &fds->res_out); + zero_fd_set(n, &fds->res_ex); current->timeout = timeout; - error = do_select(n, &fds); + error = do_select(n, fds); timeout = current->timeout - jiffies - 1; current->timeout = 0; if ((long) timeout < 0) @@ -326,10 +335,11 @@ goto out; error = 0; } - set_fd_set(n, inp, &fds.res_in); - set_fd_set(n, outp, &fds.res_out); - set_fd_set(n, exp, &fds.res_ex); + set_fd_set(n, inp, &fds->res_in); + set_fd_set(n, outp, &fds->res_out); + set_fd_set(n, exp, &fds->res_ex); out: + free_page((unsigned long) fds); unlock_kernel(); return error; } @@ -376,15 +386,12 @@ asmlinkage int sys_poll(struct pollfd * ufds, unsigned int nfds, int timeout) { - int i, count, fdcount, err = -EINVAL; + int i, count, fdcount, err; struct pollfd * fds, *fds1; poll_table wait_table; struct poll_table_entry *entry; lock_kernel(); - if (nfds > NR_OPEN) - goto out; - err = -ENOMEM; entry = (struct poll_table_entry *) __get_free_page(GFP_KERNEL); if (!entry) diff -u --recursive --new-file v2.1.25/linux/include/asm-alpha/checksum.h linux/include/asm-alpha/checksum.h --- v2.1.25/linux/include/asm-alpha/checksum.h Sat Nov 30 12:03:11 1996 +++ linux/include/asm-alpha/checksum.h Thu Feb 6 12:44:41 1997 @@ -44,9 +44,16 @@ /* * the same as csum_partial, but copies from user space (but on the alpha * we have just one address space, so this is identical to the above) + * + * this is obsolete and will go away. */ #define csum_partial_copy_fromuser csum_partial_copy +/* + * this is a new version of the above that records errors it finds in *errp, + * but continues and zeros the rest of the buffer. + */ +unsigned int csum_partial_copy_from_user(int *errp, char *src, char *dst, int len, unsigned int sum); /* * this routine is used for miscellaneous IP-like checksums, mainly diff -u --recursive --new-file v2.1.25/linux/include/asm-alpha/current.h linux/include/asm-alpha/current.h --- v2.1.25/linux/include/asm-alpha/current.h Tue Dec 31 21:41:08 1996 +++ linux/include/asm-alpha/current.h Thu Feb 6 14:42:35 1997 @@ -3,10 +3,10 @@ /* Some architectures may want to do something "clever" here since * this is the most frequently accessed piece of data in the entire - * kernel. For an example, see the Sparc implementation where an - * entire register is hard locked to contain the value of current. + * kernel. */ extern struct task_struct *current_set[NR_CPUS]; -#define current (current_set[smp_processor_id()]) /* Current on this processor */ + +register struct task_struct *current __asm__("$8"); #endif /* !(_ALPHA_CURRENT_H) */ diff -u --recursive --new-file v2.1.25/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h --- v2.1.25/linux/include/asm-alpha/system.h Wed Aug 21 09:12:49 1996 +++ linux/include/asm-alpha/system.h Thu Feb 6 14:42:35 1997 @@ -56,8 +56,8 @@ #define halt() __asm__ __volatile__ ("call_pal %0" : : "i" (PAL_halt) : "memory") #define switch_to(prev,next) do { \ - current_set[0] = next; \ - alpha_switch_to((unsigned long) &(next)->tss - 0xfffffc0000000000); \ + current_set[0] = current = next; \ + alpha_switch_to((unsigned long) ¤t->tss - 0xfffffc0000000000); \ } while (0) extern void alpha_switch_to(unsigned long pctxp); diff -u --recursive --new-file v2.1.25/linux/include/asm-i386/checksum.h linux/include/asm-i386/checksum.h --- v2.1.25/linux/include/asm-i386/checksum.h Thu Feb 6 12:42:11 1997 +++ linux/include/asm-i386/checksum.h Fri Feb 7 15:54:54 1997 @@ -23,26 +23,42 @@ * better 64-bit) boundary */ -unsigned int csum_partial_copy_from_user( int * err, const char *src, - char *dst, int len, int sum); +unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum, + int *src_err_ptr, int *dst_err_ptr); + +extern __inline__ +unsigned int csum_partial_copy_nocheck ( const char *src, char *dst, + int len, int sum) +{ + int *src_err_ptr=NULL, *dst_err_ptr=NULL; + + return csum_partial_copy_generic ( src, dst, len, sum, src_err_ptr, dst_err_ptr); +} + +extern __inline__ +unsigned int csum_partial_copy_from_user ( const char *src, char *dst, + int len, int sum, int *err_ptr) +{ + int *dst_err_ptr=NULL; + + return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, dst_err_ptr); +} /* - * I hope GCC will optimize 'dummy' away ... + * This combination is currently not used, but possible: */ -unsigned int csum_partial_copy_nocheck_generic( int * err, const char *src, char *dst, - int len, int sum); - -extern __inline__ unsigned int csum_partial_copy_nocheck ( const char *src, char *dst, - int len, int sum) +extern __inline__ +unsigned int csum_partial_copy_to_user ( const char *src, char *dst, + int len, int sum, int *err_ptr) { - int dummy; + int *src_err_ptr=NULL; - return csum_partial_copy_nocheck_generic ( &dummy, src, dst, len, sum); + return csum_partial_copy_generic ( src, dst, len, sum, src_err_ptr, err_ptr); } /* - * These are the 'old' way of doing checksums, a warning message will be + * These are the old (and unsafe) way of doing checksums, a warning message will be * printed if they are used and an exeption occurs. * * these functions should go away after some time. diff -u --recursive --new-file v2.1.25/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.1.25/linux/include/linux/fs.h Tue Jan 28 18:50:54 1997 +++ linux/include/linux/fs.h Thu Feb 6 12:53:33 1997 @@ -27,7 +27,7 @@ /* Fixed constants first: */ #undef NR_OPEN -#define NR_OPEN 256 +#define NR_OPEN 1024 #define NR_SUPER 64 #define BLOCK_SIZE 1024 diff -u --recursive --new-file v2.1.25/linux/include/linux/icmp.h linux/include/linux/icmp.h --- v2.1.25/linux/include/linux/icmp.h Wed Dec 18 15:59:03 1996 +++ linux/include/linux/icmp.h Fri Feb 7 15:54:54 1997 @@ -80,11 +80,12 @@ } un; }; +#ifdef __KERNEL__ struct icmp_err { int errno; unsigned fatal:1; }; - +#endif #endif /* _LINUX_ICMP_H */ diff -u --recursive --new-file v2.1.25/linux/include/linux/if_tr.h linux/include/linux/if_tr.h --- v2.1.25/linux/include/linux/if_tr.h Sun Mar 24 12:09:37 1996 +++ linux/include/linux/if_tr.h Fri Feb 7 15:54:55 1997 @@ -94,8 +94,8 @@ #define TR_RII 0x80 #define TR_RCF_DIR_BIT 0x80 #define TR_RCF_LEN_MASK 0x1f00 -#define TR_RCF_BROADCAST 0x8000 -#define TR_RCF_LIMITED_BROADCAST 0xA000 +#define TR_RCF_BROADCAST 0x8000 /* all-routes broadcast */ +#define TR_RCF_LIMITED_BROADCAST 0xC000 /* single-route broadcast */ #define TR_RCF_FRAME2K 0x20 #define TR_RCF_BROADCAST_MASK 0xC000 diff -u --recursive --new-file v2.1.25/linux/include/linux/limits.h linux/include/linux/limits.h --- v2.1.25/linux/include/linux/limits.h Sun Nov 10 20:12:14 1996 +++ linux/include/linux/limits.h Thu Feb 6 12:38:33 1997 @@ -1,7 +1,7 @@ #ifndef _LINUX_LIMITS_H #define _LINUX_LIMITS_H -#define NR_OPEN 256 +#define NR_OPEN 1024 #define NGROUPS_MAX 32 /* supplemental group IDs are available */ #define ARG_MAX 131072 /* # bytes of args + environ for exec() */ diff -u --recursive --new-file v2.1.25/linux/include/linux/netdevice.h linux/include/linux/netdevice.h --- v2.1.25/linux/include/linux/netdevice.h Thu Feb 6 12:42:11 1997 +++ linux/include/linux/netdevice.h Fri Feb 7 15:54:55 1997 @@ -185,12 +185,6 @@ unsigned char if_port; /* Selectable AUI, TP,..*/ unsigned char dma; /* DMA channel */ - /* - * FIXME: - * The description 'enet_statistics' is misleading. We - * should change this. - */ - struct net_device_stats* (*get_stats)(struct device *dev); struct iw_statistics* (*get_wireless_stats)(struct device *dev); diff -u --recursive --new-file v2.1.25/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.1.25/linux/include/linux/pci.h Tue Jan 28 18:50:56 1997 +++ linux/include/linux/pci.h Fri Feb 7 15:54:55 1997 @@ -31,14 +31,14 @@ * PCI-CPU bridge or PCI-ISA bridge. * - If you can't find the actual information in your hardware * booklet, try to read the references of the chip on the board. - * - Send all that to linux-pcisupport@cao-vlsi.ibp.fr, + * - Send all that to linux-pcisupport@cck.uni-kl.de * and I'll add your device to the list as soon as possible * * BEFORE you send a mail, please check the latest linux releases * to be sure it has not been recently added. * * Thanks - * Frederic Potter. + * Jens Maurer */ @@ -418,6 +418,7 @@ #define PCI_DEVICE_ID_3COM_3C595T4 0x5951 #define PCI_DEVICE_ID_3COM_3C595MII 0x5952 #define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 +#define PCI_DEVICE_ID_3COM_3C905TX 0x9050 #define PCI_VENDOR_ID_AL 0x10b9 #define PCI_DEVICE_ID_AL_M1445 0x1445 @@ -607,9 +608,10 @@ #define PCI_VENDOR_ID_ATRONICS 0x907f #define PCI_DEVICE_ID_ATRONICS_2015 0x2015 -#define PCI_VENDOR_ID_HER 0xedd8 -#define PCI_DEVICE_ID_HER_STING 0xa091 -#define PCI_DEVICE_ID_HER_STINGARK 0xa099 +#define PCI_VENDOR_ID_ARK 0xedd8 +#define PCI_DEVICE_ID_ARK_STING 0xa091 +#define PCI_DEVICE_ID_ARK_STINGARK 0xa099 +#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1 /* * The PCI interface treats multi-function devices as independent diff -u --recursive --new-file v2.1.25/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h --- v2.1.25/linux/include/linux/proc_fs.h Sun Feb 2 15:46:21 1997 +++ linux/include/linux/proc_fs.h Fri Feb 7 15:54:55 1997 @@ -127,6 +127,7 @@ PROC_NET_X25_LINKS, PROC_NET_X25_ROUTES, PROC_NET_X25, + PROC_NET_TR_RIF, PROC_NET_LAST }; diff -u --recursive --new-file v2.1.25/linux/include/linux/sched.h linux/include/linux/sched.h --- v2.1.25/linux/include/linux/sched.h Sun Feb 2 15:46:21 1997 +++ linux/include/linux/sched.h Thu Feb 6 12:53:33 1997 @@ -127,7 +127,7 @@ struct fs_struct { int count; - unsigned short umask; + int umask; struct inode * root, * pwd; }; diff -u --recursive --new-file v2.1.25/linux/include/linux/sysctl.h linux/include/linux/sysctl.h --- v2.1.25/linux/include/linux/sysctl.h Thu Feb 6 12:42:12 1997 +++ linux/include/linux/sysctl.h Fri Feb 7 15:54:55 1997 @@ -84,6 +84,7 @@ #define NET_IPV6 11 #define NET_ROSE 12 #define NET_X25 13 +#define NET_TR 14 /* /proc/sys/net/core */ @@ -164,6 +165,12 @@ NET_X25_RESET_REQUEST_TIMEOUT, NET_X25_CLEAR_REQUEST_TIMEOUT, NET_X25_ACK_HOLD_BACK_TIMEOUT +}; + +/* /proc/sys/net/token-ring */ +enum +{ + NET_TR_RIF_TIMEOUT=1 }; /* CTL_PROC names: */ diff -u --recursive --new-file v2.1.25/linux/include/net/lapb.h linux/include/net/lapb.h --- v2.1.25/linux/include/net/lapb.h Thu Jan 23 21:06:52 1997 +++ linux/include/net/lapb.h Tue Feb 4 16:44:24 1997 @@ -44,11 +44,11 @@ #define LAPB_ADDR_D 0x07 /* Define Link State constants. */ -#define LAPB_STATE_0 0 -#define LAPB_STATE_1 1 -#define LAPB_STATE_2 2 -#define LAPB_STATE_3 3 -#define LAPB_STATE_4 4 +#define LAPB_STATE_0 0 /* Disconnected State */ +#define LAPB_STATE_1 1 /* Awaiting Connection State */ +#define LAPB_STATE_2 2 /* Awaiting Disconnection State */ +#define LAPB_STATE_3 3 /* Data Transfer State */ +#define LAPB_STATE_4 4 /* Frame Reject State */ #define LAPB_DEFAULT_MODE (LAPB_STANDARD | LAPB_SLP | LAPB_DTE) #define LAPB_DEFAULT_WINDOW 7 /* Window=7 */ @@ -69,6 +69,7 @@ unsigned short n2, n2count; unsigned short t1, t2; unsigned short t1timer, t2timer; + struct sk_buff_head input_queue; struct sk_buff_head write_queue; struct sk_buff_head ack_queue; unsigned char window; @@ -77,7 +78,6 @@ } lapb_cb; /* lapb_iface.c */ -extern lapb_cb *lapb_tokentostruct(void *); extern void lapb_connect_confirmation(lapb_cb *, int); extern void lapb_connect_indication(lapb_cb *, int); extern void lapb_disconnect_confirmation(lapb_cb *, int); @@ -86,13 +86,12 @@ extern int lapb_data_transmit(lapb_cb *, struct sk_buff *); /* lapb_in.c */ +extern void lapb_data_input(lapb_cb *, struct sk_buff *); /* lapb_out.c */ extern void lapb_kick(lapb_cb *); extern void lapb_transmit_buffer(lapb_cb *, struct sk_buff *, int); -extern void lapb_nr_error_recovery(lapb_cb *); extern void lapb_establish_data_link(lapb_cb *); -extern void lapb_transmit_enquiry(lapb_cb *); extern void lapb_enquiry_response(lapb_cb *); extern void lapb_timeout_response(lapb_cb *); extern void lapb_check_iframes_acked(lapb_cb *, unsigned short); diff -u --recursive --new-file v2.1.25/linux/include/scsi/scsi.h linux/include/scsi/scsi.h --- v2.1.25/linux/include/scsi/scsi.h Mon Jul 8 13:09:16 1996 +++ linux/include/scsi/scsi.h Fri Feb 7 14:34:19 1997 @@ -74,12 +74,14 @@ #define LOG_SENSE 0x4d #define MODE_SELECT_10 0x55 #define MODE_SENSE_10 0x5a +#define MOVE_MEDIUM 0xa5 #define READ_12 0xa8 #define WRITE_12 0xaa #define WRITE_VERIFY_12 0xae #define SEARCH_HIGH_12 0xb0 #define SEARCH_EQUAL_12 0xb1 #define SEARCH_LOW_12 0xb2 +#define READ_ELEMENT_STATUS 0xb8 #define SEND_VOLUME_TAG 0xb6 #define WRITE_LONG_2 0xea diff -u --recursive --new-file v2.1.25/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.1.25/linux/kernel/ksyms.c Tue Jan 28 18:50:57 1997 +++ linux/kernel/ksyms.c Fri Feb 7 15:54:55 1997 @@ -49,7 +49,7 @@ #include #include -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) extern struct drive_info_struct drive_info; #endif @@ -202,7 +202,7 @@ EXPORT_SYMBOL(resetup_one_dev); EXPORT_SYMBOL(unplug_device); -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) EXPORT_SYMBOL(drive_info); #endif diff -u --recursive --new-file v2.1.25/linux/kernel/sched.c linux/kernel/sched.c --- v2.1.25/linux/kernel/sched.c Thu Feb 6 12:42:12 1997 +++ linux/kernel/sched.c Fri Feb 7 15:54:55 1997 @@ -1187,23 +1187,32 @@ #endif } -static unsigned long lost_ticks = 0; +volatile unsigned long lost_ticks = 0; static unsigned long lost_ticks_system = 0; static inline void update_times(void) { unsigned long ticks; + unsigned long flags; - ticks = xchg(&lost_ticks, 0); + save_flags(flags); + cli(); + + ticks = lost_ticks; + lost_ticks = 0; if (ticks) { unsigned long system; - system = xchg(&lost_ticks_system, 0); + calc_load(ticks); update_wall_time(ticks); + restore_flags(flags); + update_process_times(ticks, system); - } + + } else + restore_flags(flags); } static void timer_bh(void) @@ -1349,21 +1358,21 @@ { unsigned long newprio; int increase = 0; - int ret = -EPERM; /* - * We need a lock. sys_setpriority can affect other tasks. + * Setpriority might change our priority at the same moment. + * We don't have to worry. Conceptually one call occurs first + * and we have a single winner. */ - lock_kernel(); newprio = increment; if (increment < 0) { if (!suser()) - goto out; + return -EPERM; newprio = -increment; increase = 1; } - ret = 0; + if (newprio > 40) newprio = 40; /* @@ -1377,15 +1386,21 @@ increment = newprio; if (increase) increment = -increment; + /* + * Current->priority can change between this point + * and the assignment. We are assigning not doing add/subs + * so thats ok. Conceptually a process might just instantaneously + * read the value we stomp over. I don't think that is an issue + * unless posix makes it one. If so we can loop on changes + * to current->priority. + */ newprio = current->priority - increment; if ((signed) newprio < 1) newprio = 1; if (newprio > DEF_PRIORITY*2) newprio = DEF_PRIORITY*2; current->priority = newprio; -out: - unlock_kernel(); - return ret; + return 0; } #endif diff -u --recursive --new-file v2.1.25/linux/kernel/signal.c linux/kernel/signal.c --- v2.1.25/linux/kernel/signal.c Tue Jan 28 18:50:57 1997 +++ linux/kernel/signal.c Tue Feb 4 16:44:25 1997 @@ -72,9 +72,8 @@ { int ret; - lock_kernel(); + /* SMP safe */ ret = current->blocked; - unlock_kernel(); return ret; } diff -u --recursive --new-file v2.1.25/linux/kernel/sys.c linux/kernel/sys.c --- v2.1.25/linux/kernel/sys.c Thu Feb 6 12:42:12 1997 +++ linux/kernel/sys.c Tue Feb 4 16:44:25 1997 @@ -205,18 +205,17 @@ */ asmlinkage int sys_reboot(int magic, int magic_too, int flag) { - int error = -EPERM; - - lock_kernel(); if (!suser()) - goto out; - error = -EINVAL; + return -EPERM; if (magic != 0xfee1dead || (magic_too != 672274793 && magic_too != 85072278)) - goto out; - error = 0; + return -EINVAL; + + if (flag == 0x01234567) { + /* SMP: We need to lock during the shutdown still */ + lock_kernel(); notifier_call_chain(&boot_notifier_list, SYS_DOWN, NULL); hard_reset_now(); } @@ -225,6 +224,8 @@ else if (!flag) C_A_D = 0; else if (flag == 0xCDEF0123) { + /* SMP: We need to lock during the shutdown still */ + lock_kernel(); printk(KERN_EMERG "System halted\n"); #ifdef __sparc__ halt_now(); @@ -236,10 +237,8 @@ notifier_call_chain(&boot_notifier_list, SYS_HALT, NULL); do_exit(0); } else - error = -EINVAL; -out: - unlock_kernel(); - return error; + return -EINVAL; + return 0; } /* @@ -659,24 +658,21 @@ asmlinkage long sys_times(struct tms * tbuf) { - int error; - - lock_kernel(); - if (tbuf) { - error = put_user(current->utime,&tbuf->tms_utime); - if (!error) - error = put_user(current->stime,&tbuf->tms_stime); - if (!error) - error = put_user(current->cutime,&tbuf->tms_cutime); - if (!error) - error = put_user(current->cstime,&tbuf->tms_cstime); - if (error) - goto out; + /* + * In the SMP world we might just be unlucky and have one of + * the times increment as we use it. Since the value is an + * atomically safe type this is just fine. Conceptually its + * as if the syscall took an instant longer to occur. + */ + if (tbuf) + { + if(put_user(current->utime,&tbuf->tms_utime)|| + put_user(current->stime,&tbuf->tms_stime) || + put_user(current->cutime,&tbuf->tms_cutime) || + put_user(current->cstime,&tbuf->tms_cstime)) + return -EFAULT; } - error = jiffies; -out: - unlock_kernel(); - return error; + return jiffies; } /* @@ -691,6 +687,7 @@ * Auch. Had to add the 'did_exec' flag to conform completely to POSIX. * LBT 04.03.94 */ + asmlinkage int sys_setpgid(pid_t pid, pid_t pgid) { struct task_struct * p; @@ -820,45 +817,40 @@ */ asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist) { - int i, err = -EINVAL; + int i; + + /* + * SMP: Nobody else can change our grouplist. Thus we are + * safe. + */ - lock_kernel(); if (gidsetsize < 0) - goto out; + return -EINVAL; i = current->ngroups; if (gidsetsize) { - err = -EINVAL; if (i > gidsetsize) - goto out; - err = -EFAULT; + return -EINVAL; if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i)) - goto out; + return -EFAULT; } - err = i; -out: - unlock_kernel(); - return err; + return i; } +/* + * SMP: Our groups are not shared. We can copy to/from them safely + * without another task interfering. + */ + asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist) { - int err = -EPERM; - - lock_kernel(); if (!suser()) - goto out; - err = -EINVAL; + return -EPERM; if ((unsigned) gidsetsize > NGROUPS) - goto out; - err = copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t)); - if (err) { - gidsetsize = 0; - err = -EFAULT; - } + return -EINVAL; + if(copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t))) + return -EFAULT; current->ngroups = gidsetsize; -out: - unlock_kernel(); - return err; + return 0; } int in_group_p(gid_t grp) diff -u --recursive --new-file v2.1.25/linux/kernel/time.c linux/kernel/time.c --- v2.1.25/linux/kernel/time.c Tue Jan 28 18:50:57 1997 +++ linux/kernel/time.c Fri Feb 7 15:54:55 1997 @@ -66,13 +66,13 @@ { int i; - lock_kernel(); + /* SMP: This is fairly trivial. We grab CURRENT_TIME and + stuff it to user space. No side effects */ i = CURRENT_TIME; if (tloc) { if (put_user(i,tloc)) i = -EFAULT; } - unlock_kernel(); return i; } @@ -82,16 +82,20 @@ * why not move it into the appropriate arch directory (for those * architectures that need it). */ + asmlinkage int sys_stime(int * tptr) { - int value = -EPERM; + int value; - lock_kernel(); if (!suser()) - goto out; - value = -EFAULT; + return -EPERM; if (get_user(value, tptr)) - goto out; + return -EFAULT; + /* + * SMP: We need to lock out everything for the time update + * the new cli/sti semantics will let us drop this lock soon. + */ + lock_kernel(); cli(); xtime.tv_sec = value; xtime.tv_usec = 0; @@ -99,10 +103,8 @@ time_maxerror = MAXPHASE; time_esterror = MAXPHASE; sti(); - value = 0; -out: unlock_kernel(); - return value; + return 0; } #endif diff -u --recursive --new-file v2.1.25/linux/net/802/fddi.c linux/net/802/fddi.c --- v2.1.25/linux/net/802/fddi.c Thu Jan 2 15:55:26 1997 +++ linux/net/802/fddi.c Tue Feb 4 16:44:25 1997 @@ -52,18 +52,23 @@ int fddi_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { - struct fddihdr *fddi = (struct fddihdr *)skb_push(skb, FDDI_K_SNAP_HLEN); - - /* Fill in frame header - assume 802.2 SNAP frames for now */ - + int hl = FDDI_K_SNAP_HLEN; + struct fddihdr *fddi; + + if(type!=htons(ETH_P_IP)) + hl=FDDI_K_8022_HLEN-3; + fddi = (struct fddihdr *)skb_push(skb, hl); fddi->fc = FDDI_FC_K_ASYNC_LLC_DEF; - fddi->hdr.llc_snap.dsap = FDDI_EXTENDED_SAP; - fddi->hdr.llc_snap.ssap = FDDI_EXTENDED_SAP; - fddi->hdr.llc_snap.ctrl = FDDI_UI_CMD; - fddi->hdr.llc_snap.oui[0] = 0x00; - fddi->hdr.llc_snap.oui[1] = 0x00; - fddi->hdr.llc_snap.oui[2] = 0x00; - fddi->hdr.llc_snap.ethertype = htons(type); + if(type==htons(ETH_P_IP)) + { + fddi->hdr.llc_snap.dsap = FDDI_EXTENDED_SAP; + fddi->hdr.llc_snap.ssap = FDDI_EXTENDED_SAP; + fddi->hdr.llc_snap.ctrl = FDDI_UI_CMD; + fddi->hdr.llc_snap.oui[0] = 0x00; + fddi->hdr.llc_snap.oui[1] = 0x00; + fddi->hdr.llc_snap.oui[2] = 0x00; + fddi->hdr.llc_snap.ethertype = htons(type); + } /* Set the source and destination hardware addresses */ @@ -75,9 +80,9 @@ if (daddr != NULL) { memcpy(fddi->daddr, daddr, dev->addr_len); - return(FDDI_K_SNAP_HLEN); + return(hl); } - return(-FDDI_K_SNAP_HLEN); + return(-hl); } @@ -114,15 +119,26 @@ unsigned short fddi_type_trans(struct sk_buff *skb, struct device *dev) { struct fddihdr *fddi = (struct fddihdr *)skb->data; - + unsigned short type; + /* * Set mac.raw field to point to FC byte, set data field to point * to start of packet data. Assume 802.2 SNAP frames for now. */ skb->mac.raw = skb->data; /* point to frame control (FC) */ - skb_pull(skb, FDDI_K_SNAP_HLEN); /* adjust for 21 byte header */ - + + if(fddi->hdr.llc_8022_1.dsap==0xe0) + { + skb_pull(skb, FDDI_K_8022_HLEN-3); + type=htons(ETH_P_8022); + } + else + { + skb_pull(skb, FDDI_K_SNAP_HLEN); /* adjust for 21 byte header */ + type=fddi->hdr.llc_snap.ethertype; + } + /* Set packet type based on destination address and flag settings */ if (*fddi->daddr & 0x01) @@ -141,5 +157,6 @@ /* Assume 802.2 SNAP frames, for now */ - return(fddi->hdr.llc_snap.ethertype); + return(type); + } diff -u --recursive --new-file v2.1.25/linux/net/802/p8022.c linux/net/802/p8022.c --- v2.1.25/linux/net/802/p8022.c Wed Jan 15 19:45:47 1997 +++ linux/net/802/p8022.c Fri Feb 7 15:54:55 1997 @@ -55,6 +55,7 @@ if (proto != NULL) { skb->h.raw += 3; + skb->nh.raw += 3; skb_pull(skb,3); return proto->rcvfunc(skb, dev, pt); } diff -u --recursive --new-file v2.1.25/linux/net/802/sysctl_net_802.c linux/net/802/sysctl_net_802.c --- v2.1.25/linux/net/802/sysctl_net_802.c Thu Jan 2 15:55:26 1997 +++ linux/net/802/sysctl_net_802.c Fri Feb 7 15:54:55 1997 @@ -16,3 +16,11 @@ ctl_table e802_table[] = { {0} }; + +#ifdef CONFIG_TR +extern int sysctl_tr_rif_timeout; +ctl_table tr_table[] = { + {NET_TR_RIF_TIMEOUT, "rif_timeout", &sysctl_tr_rif_timeout, sizeof(int), + 0644, NULL, &proc_dointvec}, +}; +#endif diff -u --recursive --new-file v2.1.25/linux/net/802/tr.c linux/net/802/tr.c --- v2.1.25/linux/net/802/tr.c Thu Jan 2 15:55:26 1997 +++ linux/net/802/tr.c Fri Feb 7 15:54:55 1997 @@ -6,7 +6,10 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Fixes: + * Fixes: 3 Feb 97 Paul Norton Minor routing fixes. + * Added rif table to /proc/net/tr_rif and rif timeout to + * /proc/sys/net/token-ring/rif_timeout. + * */ #include @@ -26,31 +29,35 @@ #include #include #include +#include #include -static void tr_source_route(struct trh_hdr *trh,struct device *dev); -static void tr_add_rif_info(struct trh_hdr *trh); +static void tr_source_route(struct trh_hdr *trh, struct device *dev); +static void tr_add_rif_info(struct trh_hdr *trh, struct device *dev); static void rif_check_expire(unsigned long dummy); +#define TR_SR_DEBUG 0 + typedef struct rif_cache_s *rif_cache; /* * Each RIF entry we learn is kept this way */ -struct rif_cache_s -{ - unsigned char addr[TR_ALEN]; - unsigned short rcf; - unsigned short rseg[8]; - rif_cache next; - unsigned long last_used; +struct rif_cache_s { + unsigned char addr[TR_ALEN]; + unsigned char iface[5]; + __u16 rcf; + __u8 rseg[8]; + rif_cache next; + unsigned long last_used; + unsigned char local_ring; }; -#define RIF_TABLE_SIZE 16 +#define RIF_TABLE_SIZE 32 /* - * We hash the RIF cache 16 ways. We do after all have to look it + * We hash the RIF cache 32 ways. We do after all have to look it * up a lot. */ @@ -63,11 +70,9 @@ * Garbage disposal timer. */ -static struct timer_list rif_timer= -{ - NULL,NULL,RIF_CHECK_INTERVAL,0L,rif_check_expire -}; +static struct timer_list rif_timer; +int sysctl_tr_rif_timeout = RIF_TIMEOUT; /* * Put the headers on a token ring packet. Token ring source routing @@ -130,7 +135,7 @@ */ if(trllc->ethertype != htons(ETH_P_IP)) { - printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n",(unsigned int)htons( trllc->ethertype)); + printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n",(unsigned int)htons(trllc->ethertype)); return 0; } @@ -160,8 +165,7 @@ skb_pull(skb,dev->hard_header_len); - if(trh->saddr[0] & TR_RII) - tr_add_rif_info(trh); + tr_add_rif_info(trh, dev); if(*trh->daddr & 1) { @@ -214,11 +218,11 @@ */ if(entry) { -#if 0 +#if TR_SR_DEBUG printk("source routing for %02X %02X %02X %02X %02X %02X\n",trh->daddr[0], trh->daddr[1],trh->daddr[2],trh->daddr[3],trh->daddr[4],trh->daddr[5]); #endif - if((ntohs(entry->rcf) & TR_RCF_LEN_MASK) >> 8) + if(!entry->local_ring && (ntohs(entry->rcf) & TR_RCF_LEN_MASK) >> 8) { trh->rcf=entry->rcf; memcpy(&trh->rseg[0],&entry->rseg[0],8*sizeof(unsigned short)); @@ -226,8 +230,15 @@ trh->rcf&=htons(0x1fff); /* Issam Chehab */ trh->saddr[0]|=TR_RII; - entry->last_used=jiffies; +#if TR_SR_DEBUG + printk("entry found with rcf %04x\n", entry->rcf); + } + else + { + printk("entry found but without rcf length, local=%02x\n", entry->local_ring); +#endif } + entry->last_used=jiffies; } else { @@ -239,6 +250,7 @@ trh->rcf=htons((((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK) | TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST); trh->saddr[0]|=TR_RII; + printk("no entry in rif table found - broadcasting frame\n"); } } } @@ -248,27 +260,36 @@ * routing. */ -static void tr_add_rif_info(struct trh_hdr *trh) +static void tr_add_rif_info(struct trh_hdr *trh, struct device *dev) { int i; - unsigned int hash; + unsigned int hash, rii_p = 0; rif_cache entry; /* * Firstly see if the entry exists */ - trh->saddr[0]&=0x7f; + + if(trh->saddr[0] & TR_RII) + { + trh->saddr[0]&=0x7f; + if (((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2) + { + rii_p = 1; + } + } + for(i=0,hash=0;isaddr[i++]); hash&=RIF_TABLE_SIZE-1; for(entry=rif_table[hash];entry && memcmp(&(entry->addr[0]),&(trh->saddr[0]),TR_ALEN);entry=entry->next); if(entry==NULL) { -#if 0 +#if TR_SR_DEBUG printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", trh->saddr[0],trh->saddr[1],trh->saddr[2], trh->saddr[3],trh->saddr[4],trh->saddr[5], - trh->rcf); + ntohs(trh->rcf)); #endif /* * Allocate our new entry. A failure to allocate loses @@ -278,14 +299,26 @@ * limiting and adjust the timers to suit. */ entry=kmalloc(sizeof(struct rif_cache_s),GFP_ATOMIC); + if(!entry) { printk(KERN_DEBUG "tr.c: Couldn't malloc rif cache entry !\n"); return; } - entry->rcf=trh->rcf; - memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short)); + + if (rii_p) + { + entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK); + memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short)); + entry->local_ring = 0; + } + else + { + entry->local_ring = 1; + } + memcpy(&(entry->addr[0]),&(trh->saddr[0]),TR_ALEN); + memcpy(&(entry->iface[0]),dev->name,5); entry->next=rif_table[hash]; entry->last_used=jiffies; rif_table[hash]=entry; @@ -295,21 +328,20 @@ /* * Update existing entries */ - if ( entry->rcf != trh->rcf ) - { - if (!(trh->rcf & htons(TR_RCF_BROADCAST_MASK))) - { -#if 0 + if (!entry->local_ring) + if (entry->rcf != (trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK)) && + !(trh->rcf & htons(TR_RCF_BROADCAST_MASK))) + { +#if TR_SR_DEBUG printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", trh->saddr[0],trh->saddr[1],trh->saddr[2], trh->saddr[3],trh->saddr[4],trh->saddr[5], - trh->rcf); + ntohs(trh->rcf)); #endif - entry->rcf = trh->rcf; - memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short)); - entry->last_used=jiffies; - } - } + entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK); + memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short)); + } + entry->last_used=jiffies; } } @@ -333,7 +365,7 @@ /* * Out it goes */ - if((now-entry->last_used) > RIF_TIMEOUT) + if((now-entry->last_used) > sysctl_tr_rif_timeout) { *pentry=entry->next; kfree_s(entry,sizeof(struct rif_cache_s)); @@ -349,7 +381,7 @@ */ del_timer(&rif_timer); - rif_timer.expires=jiffies+RIF_CHECK_INTERVAL; + rif_timer.expires = jiffies + sysctl_tr_rif_timeout; add_timer(&rif_timer); } @@ -359,27 +391,46 @@ * routing. */ -int rif_get_info(char *buffer,char **start, off_t offset, int length) +#ifdef CONFIG_PROC_FS +int rif_get_info(char *buffer,char **start, off_t offset, int length, int dummy) { int len=0; off_t begin=0; off_t pos=0; - int size,i; + int size,i,j,rcf_len; + unsigned long now=jiffies; rif_cache entry; size=sprintf(buffer, - " TR address rcf routing segments TTL\n\n"); + "if TR address TTL rcf routing segments\n\n"); pos+=size; len+=size; for(i=0;i < RIF_TABLE_SIZE;i++) { for(entry=rif_table[i];entry;entry=entry->next) { - size=sprintf(buffer+len,"%02X:%02X:%02X:%02X:%02X:%02X %04X %04X %04X %04X %04X %04X %04X %04X %04X %lu\n", - entry->addr[0],entry->addr[1],entry->addr[2],entry->addr[3],entry->addr[4],entry->addr[5], - entry->rcf,entry->rseg[0],entry->rseg[1],entry->rseg[2],entry->rseg[3], - entry->rseg[4],entry->rseg[5],entry->rseg[6],entry->rseg[7],jiffies-entry->last_used); + size=sprintf(buffer+len,"%s %02X:%02X:%02X:%02X:%02X:%02X %7li ", + entry->iface,entry->addr[0],entry->addr[1],entry->addr[2],entry->addr[3],entry->addr[4],entry->addr[5], + sysctl_tr_rif_timeout-(now-entry->last_used)); + len+=size; + pos=begin+len; + if (entry->local_ring) + size=sprintf(buffer+len,"local\n"); + else { + size=sprintf(buffer+len,"%04X", ntohs(entry->rcf)); + rcf_len = ((ntohs(entry->rcf) & TR_RCF_LEN_MASK)>>8)-2; + if (rcf_len) + rcf_len >>= 1; + for(j = 0; j < rcf_len; j++) { + len+=size; + pos=begin+len; + size=sprintf(buffer+len," %04X",ntohs(entry->rseg[j])); + } + len+=size; + pos=begin+len; + size=sprintf(buffer+len,"\n"); + } len+=size; pos=begin+len; @@ -401,15 +452,28 @@ len=length; /* Ending slop */ return len; } +#endif /* * Called during bootup. We don't actually have to initialise - * too much for this. The timer structure is setup statically. Thats - * probably NOT a good thing if we change the structure. + * too much for this. */ void rif_init(struct net_proto *unused) { + + rif_timer.expires = RIF_TIMEOUT; + rif_timer.data = 0L; + rif_timer.function = rif_check_expire; + init_timer(&rif_timer); add_timer(&rif_timer); -} +#ifdef CONFIG_PROC_FS + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_TR_RIF, 6, "tr_rif", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + rif_get_info + }); +#endif +} diff -u --recursive --new-file v2.1.25/linux/net/core/sock.c linux/net/core/sock.c --- v2.1.25/linux/net/core/sock.c Tue Jan 28 18:50:58 1997 +++ linux/net/core/sock.c Tue Feb 4 16:44:25 1997 @@ -185,6 +185,10 @@ if(val > 65535) val = 65535; sk->sndbuf = val; + /* + * FIXME: Wake up sending tasks if we + * upped the value. + */ break; case SO_RCVBUF: diff -u --recursive --new-file v2.1.25/linux/net/ipv4/Config.in linux/net/ipv4/Config.in --- v2.1.25/linux/net/ipv4/Config.in Thu Feb 6 12:42:15 1997 +++ linux/net/ipv4/Config.in Fri Feb 7 15:54:55 1997 @@ -18,12 +18,10 @@ fi fi bool 'IP: accounting' CONFIG_IP_ACCT -if [ "$CONFIG_IP_FORWARD" = "y" ]; then - bool 'IP: optimize as router not host' CONFIG_IP_ROUTER - tristate 'IP: tunneling' CONFIG_NET_IPIP - if [ "$CONFIG_IP_MULTICAST" = "y" ]; then - bool 'IP: multicast routing' CONFIG_IP_MROUTE - fi +bool 'IP: optimize as router not host' CONFIG_IP_ROUTER +tristate 'IP: tunneling' CONFIG_NET_IPIP +if [ "$CONFIG_IP_MULTICAST" = "y" ]; then + bool 'IP: multicast routing' CONFIG_IP_MROUTE fi if [ "$CONFIG_NET_ALIAS" = "y" ]; then tristate 'IP: aliasing support' CONFIG_IP_ALIAS diff -u --recursive --new-file v2.1.25/linux/net/ipv4/arp.c linux/net/ipv4/arp.c --- v2.1.25/linux/net/ipv4/arp.c Thu Feb 6 12:42:15 1997 +++ linux/net/ipv4/arp.c Tue Feb 4 16:44:25 1997 @@ -54,6 +54,10 @@ * Stuart Cheshire : Metricom and grat arp fixes * *** FOR 2.1 clean this up *** * Lawrence V. Stefani: (08/12/96) Added FDDI support. + * Alan Cox : Took the AP1000 nasty FDDI hack and + * folded into the mainstream FDDI code. + * Ack spit, Linus how did you allow that + * one in... */ /* RFC1122 Status: @@ -1383,7 +1387,7 @@ * is not from an IP number. We can't currently handle this, so toss * it. */ -#ifdef CONFIG_FDDI +#if defined(CONFIG_FDDI) || defined(CONFIG_AP1000) if (dev->type == ARPHRD_FDDI) { /* @@ -1415,18 +1419,7 @@ } #else if (arp->ar_hln != dev->addr_len || -#if CONFIG_AP1000 - /* - * ARP from cafe-f was found to use ARPHDR_IEEE802 instead of - * the expected ARPHDR_ETHER. - */ - (strcmp(dev->name,"fddi") == 0 && - arp->ar_hrd != ARPHRD_ETHER && arp->ar_hrd != ARPHRD_IEEE802) || - (strcmp(dev->name,"fddi") != 0 && - dev->type != ntohs(arp->ar_hrd)) || -#else dev->type != ntohs(arp->ar_hrd) || -#endif dev->flags & IFF_NOARP || skb->pkt_type == PACKET_OTHERHOST || arp->ar_pln != 4) { @@ -1491,8 +1484,6 @@ tha=arp_ptr; arp_ptr += dev->addr_len; memcpy(&tip, arp_ptr, 4); - - /* * Check for bad requests for 127.x.x.x and requests for multicast * addresses. If this is one such, delete it. diff -u --recursive --new-file v2.1.25/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c --- v2.1.25/linux/net/ipv4/tcp.c Thu Feb 6 12:42:15 1997 +++ linux/net/ipv4/tcp.c Fri Feb 7 15:54:55 1997 @@ -1033,8 +1033,8 @@ skb->h.th->urg_ptr = ntohs(copy); } - skb->csum = csum_partial_copy_from_user(&err, from, - skb_put(skb, copy), copy, 0); + skb->csum = csum_partial_copy_from_user(from, + skb_put(skb, copy), copy, 0, &err); from += copy; copied += copy; diff -u --recursive --new-file v2.1.25/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c --- v2.1.25/linux/net/ipv4/tcp_ipv4.c Thu Feb 6 12:42:15 1997 +++ linux/net/ipv4/tcp_ipv4.c Tue Feb 4 16:44:25 1997 @@ -629,7 +629,7 @@ if (sk->ack_backlog >= sk->max_ack_backlog || tcp_v4_syn_filter(sk, skb, saddr)) { - printk(KERN_DEBUG "droping syn ack:%d max:%d\n", + printk(KERN_DEBUG "dropping syn ack:%d max:%d\n", sk->ack_backlog, sk->max_ack_backlog); #ifdef CONFIG_IP_TCPSF tcp_v4_random_drop(sk); diff -u --recursive --new-file v2.1.25/linux/net/ipv4/udp.c linux/net/ipv4/udp.c --- v2.1.25/linux/net/ipv4/udp.c Thu Feb 6 12:42:15 1997 +++ linux/net/ipv4/udp.c Fri Feb 7 15:54:55 1997 @@ -627,7 +627,7 @@ sk->ip_tos|sk->localroute); if (err) return err; - if (rt->rt_flags&RTF_BROADCAST && !sk->broadcast) { + if ((rt->rt_flags&RTF_BROADCAST) && !sk->broadcast) { ip_rt_put(rt); return -EACCES; } diff -u --recursive --new-file v2.1.25/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c --- v2.1.25/linux/net/ipx/af_ipx.c Sun Feb 2 15:46:22 1997 +++ linux/net/ipx/af_ipx.c Fri Feb 7 15:54:55 1997 @@ -2103,7 +2103,7 @@ ipx_interface *intrfc; struct ipxhdr *ipx; - skb->h.raw = (void *)ipx = skb->nh.ipxh; + ipx = skb->nh.ipxh; /* Too small? */ if(ntohs(ipx->ipx_pktsize) @@ -104,7 +107,7 @@ * Convert the integer token used by the device driver into a pointer * to a LAPB control structure. */ -lapb_cb *lapb_tokentostruct(void *token) +static lapb_cb *lapb_tokentostruct(void *token) { lapb_cb *lapb; @@ -129,6 +132,7 @@ memset(lapb, 0x00, sizeof(*lapb)); + skb_queue_head_init(&lapb->input_queue); skb_queue_head_init(&lapb->write_queue); skb_queue_head_init(&lapb->ack_queue); @@ -323,6 +327,18 @@ skb_queue_tail(&lapb->write_queue, skb); lapb_kick(lapb); + + return LAPB_OK; +} + +int lapb_data_received(void *token, struct sk_buff *skb) +{ + lapb_cb *lapb; + + if ((lapb = lapb_tokentostruct(token)) == NULL) + return LAPB_BADTOKEN; + + skb_queue_tail(&lapb->input_queue, skb); return LAPB_OK; } diff -u --recursive --new-file v2.1.25/linux/net/lapb/lapb_in.c linux/net/lapb/lapb_in.c --- v2.1.25/linux/net/lapb/lapb_in.c Thu Feb 6 12:42:15 1997 +++ linux/net/lapb/lapb_in.c Tue Feb 4 16:44:25 1997 @@ -312,6 +312,7 @@ lapb->condition = 0x00; lapb->t1timer = 0; lapb->t2timer = 0; + lapb->n2count = 0; lapb->vs = 0; lapb->vr = 0; lapb->va = 0; @@ -331,6 +332,7 @@ lapb->condition = 0x00; lapb->t1timer = 0; lapb->t2timer = 0; + lapb->n2count = 0; lapb->vs = 0; lapb->vr = 0; lapb->va = 0; @@ -384,7 +386,7 @@ #if LAPB_DEBUG > 0 printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->token); #endif - lapb_nr_error_recovery(lapb); + lapb_establish_data_link(lapb); lapb->state = LAPB_STATE_1; } break; @@ -401,7 +403,7 @@ #if LAPB_DEBUG > 0 printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->token); #endif - lapb_nr_error_recovery(lapb); + lapb_establish_data_link(lapb); lapb->state = LAPB_STATE_1; } break; @@ -415,12 +417,13 @@ if (lapb_validate_nr(lapb, nr)) { lapb_frames_acked(lapb, nr); lapb->t1timer = 0; + lapb->n2count = 0; lapb_requeue_frames(lapb); } else { #if LAPB_DEBUG > 0 printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->token); #endif - lapb_nr_error_recovery(lapb); + lapb_establish_data_link(lapb); lapb->state = LAPB_STATE_1; } break; @@ -433,7 +436,7 @@ #if LAPB_DEBUG > 0 printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->token); #endif - lapb_nr_error_recovery(lapb); + lapb_establish_data_link(lapb); lapb->state = LAPB_STATE_1; break; } @@ -490,284 +493,11 @@ } /* - * State machine for state 4, Timer Recovery State. - * The handling of the timer(s) is in file lapb_timer.c - */ -static void lapb_state4_machine(lapb_cb *lapb, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type) -{ - int queued = 0; - int modulus; - - modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS; - - switch (frametype) { - case LAPB_SABM: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 RX SABM(%d)\n", lapb->token, pf); -#endif - if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", lapb->token, pf); -#endif - lapb_send_control(lapb, LAPB_DM, pf, LAPB_RESPONSE); - } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", lapb->token, pf); -#endif - lapb_send_control(lapb, LAPB_UA, pf, LAPB_RESPONSE); - lapb->condition = 0x00; - lapb->t1timer = 0; - lapb->t2timer = 0; - lapb->vs = 0; - lapb->vr = 0; - lapb->va = 0; - lapb_requeue_frames(lapb); - } - break; - - case LAPB_SABME: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 RX SABME(%d)\n", lapb->token, pf); -#endif - if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", lapb->token, pf); -#endif - lapb_send_control(lapb, LAPB_UA, pf, LAPB_RESPONSE); - lapb->condition = 0x00; - lapb->t1timer = 0; - lapb->t2timer = 0; - lapb->vs = 0; - lapb->vr = 0; - lapb->va = 0; - lapb_requeue_frames(lapb); - } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", lapb->token, pf); -#endif - lapb_send_control(lapb, LAPB_DM, pf, LAPB_RESPONSE); - } - break; - - case LAPB_DISC: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 RX DISC(%d)\n", lapb->token, pf); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S0\n", lapb->token); -#endif - lapb_clear_queues(lapb); - lapb_send_control(lapb, LAPB_UA, pf, LAPB_RESPONSE); - lapb->state = LAPB_STATE_0; - lapb->t1timer = lapb->t1; - lapb->t2timer = 0; - lapb_disconnect_indication(lapb, LAPB_OK); - break; - - case LAPB_DM: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 RX DM(%d)\n", lapb->token, pf); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S0\n", lapb->token); -#endif - lapb_clear_queues(lapb); - lapb->state = LAPB_STATE_0; - lapb->t1timer = lapb->t1; - lapb->t2timer = 0; - lapb_disconnect_indication(lapb, LAPB_NOTCONNECTED); - break; - - case LAPB_RNR: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 RX RNR(%d) R%d\n", lapb->token, pf, nr); -#endif - lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION; - if (type == LAPB_RESPONSE && pf) { - lapb->t1timer = 0; - if (lapb_validate_nr(lapb, nr)) { - lapb_frames_acked(lapb, nr); - if (lapb->vs == lapb->va) { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->token); -#endif - lapb->n2count = 0; - lapb->state = LAPB_STATE_3; - } - } else { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token); -#endif - lapb_nr_error_recovery(lapb); - lapb->state = LAPB_STATE_1; - } - break; - } - - lapb_check_need_response(lapb, type, pf); - if (lapb_validate_nr(lapb, nr)) { - lapb_frames_acked(lapb, nr); - } else { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token); -#endif - lapb_nr_error_recovery(lapb); - lapb->state = LAPB_STATE_1; - } - break; - - case LAPB_RR: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 RX RR(%d) R%d\n", lapb->token, pf, nr); -#endif - lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION; - if (pf && type == LAPB_RESPONSE) { - lapb->t1timer = 0; - if (lapb_validate_nr(lapb, nr)) { - lapb_frames_acked(lapb, nr); - if (lapb->vs == lapb->va) { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->token); -#endif - lapb->n2count = 0; - lapb->state = LAPB_STATE_3; - } else { - lapb_requeue_frames(lapb); - } - } else { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token); -#endif - lapb_nr_error_recovery(lapb); - lapb->state = LAPB_STATE_1; - } - break; - } - - lapb_check_need_response(lapb, type, pf); - if (lapb_validate_nr(lapb, nr)) { - lapb_frames_acked(lapb, nr); - } else { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token); -#endif - lapb_nr_error_recovery(lapb); - lapb->state = LAPB_STATE_1; - } - break; - - case LAPB_REJ: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 RX REJ(%d) R%d\n", lapb->token, pf, nr); -#endif - lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION; - if (pf && type == LAPB_RESPONSE) { - lapb->t1timer = 0; - if (lapb_validate_nr(lapb, nr)) { - lapb_frames_acked(lapb, nr); - if (lapb->vs == lapb->va) { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->token); -#endif - lapb->n2count = 0; - lapb->state = LAPB_STATE_3; - } else { - lapb_requeue_frames(lapb); - } - } else { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token); -#endif - lapb_nr_error_recovery(lapb); - lapb->state = LAPB_STATE_1; - } - break; - } - - lapb_check_need_response(lapb, type, pf); - if (lapb_validate_nr(lapb, nr)) { - lapb_frames_acked(lapb, nr); - if (lapb->vs != lapb->va) - lapb_requeue_frames(lapb); - } else { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token); -#endif - lapb_nr_error_recovery(lapb); - lapb->state = LAPB_STATE_1; - } - break; - - case LAPB_I: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 RX I(%d) S%d R%d\n", lapb->token, pf, ns, nr); -#endif - if (!lapb_validate_nr(lapb, nr)) { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token); -#endif - lapb_nr_error_recovery(lapb); - lapb->state = LAPB_STATE_1; - break; - } - lapb_frames_acked(lapb, nr); - if (ns == lapb->vr) { - lapb->vr = (lapb->vr + 1) % modulus; - queued = lapb_data_indication(lapb, skb); - lapb->condition &= ~LAPB_REJECT_CONDITION; - if (pf) { - lapb_enquiry_response(lapb); - } else { - if (!(lapb->condition & LAPB_ACK_PENDING_CONDITION)) { - lapb->t2timer = lapb->t2; - lapb->condition |= LAPB_ACK_PENDING_CONDITION; - } - } - } else { - if (lapb->condition & LAPB_REJECT_CONDITION) { - if (pf) - lapb_enquiry_response(lapb); - } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 TX REJ(%d) R%d\n", lapb->token, pf, lapb->vr); -#endif - lapb->condition |= LAPB_REJECT_CONDITION; - lapb_send_control(lapb, LAPB_REJ, pf, LAPB_RESPONSE); - lapb->condition &= ~LAPB_ACK_PENDING_CONDITION; - } - } - break; - - case LAPB_FRMR: - case LAPB_ILLEGAL: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 TX {FRMR,ILLEGAL}(%d)\n", lapb->token, pf); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token); -#endif - lapb_establish_data_link(lapb); - lapb->state = LAPB_STATE_1; - break; - - default: - break; - } - - if (!queued) - kfree_skb(skb, FREE_READ); -} - -/* * Process an incoming LAPB frame */ -int lapb_data_received(void *token, struct sk_buff *skb) +void lapb_data_input(lapb_cb *lapb, struct sk_buff *skb) { int frametype, ns, nr, pf, type; - lapb_cb *lapb; - - if ((lapb = lapb_tokentostruct(token)) == NULL) - return LAPB_BADTOKEN; del_timer(&lapb->timer); @@ -786,14 +516,9 @@ case LAPB_STATE_3: lapb_state3_machine(lapb, skb, frametype, ns, nr, pf, type); break; - case LAPB_STATE_4: - lapb_state4_machine(lapb, skb, frametype, ns, nr, pf, type); - break; } lapb_set_timer(lapb); - - return LAPB_OK; } #endif diff -u --recursive --new-file v2.1.25/linux/net/lapb/lapb_out.c linux/net/lapb/lapb_out.c --- v2.1.25/linux/net/lapb/lapb_out.c Thu Jan 23 21:06:58 1997 +++ linux/net/lapb/lapb_out.c Tue Feb 4 16:44:25 1997 @@ -167,11 +167,6 @@ kfree_skb(skb, FREE_WRITE); } -void lapb_nr_error_recovery(lapb_cb *lapb) -{ - lapb_establish_data_link(lapb); -} - void lapb_establish_data_link(lapb_cb *lapb) { lapb->condition = 0x00; @@ -193,19 +188,6 @@ lapb->t1timer = lapb->t1; } -void lapb_transmit_enquiry(lapb_cb *lapb) -{ -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S%d TX RR(1) R%d\n", lapb->token, lapb->state, lapb->vr); -#endif - - lapb_send_control(lapb, LAPB_RR, LAPB_POLLON, LAPB_COMMAND); - - lapb->condition &= ~LAPB_ACK_PENDING_CONDITION; - - lapb->t1timer = lapb->t1; -} - void lapb_enquiry_response(lapb_cb *lapb) { #if LAPB_DEBUG > 1 @@ -233,6 +215,7 @@ if (lapb->vs == nr) { lapb_frames_acked(lapb, nr); lapb->t1timer = 0; + lapb->n2count = 0; } else { if (lapb->va != nr) { lapb_frames_acked(lapb, nr); diff -u --recursive --new-file v2.1.25/linux/net/lapb/lapb_subr.c linux/net/lapb/lapb_subr.c --- v2.1.25/linux/net/lapb/lapb_subr.c Thu Jan 23 21:06:58 1997 +++ linux/net/lapb/lapb_subr.c Tue Feb 4 16:44:26 1997 @@ -45,6 +45,9 @@ { struct sk_buff *skb; + while ((skb = skb_dequeue(&lapb->input_queue)) != NULL) + kfree_skb(skb, FREE_READ); + while ((skb = skb_dequeue(&lapb->write_queue)) != NULL) kfree_skb(skb, FREE_WRITE); diff -u --recursive --new-file v2.1.25/linux/net/lapb/lapb_timer.c linux/net/lapb/lapb_timer.c --- v2.1.25/linux/net/lapb/lapb_timer.c Thu Feb 6 12:42:15 1997 +++ linux/net/lapb/lapb_timer.c Tue Feb 4 16:44:26 1997 @@ -67,12 +67,25 @@ static void lapb_timer(unsigned long param) { lapb_cb *lapb = (lapb_cb *)param; + struct sk_buff *skb; - if (lapb->state == LAPB_STATE_3 || lapb->state == LAPB_STATE_4) + /* + * Process all packet received since the last clock tick. + */ + while ((skb = skb_dequeue(&lapb->input_queue)) != NULL) + lapb_data_input(lapb, skb); + + /* + * If in a data transfer state, transmit any data. + */ + if (lapb->state == LAPB_STATE_3) lapb_kick(lapb); + /* + * T2 expiry code. + */ if (lapb->t2timer > 0 && --lapb->t2timer == 0) { - if (lapb->state == LAPB_STATE_3 || lapb->state == LAPB_STATE_4) { + if (lapb->state == LAPB_STATE_3) { if (lapb->condition & LAPB_ACK_PENDING_CONDITION) { lapb->condition &= ~LAPB_ACK_PENDING_CONDITION; lapb_timeout_response(lapb); @@ -80,16 +93,30 @@ } } + /* + * If T1 isn't running, or hasn't timed out yet, keep going. + */ if (lapb->t1timer == 0 || --lapb->t1timer > 0) { lapb_set_timer(lapb); return; } + /* + * T1 has expired. + */ switch (lapb->state) { + + /* + * If we are a DCE, keep going DM .. DM .. DM + */ case LAPB_STATE_0: if (lapb->mode & LAPB_DCE) lapb_send_control(lapb, LAPB_DM, LAPB_POLLOFF, LAPB_RESPONSE); break; + + /* + * Awaiting connection state, send SABM(E), up to N2 times. + */ case LAPB_STATE_1: if (lapb->n2count == lapb->n2) { lapb_clear_queues(lapb); @@ -115,6 +142,9 @@ } break; + /* + * Awaiting disconnection state, send DISC, up to N2 times. + */ case LAPB_STATE_2: if (lapb->n2count == lapb->n2) { lapb_clear_queues(lapb); @@ -133,27 +163,21 @@ } break; - case LAPB_STATE_3: - lapb->n2count = 1; - lapb_transmit_enquiry(lapb); - lapb->state = LAPB_STATE_4; -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token); -#endif - break; - - case LAPB_STATE_4: + /* + * Data transfer state, restransmit I frames, up to N2 times. + */ + case LAPB_STATE_3: if (lapb->n2count == lapb->n2) { lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb->t2timer = 0; lapb_disconnect_indication(lapb, LAPB_TIMEDOUT); #if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S0\n", lapb->token); + printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->token); #endif } else { lapb->n2count++; - lapb_transmit_enquiry(lapb); + lapb_requeue_frames(lapb); } break; } diff -u --recursive --new-file v2.1.25/linux/net/netrom/nr_dev.c linux/net/netrom/nr_dev.c --- v2.1.25/linux/net/netrom/nr_dev.c Thu Feb 6 12:42:15 1997 +++ linux/net/netrom/nr_dev.c Tue Feb 4 16:44:26 1997 @@ -59,7 +59,7 @@ int nr_rx_ip(struct sk_buff *skb, struct device *dev) { - struct enet_statistics *stats = (struct enet_statistics *)dev->priv; + struct net_device_stats *stats = (struct net_device_stats *)dev->priv; if (!dev->start) { stats->rx_errors++; @@ -67,6 +67,8 @@ } stats->rx_packets++; + stats->rx_bytes += skb->len; + skb->protocol = htons(ETH_P_IP); /* Spoof incoming device */ @@ -115,7 +117,7 @@ static int nr_rebuild_header(struct sk_buff *skb) { struct device *dev = skb->dev; - struct enet_statistics *stats = (struct enet_statistics *)dev->priv; + struct net_device_stats *stats = (struct net_device_stats *)dev->priv; struct sk_buff *skbn; unsigned char *bp = skb->data; @@ -149,6 +151,7 @@ } stats->tx_packets++; + stats->tx_bytes += skbn->len; return 1; } @@ -188,7 +191,7 @@ static int nr_xmit(struct sk_buff *skb, struct device *dev) { - struct enet_statistics *stats = (struct enet_statistics *)dev->priv; + struct net_device_stats *stats = (struct net_device_stats *)dev->priv; if (skb == NULL || dev == NULL) return 0; @@ -221,9 +224,9 @@ return 0; } -static struct enet_statistics *nr_get_stats(struct device *dev) +static struct net_device_stats *nr_get_stats(struct device *dev) { - return (struct enet_statistics *)dev->priv; + return (struct net_device_stats *)dev->priv; } int nr_init(struct device *dev) @@ -250,10 +253,10 @@ dev->pa_mask = 0; dev->pa_alen = sizeof(unsigned long); - if ((dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL)) == NULL) + if ((dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL)) == NULL) return -ENOMEM; - memset(dev->priv, 0, sizeof(struct enet_statistics)); + memset(dev->priv, 0, sizeof(struct net_device_stats)); dev->get_stats = nr_get_stats; diff -u --recursive --new-file v2.1.25/linux/net/rose/rose_dev.c linux/net/rose/rose_dev.c --- v2.1.25/linux/net/rose/rose_dev.c Thu Feb 6 12:42:16 1997 +++ linux/net/rose/rose_dev.c Tue Feb 4 16:44:27 1997 @@ -55,7 +55,7 @@ int rose_rx_ip(struct sk_buff *skb, struct device *dev) { - struct enet_statistics *stats = (struct enet_statistics *)dev->priv; + struct net_device_stats *stats = (struct net_device_stats *)dev->priv; if (!dev->start) { stats->rx_errors++; @@ -63,6 +63,8 @@ } stats->rx_packets++; + stats->rx_bytes += skb->len; + skb->protocol = htons(ETH_P_IP); /* Spoof incoming device */ @@ -96,7 +98,7 @@ static int rose_rebuild_header(struct sk_buff *skb) { struct device *dev = skb->dev; - struct enet_statistics *stats = (struct enet_statistics *)dev->priv; + struct net_device_stats *stats = (struct net_device_stats *)dev->priv; unsigned char *bp = (unsigned char *)skb->data; struct sk_buff *skbn; @@ -121,6 +123,7 @@ } stats->tx_packets++; + stats->tx_bytes += skbn->len; return 1; } @@ -160,7 +163,7 @@ static int rose_xmit(struct sk_buff *skb, struct device *dev) { - struct enet_statistics *stats = (struct enet_statistics *)dev->priv; + struct net_device_stats *stats = (struct net_device_stats *)dev->priv; if (skb == NULL || dev == NULL) return 0; @@ -193,9 +196,9 @@ return 0; } -static struct enet_statistics *rose_get_stats(struct device *dev) +static struct net_device_stats *rose_get_stats(struct device *dev) { - return (struct enet_statistics *)dev->priv; + return (struct net_device_stats *)dev->priv; } int rose_init(struct device *dev) @@ -222,10 +225,10 @@ dev->pa_mask = 0; dev->pa_alen = sizeof(unsigned long); - if ((dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL)) == NULL) + if ((dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL)) == NULL) return -ENOMEM; - memset(dev->priv, 0, sizeof(struct enet_statistics)); + memset(dev->priv, 0, sizeof(struct net_device_stats)); dev->get_stats = rose_get_stats; diff -u --recursive --new-file v2.1.25/linux/net/socket.c linux/net/socket.c --- v2.1.25/linux/net/socket.c Thu Feb 6 12:42:16 1997 +++ linux/net/socket.c Fri Feb 7 15:57:06 1997 @@ -645,7 +645,7 @@ asmlinkage int sys_socketpair(int family, int type, int protocol, int usockvec[2]) { int fd1, fd2, i; - struct socket *sock1, *sock2; + struct socket *sock1=NULL, *sock2=NULL; int err; lock_kernel(); @@ -700,6 +700,10 @@ } } out: + if(sock1) + sockfd_put(sock1); + if(sock2) + sockfd_put(sock2); unlock_kernel(); return err; } @@ -1114,6 +1118,7 @@ err=sock->ops->shutdown(sock, how); sockfd_put(sock); } + unlock_kernel(); return err; } diff -u --recursive --new-file v2.1.25/linux/net/sysctl_net.c linux/net/sysctl_net.c --- v2.1.25/linux/net/sysctl_net.c Tue Nov 12 15:56:17 1996 +++ linux/net/sysctl_net.c Fri Feb 7 15:54:55 1997 @@ -42,6 +42,10 @@ extern ctl_table ipv6_table[]; #endif +#ifdef CONFIG_TR +extern ctl_table tr_table[]; +#endif + ctl_table net_table[] = { {NET_CORE, "core", NULL, 0, 0555, core_table}, {NET_UNIX, "unix", NULL, 0, 0555, unix_table}, @@ -63,6 +67,9 @@ #endif #ifdef CONFIG_IPV6 {NET_IPV6, "ipv6", NULL, 0, 0555, ipv6_table}, +#endif +#ifdef CONFIG_TR + {NET_TR, "token-ring", NULL, 0, 0555, tr_table}, #endif {0} }; diff -u --recursive --new-file v2.1.25/linux/scripts/Configure linux/scripts/Configure --- v2.1.25/linux/scripts/Configure Wed Jan 15 19:45:47 1997 +++ linux/scripts/Configure Fri Feb 7 15:54:55 1997 @@ -288,7 +288,7 @@ def=${old:-$3} while :; do readln "$1 ($2) [$def] " "$def" "$old" - if expr "$ans" : '0$\|-?[1-9][0-9]*$' > /dev/null; then + if expr "$ans" : '0$\|-\?[1-9][0-9]*$' > /dev/null; then define_int "$2" "$ans" break else @@ -319,7 +319,7 @@ while :; do readln "$1 ($2) [$def] " "$def" "$old" ans=${ans#*[x,X]} - if expr "$ans" : '[0-9a-fA-F]+$' > /dev/null; then + if expr "$ans" : '[0-9a-fA-F]\+$' > /dev/null; then define_hex "$2" "$ans" break else diff -u --recursive --new-file v2.1.25/linux/scripts/Menuconfig linux/scripts/Menuconfig --- v2.1.25/linux/scripts/Menuconfig Wed Jan 15 19:45:47 1997 +++ linux/scripts/Menuconfig Fri Feb 7 15:54:55 1997 @@ -400,7 +400,7 @@ answer="`cat MCdialog.out`" answer="${answer:-$3}" - if expr $answer : '0$\|-?[1-9][0-9]*$' >/dev/null + if expr $answer : '0$\|-\?[1-9][0-9]*$' >/dev/null then eval $2="$answer" else @@ -433,7 +433,7 @@ answer="${answer:-$3}" answer="${answer##*[x,X]}" - if expr $answer : '[0-9a-fA-F]+$' >/dev/null + if expr $answer : '[0-9a-fA-F]\+$' >/dev/null then eval $2="$answer" else