diff -u --recursive --new-file v2.1.18/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.1.18/linux/Documentation/Configure.help	Mon Dec 30 15:39:02 1996
+++ linux/Documentation/Configure.help	Tue Dec 31 12:39:14 1996
@@ -4063,6 +4063,11 @@
   This is support for the soundcards on Sun workstations. The code
   does not exist yet, so you might as well say N here.
 
+SB32/AWE support
+CONFIG_AWE32_SYNTH
+Enable this option if you have a SB32 or SB AWE soundcard. See
+linux/drivers/sound/lowlevel/README.awe for more info.
+
 Kernel profiling support
 CONFIG_PROFILE
   This is for kernel hackers who want to know how much time the kernel
diff -u --recursive --new-file v2.1.18/linux/Makefile linux/Makefile
--- v2.1.18/linux/Makefile	Mon Dec 30 15:39:02 1996
+++ linux/Makefile	Mon Dec 30 15:46:28 1996
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 18
+SUBLEVEL = 19
 
 ARCH = i386
 
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/defconfig linux/arch/sparc/defconfig
--- v2.1.18/linux/arch/sparc/defconfig	Sun Dec 22 16:37:23 1996
+++ linux/arch/sparc/defconfig	Mon Dec 30 11:59:58 1996
@@ -11,7 +11,7 @@
 # Loadable module support
 #
 CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
+# CONFIG_MODVERSIONS is not set
 CONFIG_KERNELD=y
 
 #
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
--- v2.1.18/linux/arch/sparc/kernel/entry.S	Sun Dec 22 16:37:23 1996
+++ linux/arch/sparc/kernel/entry.S	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.128 1996/12/18 06:33:39 tridge Exp $
+/* $Id: entry.S,v 1.129 1996/12/30 00:31:07 davem Exp $
  * arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1721,5 +1721,43 @@
 	ldd	[%o0], %o6
 	jmpl	%o7 + 0xc, %g0			! see asm-sparc/processor.h
 	 mov	1, %g1				! signal EFAULT condition
+
+	.align	4
+	.globl	C_LABEL(kill_user_windows), kuw_patch1_7win
+	.globl	kuw_patch1
+kuw_patch1_7win:	sll	%o3, 6, %o3
+
+	/* No matter how much overhead this routine has in the worst
+	 * case scenerio, it is several times better than taking the
+	 * traps with the old method of just doing flush_user_windows().
+	 */
+C_LABEL(kill_user_windows):
+	ld	[%g6 + THREAD_UMASK], %o0	! get current umask
+	orcc	%g0, %o0, %g0			! if no bits set, we are done
+	be	3f				! nothing to do
+	 rd	%psr, %o5			! must clear interrupts
+	or	%o5, PSR_PIL, %o4		! or else that could change
+	wr	%o4, 0x0, %psr			! the uwinmask state
+	WRITE_PAUSE				! burn them cycles
+1:
+	ld	[%g6 + THREAD_UMASK], %o0	! get consistant state
+	orcc	%g0, %o0, %g0			! did an interrupt come in?
+	be	4f				! yep, we are done
+	 rd	%wim, %o3			! get current wim
+	srl	%o3, 1, %o4			! simulate a save
+kuw_patch1:
+	sll	%o3, 7, %o3			! compute next wim
+	or	%o4, %o3, %o3			! result
+	andncc	%o0, %o3, %o0			! clean this bit in umask
+	bne	kuw_patch1			! not done yet
+	 srl	%o3, 1, %o4			! begin another save simulation
+	wr	%o3, 0x0, %wim			! set the new wim
+	st	%g0, [%g6 + THREAD_UMASK]	! clear uwinmask
+4:
+	wr	%o5, 0x0, %psr			! re-enable interrupts
+	WRITE_PAUSE				! burn baby burn
+3:
+	retl					! return
+	 st	%g0, [%g6 + THREAD_W_SAVED]	! no windows saved
 
 /* End of entry.S */
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S
--- v2.1.18/linux/arch/sparc/kernel/head.S	Mon Dec 30 15:39:03 1996
+++ linux/arch/sparc/kernel/head.S	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.75 1996/12/20 07:54:57 davem Exp $
+/* $Id: head.S,v 1.76 1996/12/30 00:31:09 davem Exp $
  * head.S: The initial boot code for the Sparc port of Linux.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1062,6 +1062,10 @@
 		PATCH_INSN(rirq_7win_patch5, rirq_patch5)
 
 #endif
+
+		/* Patch for killing user windows from the register file. */
+		PATCH_INSN(kuw_patch1_7win, kuw_patch1)
+
 		/* Now patch the kernel window flush sequences.
 		 * This saves 2 traps on every switch and fork.
 		 */
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
--- v2.1.18/linux/arch/sparc/kernel/process.c	Sun Dec 22 16:37:23 1996
+++ linux/arch/sparc/kernel/process.c	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/*  $Id: process.c,v 1.85 1996/12/18 06:33:42 tridge Exp $
+/*  $Id: process.c,v 1.87 1996/12/30 06:16:21 davem Exp $
  *  linux/arch/sparc/kernel/process.c
  *
  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -280,7 +280,7 @@
  */
 void exit_thread(void)
 {
-	flush_user_windows();
+	kill_user_windows();
 #ifndef __SMP__
 	if(last_task_used_math == current) {
 #else
@@ -296,15 +296,13 @@
 		current->flags &= ~PF_USEDFPU;
 #endif
 	}
-	mmu_exit_hook();
 }
 
 void flush_thread(void)
 {
 	/* Make sure old user windows don't get in the way. */
-	flush_user_windows();
-	current->tss.w_saved = 0;
-	current->tss.uwinmask = 0;
+	kill_user_windows();
+
 	current->tss.sstk_info.cur_status = 0;
 	current->tss.sstk_info.the_stack = 0;
 
@@ -326,7 +324,6 @@
 #endif
 	}
 
-	mmu_flush_hook();
 	/* Now, this task is no longer a kernel thread. */
 	current->tss.flags &= ~SPARC_FLAG_KTHREAD;
 	current->tss.current_ds = USER_DS;
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/rtrap.S linux/arch/sparc/kernel/rtrap.S
--- v2.1.18/linux/arch/sparc/kernel/rtrap.S	Wed Dec 18 15:58:43 1996
+++ linux/arch/sparc/kernel/rtrap.S	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.40 1996/12/10 06:06:18 davem Exp $
+/* $Id: rtrap.S,v 1.41 1996/12/28 18:14:21 davem Exp $
  * rtrap.S: Return from Sparc trap low-level code.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -70,7 +70,6 @@
 	 sethi	%hi(C_LABEL(need_resched)), %twin_tmp1
 
 	wr	%t_psr, 0x0, %psr
-	WRITE_PAUSE
 	b	ret_trap_kernel
 	 nop
 
@@ -179,7 +178,6 @@
 	ld	[%sp + REGWIN_SZ + PT_PSR], %o3
 
 	wr	%t_wim, 0x0, %wim		! or else...
-	WRITE_PAUSE
 
 	wr	%t_psr, PSR_ET, %psr
 	WRITE_PAUSE
@@ -206,7 +204,6 @@
 rtrap_patch5:	and	%g1, 0xff, %g1
 
 	wr	%g1, 0x0, %wim
-	WRITE_PAUSE
 
 	/* Grrr, make sure we load from the right %sp... */
 	LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
@@ -232,7 +229,6 @@
 
 ret_trap_user_stack_is_bolixed:
 	wr	%t_wim, 0x0, %wim
-	WRITE_PAUSE
 
 	wr	%t_psr, PSR_ET, %psr
 	WRITE_PAUSE
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/setup.c linux/arch/sparc/kernel/setup.c
--- v2.1.18/linux/arch/sparc/kernel/setup.c	Sun Dec 22 16:37:23 1996
+++ linux/arch/sparc/kernel/setup.c	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.78 1996/12/19 08:06:30 davem Exp $
+/*  $Id: setup.c,v 1.79 1996/12/23 10:57:02 ecd Exp $
  *  linux/arch/sparc/kernel/setup.c
  *
  *  Copyright (C) 1995  David S. Miller (davem@caip.rutgers.edu)
@@ -248,7 +248,7 @@
 
 extern int root_mountflags;
 
-extern void register_console(void (*proc)(char *));
+extern void register_console(void (*proc)(const char *));
 
 char saved_command_line[256];
 char reboot_command[256];
@@ -310,7 +310,7 @@
 		printk("SUN4U\n");
 		break;
 	case ap1000:
-		register_console(prom_printf);
+		register_console((void (*) (const char *))prom_printf);
 		printk("AP1000\n");
 		packed = 1;
 		break;
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/sparc_ksyms.c linux/arch/sparc/kernel/sparc_ksyms.c
--- v2.1.18/linux/arch/sparc/kernel/sparc_ksyms.c	Mon Dec 30 15:39:03 1996
+++ linux/arch/sparc/kernel/sparc_ksyms.c	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: sparc_ksyms.c,v 1.32 1996/12/18 06:33:45 tridge Exp $
+/* $Id: sparc_ksyms.c,v 1.33 1996/12/29 20:46:01 davem Exp $
  * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/sys_sparc.c linux/arch/sparc/kernel/sys_sparc.c
--- v2.1.18/linux/arch/sparc/kernel/sys_sparc.c	Sun Dec 22 16:37:27 1996
+++ linux/arch/sparc/kernel/sys_sparc.c	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.32 1996/12/19 05:25:46 davem Exp $
+/* $Id: sys_sparc.c,v 1.33 1996/12/24 08:59:33 davem Exp $
  * linux/arch/sparc/kernel/sys_sparc.c
  *
  * This file contains various random system calls that
@@ -201,18 +201,47 @@
 #endif
 }
 
-extern int
-sys_sigaction (int signum, const struct sigaction *action, struct sigaction *oldaction);
+extern void check_pending(int signum);
 
 asmlinkage int
 sparc_sigaction (int signum, const struct sigaction *action, struct sigaction *oldaction)
 {
-    if (signum >= 0){
-	return sys_sigaction (signum, action, oldaction);
-    } else {
-	current->tss.new_signal = 1;
-	return sys_sigaction (-signum, action, oldaction);
-    }
+	struct sigaction new_sa, *p;
+
+	if(signum < 0) {
+		current->tss.new_signal = 1;
+		signum = -signum;
+	}
+
+	if (signum<1 || signum>32)
+		return -EINVAL;
+	p = signum - 1 + current->sig->action;
+	if (action) {
+		int err = verify_area(VERIFY_READ,action,sizeof(struct sigaction));
+		if (err)
+			return err;
+		if (signum==SIGKILL || signum==SIGSTOP)
+			return -EINVAL;
+		if(copy_from_user(&new_sa, action, sizeof(struct sigaction)))
+			return -EFAULT;	
+		if (new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) {
+			err = verify_area(VERIFY_READ, new_sa.sa_handler, 1);
+			if (err)
+				return err;
+		}
+	}
+
+	if (oldaction) {
+		if (copy_to_user(oldaction, p, sizeof(struct sigaction)))
+			return -EFAULT;	
+	}
+
+	if (action) {
+		*p = new_sa;
+		check_pending(signum);
+	}
+
+	return 0;
 }
 
 #ifndef CONFIG_AP1000
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c
--- v2.1.18/linux/arch/sparc/kernel/sys_sunos.c	Mon Dec 30 15:39:03 1996
+++ linux/arch/sparc/kernel/sys_sunos.c	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.69 1996/12/21 04:50:38 tridge Exp $
+/* $Id: sys_sunos.c,v 1.71 1996/12/29 20:46:02 davem Exp $
  * sys_sunos.c: SunOS specific syscall compatibility support.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -26,7 +26,6 @@
  * to do the inverse mapping.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -1155,49 +1154,52 @@
 
 #define SUNOS_SV_INTERRUPT 2
 
-extern asmlinkage int sys_sigaction(int, const struct sigaction *, struct sigaction *);
+extern void check_pending(int signum);
 
 asmlinkage int sunos_sigaction(int signum, const struct sigaction *action,
 	struct sigaction *oldaction)
 {
-	struct sigaction tmp_sa, *tmp_sap;
+	struct sigaction new_sa, *p;
 	const  int sigaction_size = sizeof (struct sigaction) - sizeof (void *);
 	int err;
-	int old_fs = USER_DS;
 
 	current->personality |= PER_BSD;
 
+	if (signum<1 || signum>32)
+		return -EINVAL;
+
+	p = signum - 1 + current->sig->action;
 	if (action) {
-		if(copy_from_user(&tmp_sa, action, sigaction_size))
+		if(copy_from_user(&new_sa, action, sigaction_size))
 			return -EFAULT;
-		if (oldaction) {
-			err = verify_area(VERIFY_WRITE,oldaction,sigaction_size);
+		if (signum==SIGKILL || signum==SIGSTOP)
+			return -EINVAL;
+		memset(&new_sa, 0, sizeof(struct sigaction));
+		if(copy_from_user(&new_sa, action, sigaction_size))
+			return -EFAULT;	
+		if (new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) {
+			err = verify_area(VERIFY_READ, new_sa.sa_handler, 1);
 			if (err)
 				return err;
 		}
-			
-		if (tmp_sa.sa_flags & SUNOS_SV_INTERRUPT)
-			tmp_sa.sa_flags &= ~SUNOS_SV_INTERRUPT;
-		else
-			tmp_sa.sa_flags |= SA_RESTART;
-		old_fs = get_fs ();
-		set_fs (get_ds ());
-		tmp_sap = &tmp_sa;
-	} else {
-		tmp_sap = (struct sigaction *) action;
+		new_sa.sa_flags ^= SUNOS_SV_INTERRUPT;
 	}
 
-	err = sys_sigaction (signum, tmp_sap, oldaction);
-
-	if (err == 0 && oldaction){
+	if (oldaction) {
+		if (copy_to_user(oldaction, p, sigaction_size))
+			return -EFAULT;	
 		if (oldaction->sa_flags & SA_RESTART)
 			oldaction->sa_flags &= ~SA_RESTART;
 		else
 			oldaction->sa_flags |= SUNOS_SV_INTERRUPT;
 	}
-	if (action)
-		set_fs (old_fs);
-	return err;
+
+	if (action) {
+		*p = new_sa;
+		check_pending(signum);
+	}
+
+	return 0;
 }
 
 
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/systbls.S linux/arch/sparc/kernel/systbls.S
--- v2.1.18/linux/arch/sparc/kernel/systbls.S	Sun Dec 22 16:37:27 1996
+++ linux/arch/sparc/kernel/systbls.S	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.55 1996/12/18 06:33:47 tridge Exp $
+/* $Id: systbls.S,v 1.56 1996/12/29 20:46:03 davem Exp $
  * systbls.S: System call entry point tables for OS compatibility.
  *            The native Linux system call table lives here also.
  *
@@ -106,7 +106,7 @@
 	.long C_LABEL(sys_nis_syscall), C_LABEL(sys_getdents), C_LABEL(sys_setsid)
 	.long C_LABEL(sys_fchdir), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
 	.long C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
-	.long C_LABEL(sys_nis_syscall), C_LABEL(sys_sigpending), C_LABEL(sys_nis_syscall)
+	.long C_LABEL(sys_nis_syscall), C_LABEL(sys_sigpending), C_LABEL(sys_query_module)
 	.long C_LABEL(sys_setpgid), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
 	.long C_LABEL(sys_nis_syscall), C_LABEL(sys_newuname), C_LABEL(sys_init_module)
 	.long C_LABEL(sys_personality), C_LABEL(sys_prof), C_LABEL(sys_break)
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/traps.c linux/arch/sparc/kernel/traps.c
--- v2.1.18/linux/arch/sparc/kernel/traps.c	Sun Dec 22 16:37:27 1996
+++ linux/arch/sparc/kernel/traps.c	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.49 1996/12/18 06:33:49 tridge Exp $
+/* $Id: traps.c,v 1.50 1996/12/29 20:46:05 davem Exp $
  * arch/sparc/kernel/traps.c
  *
  * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -10,7 +10,6 @@
 
 #include <linux/sched.h>  /* for jiffies */
 #include <linux/kernel.h>
-#include <linux/config.h>
 #include <linux/signal.h>
 
 #include <asm/delay.h>
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/wof.S linux/arch/sparc/kernel/wof.S
--- v2.1.18/linux/arch/sparc/kernel/wof.S	Wed Dec 18 15:58:46 1996
+++ linux/arch/sparc/kernel/wof.S	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: wof.S,v 1.30 1996/12/10 06:06:19 davem Exp $
+/* $Id: wof.S,v 1.31 1996/12/28 18:14:22 davem Exp $
  * wof.S: Sparc window overflow handler.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -205,7 +205,6 @@
 	 * c-code to gun down the process.
 	 */
 	rd	%psr, %glob_tmp
-	WRITE_PAUSE
 	andcc	%glob_tmp, PSR_PS, %g0
 	bne	spwin_bad_ustack_from_kernel
 	 nop
@@ -249,8 +248,7 @@
 
 	/* Turn on traps and call c-code to deal with it. */
 	wr	%t_psr, PSR_ET, %psr
-	WRITE_PAUSE
-
+	nop
 	call	C_LABEL(window_overflow_fault)
 	 nop
 
@@ -316,7 +314,6 @@
 	 sra	%sp, 29, %glob_tmp
 
 	rd	%psr, %glob_tmp
-	WRITE_PAUSE
 	b	spwin_user_stack_is_bolixed + 0x4
 	 nop
 
@@ -327,7 +324,6 @@
 	 and	%sp, 0xfff, %glob_tmp		! delay slot
 
 	rd	%psr, %glob_tmp
-	WRITE_PAUSE
 	b	spwin_user_stack_is_bolixed + 0x4
 	 nop
 
@@ -348,7 +344,6 @@
 	 add	%sp, 0x38, %glob_tmp	/* Is second page in vma hole? */
 
 	rd	%psr, %glob_tmp
-	WRITE_PAUSE
 	b	spwin_user_stack_is_bolixed + 0x4
 	 nop
 
@@ -360,7 +355,6 @@
 	 add	%sp, 0x38, %glob_tmp
 
 	rd	%psr, %glob_tmp
-	WRITE_PAUSE
 	b	spwin_user_stack_is_bolixed + 0x4
 	 nop
 
@@ -374,7 +368,6 @@
 	 nop
 
 	rd	%psr, %glob_tmp
-	WRITE_PAUSE
 	b	spwin_user_stack_is_bolixed + 0x4
 	 nop
 
@@ -429,6 +422,5 @@
 	 restore %g0, %g0, %g0
 
 	rd	%psr, %glob_tmp
-	WRITE_PAUSE
 	b	spwin_user_stack_is_bolixed + 0x4	! we faulted, ugh
 	 nop
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/kernel/wuf.S linux/arch/sparc/kernel/wuf.S
--- v2.1.18/linux/arch/sparc/kernel/wuf.S	Wed Dec 18 15:58:46 1996
+++ linux/arch/sparc/kernel/wuf.S	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: wuf.S,v 1.28 1996/12/10 06:06:20 davem Exp $
+/* $Id: wuf.S,v 1.29 1996/12/28 18:14:23 davem Exp $
  * wuf.S: Window underflow trap handler for the Sparc.
  *
  * Copyright (C) 1995 David S. Miller
@@ -184,8 +184,7 @@
 	ENTER_SYSCALL
 
 	wr	%t_psr, PSR_ET, %psr			! enable traps
-	WRITE_PAUSE
-
+	nop
 	call	C_LABEL(window_underflow_fault)
 	 mov	%g4, %o0
 
@@ -343,7 +342,7 @@
 	 nop
 
 	wr	%t_psr, 0x0, %psr
-	WRITE_PAUSE
+	nop
 	b	fwin_user_finish_up + 0x4
 	 nop
 
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/mm/extable.c linux/arch/sparc/mm/extable.c
--- v2.1.18/linux/arch/sparc/mm/extable.c	Mon Dec 30 15:39:03 1996
+++ linux/arch/sparc/mm/extable.c	Mon Dec 30 11:59:58 1996
@@ -37,7 +37,7 @@
         }
         if (first > start && first[-1].insn < value
 	    && !first[-1].fixup && first->insn < value) {
-        	*g2 = (value - firstp[-1].insn)/4;
+        	*g2 = (value - first[-1].insn)/4;
         	return first->fixup;
         }
         return 0;
@@ -60,7 +60,7 @@
 		if (mp->ex_table_start == NULL)
 			continue;
 		ret = search_one_table(mp->ex_table_start,
-				       mp->ex_table_stop-1, addr, g2);
+				       mp->ex_table_end-1, addr, g2);
 		if (ret) return ret;
 	}
 #endif
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/mm/loadmmu.c linux/arch/sparc/mm/loadmmu.c
--- v2.1.18/linux/arch/sparc/mm/loadmmu.c	Sun Dec 22 16:37:27 1996
+++ linux/arch/sparc/mm/loadmmu.c	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: loadmmu.c,v 1.43 1996/12/18 06:43:24 tridge Exp $
+/* $Id: loadmmu.c,v 1.45 1996/12/30 06:16:28 davem Exp $
  * loadmmu.c:  This code loads up all the mm function pointers once the
  *             machine type has been determined.  It also sets the static
  *             mmu values such as PAGE_NONE, etc.
@@ -15,6 +15,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/a.out.h>
+#include <asm/mmu_context.h>
 
 unsigned long page_offset = 0xf0000000;
 unsigned long stack_top = 0xf0000000 - PAGE_SIZE;
@@ -30,8 +31,8 @@
 
 void (*quick_kernel_fault)(unsigned long);
 
-void (*mmu_exit_hook)(void);
-void (*mmu_flush_hook)(void);
+void (*init_new_context)(struct mm_struct *mm);
+void (*destroy_context)(struct mm_struct *mm);
 
 /* translate between physical and virtual addresses */
 unsigned long (*mmu_v2p)(unsigned long);
@@ -135,7 +136,6 @@
 void (*pgd_free)(pgd_t *);
 
 pgd_t * (*pgd_alloc)(void);
-void (*pgd_flush)(pgd_t *);
 
 int (*pte_write)(pte_t);
 int (*pte_dirty)(pte_t);
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c
--- v2.1.18/linux/arch/sparc/mm/srmmu.c	Sun Dec 22 16:37:28 1996
+++ linux/arch/sparc/mm/srmmu.c	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.119 1996/12/19 08:06:37 davem Exp $
+/* $Id: srmmu.c,v 1.122 1996/12/30 06:16:31 davem Exp $
  * srmmu.c:  SRMMU specific routines for memory management.
  *
  * Copyright (C) 1995 David S. Miller  (davem@caip.rutgers.edu)
@@ -28,6 +28,7 @@
 #include <asm/asi.h>
 #include <asm/msi.h>
 #include <asm/a.out.h>
+#include <asm/mmu_context.h>
 
 /* Now the cpu specific definitions. */
 #include <asm/viking.h>
@@ -284,48 +285,6 @@
 	}
 }
 
-static inline void srmmu_uncache_page(unsigned long addr)
-{
-	pgd_t *pgdp = srmmu_pgd_offset(init_task.mm, addr);
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	if((pgd_val(*pgdp) & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
-		ptep = (pte_t *) pgdp;
-	} else {
-		pmdp = srmmu_pmd_offset(pgdp, addr);
-		if((pmd_val(*pmdp) & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
-			ptep = (pte_t *) pmdp;
-		} else {
-			ptep = srmmu_pte_offset(pmdp, addr);
-		}
-	}
-
-	flush_cache_page_to_uncache(addr);
-	set_pte(ptep, __pte((pte_val(*ptep) & ~SRMMU_CACHE)));
-	flush_tlb_page_for_cbit(addr);
-}
-
-static inline void srmmu_recache_page(unsigned long addr)
-{
-	pgd_t *pgdp = srmmu_pgd_offset(init_task.mm, addr);
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	if((pgd_val(*pgdp) & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
-		ptep = (pte_t *) pgdp;
-	} else {
-		pmdp = srmmu_pmd_offset(pgdp, addr);
-		if((pmd_val(*pmdp) & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
-			ptep = (pte_t *) pmdp;
-		} else {
-			ptep = srmmu_pte_offset(pmdp, addr);
-		}
-	}
-	set_pte(ptep, __pte((pte_val(*ptep) | SRMMU_CACHE)));
-	flush_tlb_page_for_cbit(addr);
-}
-
 static unsigned long srmmu_getpage(void)
 {
 	unsigned long page = get_free_page(GFP_KERNEL);
@@ -722,10 +681,6 @@
 	return NEW_PGD();
 }
 
-static void srmmu_pgd_flush(pgd_t *pgdp)
-{
-}
-
 static void srmmu_set_pte_cacheable(pte_t *ptep, pte_t pteval)
 {
 	srmmu_set_entry(ptep, pte_val(pteval));
@@ -801,9 +756,8 @@
 #endif
 }
 
-static inline void alloc_context(struct task_struct *tsk)
+static inline void alloc_context(struct mm_struct *mm)
 {
-	struct mm_struct *mm = tsk->mm;
 	struct ctx_list *ctxp;
 
 	ctxp = ctx_free.next;
@@ -841,14 +795,26 @@
 static void srmmu_switch_to_context(struct task_struct *tsk)
 {
 	if(tsk->mm->context == NO_CONTEXT) {
-		alloc_context(tsk);
-		flush_cache_mm(current->mm);
+		alloc_context(tsk->mm);
+		flush_cache_mm(tsk->mm);
 		ctxd_set(&srmmu_context_table[tsk->mm->context], tsk->mm->pgd);
-		flush_tlb_mm(current->mm);
+		flush_tlb_mm(tsk->mm);
 	}
 	srmmu_set_context(tsk->mm->context);
 }
 
+static void srmmu_init_new_context(struct mm_struct *mm)
+{
+	alloc_context(mm);
+
+	flush_cache_mm(mm);
+	ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
+	flush_tlb_mm(mm);
+
+	if(mm == current->mm)
+		srmmu_set_context(mm->context);
+}
+
 /* Low level IO area allocation on the SRMMU. */
 void srmmu_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_type, int rdonly)
 {
@@ -1328,11 +1294,6 @@
 	return page;
 }
 
-static void viking_no_mxcc_pgd_flush(pgd_t *pgdp)
-{
-	viking_no_mxcc_flush_page((unsigned long)pgdp);
-}
-
 static void viking_flush_tlb_all(void)
 {
 	module_stats.invall++;
@@ -1450,7 +1411,9 @@
 		save_and_cli(flags);
 		octx = srmmu_get_context();
 		srmmu_set_context(mm->context);
-		a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+		a = 0x20; b = 0x40; c = 0x60;
+		d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+
 		faddr = (0x10000 - 0x100);
 		goto inside;
 		do {
@@ -1488,7 +1451,9 @@
 		save_and_cli(flags);
 		octx = srmmu_get_context();
 		srmmu_set_context(mm->context);
-		a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+		a = 0x20; b = 0x40; c = 0x60;
+		d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+
 		start &= SRMMU_PMD_MASK;
 		while(start < end) {
 			faddr = (start + (0x10000 - 0x100));
@@ -1532,7 +1497,9 @@
 		save_and_cli(flags);
 		octx = srmmu_get_context();
 		srmmu_set_context(mm->context);
-		a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+		a = 0x20; b = 0x40; c = 0x60;
+		d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+
 		page &= PAGE_MASK;
 		line = (page + PAGE_SIZE) - 0x100;
 		goto inside;
@@ -1656,34 +1623,6 @@
 	return page;
 }
 
-static void cypress_pgd_flush(pgd_t *pgdp)
-{
-	register unsigned long a, b, c, d, e, f, g;
-	unsigned long page = ((unsigned long) pgdp) & PAGE_MASK;
-	unsigned long line;
-
-	a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
-	page &= PAGE_MASK;
-	line = (page + PAGE_SIZE) - 0x100;
-	goto inside;
-	do {
-		line -= 0x100;
-	inside:
-		__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
-				     "sta %%g0, [%0 + %2] %1\n\t"
-				     "sta %%g0, [%0 + %3] %1\n\t"
-				     "sta %%g0, [%0 + %4] %1\n\t"
-				     "sta %%g0, [%0 + %5] %1\n\t"
-				     "sta %%g0, [%0 + %6] %1\n\t"
-				     "sta %%g0, [%0 + %7] %1\n\t"
-				     "sta %%g0, [%0 + %8] %1\n\t" : :
-				     "r" (line),
-				     "i" (ASI_M_FLUSH_PAGE),
-				     "r" (a), "r" (b), "r" (c), "r" (d),
-				     "r" (e), "r" (f), "r" (g));
-	} while(line != page);
-}
-
 static void cypress_flush_tlb_all(void)
 {
 	module_stats.invall++;
@@ -1888,19 +1827,6 @@
 	return page;
 }
 
-static void hypersparc_pgd_flush(pgd_t *pgdp)
-{
-	volatile unsigned long clear;
-	unsigned long page = ((unsigned long) pgdp) & PAGE_MASK;
-	unsigned long flags;
-
-	save_and_cli(flags);
-	if(srmmu_hwprobe(page))
-		hyper_flush_cache_page(page);
-	clear = srmmu_get_fstatus();
-	restore_flags(flags);
-}
-
 static void hypersparc_flush_tlb_all(void)
 {
 	module_stats.invall++;
@@ -1996,6 +1922,61 @@
 
 static void hypersparc_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) 
 {
+	volatile unsigned long clear;
+	unsigned long page = ((unsigned long) pgdp) & PAGE_MASK;
+	unsigned long flags;
+
+	/* Do PGD flush. */
+	save_and_cli(flags);
+	if(srmmu_hwprobe(page))
+		hyper_flush_cache_page(page);
+	clear = srmmu_get_fstatus();
+	restore_flags(flags);
+
+	if(tsk->mm->context != NO_CONTEXT) {
+		flush_cache_mm(current->mm);
+		ctxd_set(&srmmu_context_table[tsk->mm->context], pgdp);
+		flush_tlb_mm(current->mm);
+	}
+}
+
+static void viking_no_mxcc_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) 
+{
+	viking_no_mxcc_flush_page((unsigned long)pgdp);
+	if(tsk->mm->context != NO_CONTEXT) {
+		flush_cache_mm(current->mm);
+		ctxd_set(&srmmu_context_table[tsk->mm->context], pgdp);
+		flush_tlb_mm(current->mm);
+	}
+}
+
+static void cypress_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) 
+{
+	register unsigned long a, b, c, d, e, f, g;
+	unsigned long page = ((unsigned long) pgdp) & PAGE_MASK;
+	unsigned long line;
+
+	a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+	page &= PAGE_MASK;
+	line = (page + PAGE_SIZE) - 0x100;
+	goto inside;
+	do {
+		line -= 0x100;
+	inside:
+		__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
+				     "sta %%g0, [%0 + %2] %1\n\t"
+				     "sta %%g0, [%0 + %3] %1\n\t"
+				     "sta %%g0, [%0 + %4] %1\n\t"
+				     "sta %%g0, [%0 + %5] %1\n\t"
+				     "sta %%g0, [%0 + %6] %1\n\t"
+				     "sta %%g0, [%0 + %7] %1\n\t"
+				     "sta %%g0, [%0 + %8] %1\n\t" : :
+				     "r" (line),
+				     "i" (ASI_M_FLUSH_PAGE),
+				     "r" (a), "r" (b), "r" (c), "r" (d),
+				     "r" (e), "r" (f), "r" (g));
+	} while(line != page);
+
 	if(tsk->mm->context != NO_CONTEXT) {
 		flush_cache_mm(current->mm);
 		ctxd_set(&srmmu_context_table[tsk->mm->context], pgdp);
@@ -2007,14 +1988,28 @@
 {
 	hyper_flush_whole_icache();
 	if(tsk->mm->context == NO_CONTEXT) {
-		alloc_context(tsk);
-		flush_cache_mm(current->mm);
+		alloc_context(tsk->mm);
+		flush_cache_mm(tsk->mm);
 		ctxd_set(&srmmu_context_table[tsk->mm->context], tsk->mm->pgd);
-		flush_tlb_mm(current->mm);
+		flush_tlb_mm(tsk->mm);
 	}
 	srmmu_set_context(tsk->mm->context);
 }
 
+static void hypersparc_init_new_context(struct mm_struct *mm)
+{
+	hyper_flush_whole_icache();
+
+	alloc_context(mm);
+
+	flush_cache_mm(mm);
+	ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
+	flush_tlb_mm(mm);
+
+	if(mm == current->mm)
+		srmmu_set_context(mm->context);
+}
+
 /* IOMMU things go here. */
 
 #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
@@ -2842,10 +2837,8 @@
 {
 }
 
-static void srmmu_exit_hook(void)
+static void srmmu_destroy_context(struct mm_struct *mm)
 {
-	struct mm_struct *mm = current->mm;
-
 	if(mm->context != NO_CONTEXT && mm->count == 1) {
 		flush_cache_mm(mm);
 		ctxd_set(&srmmu_context_table[mm->context], swapper_pg_dir);
@@ -2855,17 +2848,6 @@
 	}
 }
 
-static void srmmu_flush_hook(void)
-{
-	if(current->tss.flags & SPARC_FLAG_KTHREAD) {
-		alloc_context(current);
-		flush_cache_mm(current->mm);
-		ctxd_set(&srmmu_context_table[current->mm->context], current->mm->pgd);
-		flush_tlb_mm(current->mm);
-		srmmu_set_context(current->mm->context);
-	}
-}
-
 static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
 				       unsigned long address, pte_t pte)
 {
@@ -2930,10 +2912,8 @@
 	}
 }
 
-static void hypersparc_exit_hook(void)
+static void hypersparc_destroy_context(struct mm_struct *mm)
 {
-	struct mm_struct *mm = current->mm;
-
 	if(mm->context != NO_CONTEXT && mm->count == 1) {
 		/* HyperSparc is copy-back, any data for this
 		 * process in a modified cache line is stale
@@ -2948,17 +2928,6 @@
 	}
 }
 
-static void hypersparc_flush_hook(void)
-{
-	if(current->tss.flags & SPARC_FLAG_KTHREAD) {
-		alloc_context(current);
-		flush_cache_mm(current->mm);
-		ctxd_set(&srmmu_context_table[current->mm->context], current->mm->pgd);
-		flush_tlb_mm(current->mm);
-		srmmu_set_context(current->mm->context);
-	}
-}
-
 /* Init various srmmu chip types. */
 __initfunc(static void srmmu_is_bad(void))
 {
@@ -3063,12 +3032,11 @@
 	flush_page_for_dma = hypersparc_flush_page_for_dma;
 	flush_cache_page_to_uncache = hypersparc_flush_cache_page_to_uncache;
 	flush_tlb_page_for_cbit = hypersparc_flush_tlb_page_for_cbit;
-	pgd_flush = hypersparc_pgd_flush;
 
 	ctxd_set = hypersparc_ctxd_set;
 	switch_to_context = hypersparc_switch_to_context;
-	mmu_exit_hook = hypersparc_exit_hook;
-	mmu_flush_hook = hypersparc_flush_hook;
+	init_new_context = hypersparc_init_new_context;
+	destroy_context = hypersparc_destroy_context;
 	update_mmu_cache = srmmu_vac_update_mmu_cache;
 	sparc_update_rootmmu_dir = hypersparc_update_rootmmu_dir;
 	poke_srmmu = poke_hypersparc;
@@ -3077,17 +3045,32 @@
 static void poke_cypress(void)
 {
 	unsigned long mreg = srmmu_get_mmureg();
-	unsigned long faddr;
+	unsigned long faddr, tagval;
+	volatile unsigned long cypress_sucks;
 	volatile unsigned long clear;
 
 	clear = srmmu_get_faddr();
 	clear = srmmu_get_fstatus();
 
-	for(faddr = 0x0; faddr < 0x10000; faddr += 20) {
-		__asm__ __volatile__("sta %%g0, [%0 + %1] %2\n\t"
-				     "sta %%g0, [%0] %2\n\t" : :
-				     "r" (faddr), "r" (0x40000),
-				     "i" (ASI_M_DATAC_TAG));
+	if (!(mreg & CYPRESS_CENABLE)) {
+		for(faddr = 0x0; faddr < 0x10000; faddr += 20) {
+			__asm__ __volatile__("sta %%g0, [%0 + %1] %2\n\t"
+					     "sta %%g0, [%0] %2\n\t" : :
+					     "r" (faddr), "r" (0x40000),
+					     "i" (ASI_M_DATAC_TAG));
+		}
+	} else {
+		for(faddr = 0; faddr < 0x10000; faddr += 0x20) {
+			__asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" :
+					     "=r" (tagval) :
+					     "r" (faddr), "r" (0x40000),
+					     "i" (ASI_M_DATAC_TAG));
+
+			/* If modified and valid, kick it. */
+			if((tagval & 0x60) == 0x60)
+				cypress_sucks = *(unsigned long *)
+							(0xf0020000 + faddr);
+		}
 	}
 
 	/* And one more, for our good neighbor, Mr. Broken Cypress. */
@@ -3119,7 +3102,7 @@
 	flush_page_for_dma = cypress_flush_page_for_dma;
 	flush_cache_page_to_uncache = cypress_flush_page_to_uncache;
 	flush_tlb_page_for_cbit = cypress_flush_tlb_page_for_cbit;
-	pgd_flush = cypress_pgd_flush;
+	sparc_update_rootmmu_dir = cypress_update_rootmmu_dir;
 
 	update_mmu_cache = srmmu_vac_update_mmu_cache;
 	poke_srmmu = poke_cypress;
@@ -3355,7 +3338,7 @@
 
 		mmu_getpage = viking_no_mxcc_getpage;
 		set_pte = srmmu_set_pte_nocache_nomxccvik;
-		pgd_flush = viking_no_mxcc_pgd_flush;
+		sparc_update_rootmmu_dir = viking_no_mxcc_update_rootmmu_dir;
 
 		flush_cache_page_to_uncache = viking_no_mxcc_flush_page;
 
@@ -3538,7 +3521,7 @@
 	/* Functions */
 	mmu_getpage = srmmu_getpage;
 	set_pte = srmmu_set_pte_cacheable;
-	switch_to_context = srmmu_switch_to_context;
+	init_new_context = srmmu_init_new_context;
 	pmd_align = srmmu_pmd_align;
 	pgdir_align = srmmu_pgdir_align;
 	vmalloc_start = srmmu_vmalloc_start;
@@ -3581,7 +3564,6 @@
 	pmd_alloc = srmmu_pmd_alloc;
 	pgd_free = srmmu_pgd_free;
 	pgd_alloc = srmmu_pgd_alloc;
-	pgd_flush = srmmu_pgd_flush;
 
 	pte_write = srmmu_pte_write;
 	pte_dirty = srmmu_pte_dirty;
@@ -3593,8 +3575,7 @@
 	pte_mkdirty = srmmu_pte_mkdirty;
 	pte_mkyoung = srmmu_pte_mkyoung;
 	update_mmu_cache = srmmu_update_mmu_cache;
-	mmu_exit_hook = srmmu_exit_hook;
-	mmu_flush_hook = srmmu_flush_hook;
+	destroy_context = srmmu_destroy_context;
 	mmu_lockarea = srmmu_lockarea;
 	mmu_unlockarea = srmmu_unlockarea;
 
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/mm/sun4c.c linux/arch/sparc/mm/sun4c.c
--- v2.1.18/linux/arch/sparc/mm/sun4c.c	Mon Dec 30 15:39:04 1996
+++ linux/arch/sparc/mm/sun4c.c	Mon Dec 30 11:59:58 1996
@@ -1,4 +1,4 @@
-/* $Id: sun4c.c,v 1.135 1996/12/23 05:27:50 davem Exp $
+/* $Id: sun4c.c,v 1.137 1996/12/30 06:16:36 davem Exp $
  * sun4c.c: Doing in software what should be done in hardware.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -21,6 +21,7 @@
 #include <asm/io.h>
 #include <asm/oplib.h>
 #include <asm/openprom.h>
+#include <asm/mmu_context.h>
 
 extern int num_segmaps, num_contexts;
 
@@ -1609,22 +1610,16 @@
 	restore_flags(flags);
 }
 
-static void sun4c_flush_hook(void)
+static void sun4c_init_new_context(struct mm_struct *mm)
 {
-	if(current->tss.flags & SPARC_FLAG_KTHREAD) {
-		unsigned long flags;
-
-		save_flags(flags);
-		sun4c_alloc_context(current->mm);
-		sun4c_set_context(current->mm->context);
-		restore_flags(flags);
-	}
+	sun4c_alloc_context(mm);
+	if(mm == current->mm)
+		sun4c_set_context(mm->context);
 }
 
-static void sun4c_exit_hook(void)
+static void sun4c_destroy_context(struct mm_struct *mm)
 {
 	struct ctx_list *ctx_old;
-	struct mm_struct *mm = current->mm;
 
 	if(mm->context != NO_CONTEXT && mm->count == 1) {
 		unsigned long flags;
@@ -2038,10 +2033,6 @@
 	restore_flags(flags);
 }
 
-static void sun4c_pgd_flush(pgd_t *pgdp)
-{
-}
-
 extern unsigned long free_area_init(unsigned long, unsigned long);
 extern unsigned long sparc_context_init(unsigned long, int);
 extern unsigned long end;
@@ -2177,7 +2168,6 @@
 	pmd_alloc = sun4c_pmd_alloc;
 	pgd_free = sun4c_pgd_free;
 	pgd_alloc = sun4c_pgd_alloc;
-	pgd_flush = sun4c_pgd_flush;
 
 	pte_write = sun4c_pte_write;
 	pte_dirty = sun4c_pte_dirty;
@@ -2189,8 +2179,8 @@
 	pte_mkdirty = sun4c_pte_mkdirty;
 	pte_mkyoung = sun4c_pte_mkyoung;
 	update_mmu_cache = sun4c_update_mmu_cache;
-	mmu_exit_hook = sun4c_exit_hook;
-	mmu_flush_hook = sun4c_flush_hook;
+	destroy_context = sun4c_destroy_context;
+	init_new_context = sun4c_init_new_context;
 	mmu_lockarea = sun4c_lockarea;
 	mmu_unlockarea = sun4c_unlockarea;
 
diff -u --recursive --new-file v2.1.18/linux/arch/sparc/prom/tree.c linux/arch/sparc/prom/tree.c
--- v2.1.18/linux/arch/sparc/prom/tree.c	Sun Dec 22 16:37:30 1996
+++ linux/arch/sparc/prom/tree.c	Mon Dec 30 11:59:58 1996
@@ -1,11 +1,10 @@
-/* $Id: tree.c,v 1.13 1996/12/18 06:46:56 tridge Exp $
+/* $Id: tree.c,v 1.14 1996/12/29 20:46:12 davem Exp $
  * tree.c: Basic device tree traversal/scanning for the Linux
  *         prom library.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  */
 
-#include <linux/config.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/Makefile linux/arch/sparc64/Makefile
--- v2.1.18/linux/arch/sparc64/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/Makefile	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,45 @@
+# $Id: Makefile,v 1.2 1996/12/27 17:28:20 davem Exp $
+# sparc64/Makefile
+#
+# Makefile for the architecture dependent flags and dependencies on the
+# 64-bit Sparc.
+#
+# Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+#
+
+# If the solaris /bin/sh wasn't so broken, I wouldn't need the following
+# line...
+SHELL  =/bin/bash
+
+CC		= sparc64-linux-gcc -D__KERNEL__ -I$(TOPDIR)/include
+AS		= sparc64-linux-as
+LD		= sparc64-linux-ld
+NM		= sparc64-linux-nm
+AR		= sparc64-linux-ar
+RANLIB		= sparc64-linux-ranlib
+
+#
+# Uncomment the first CFLAGS if you are doing kgdb source level
+# debugging of the kernel to get the proper debugging information.
+
+#CFLAGS := $(CFLAGS) -g -pipe
+CFLAGS := $(CFLAGS) -pipe
+
+LINKFLAGS = -N -Ttext 0xFFFFF80000008000
+
+HEAD := arch/sparc/kernel/head.o
+
+SUBDIRS := $(SUBDIRS) arch/sparc64/kernel arch/sparc64/lib arch/sparc64/mm \
+	arch/sparc64/prom
+
+ARCHIVES := arch/sparc64/kernel/kernel.o arch/sparc64/mm/mm.o $(ARCHIVES)
+
+LIBS := $(TOPDIR)/lib/lib.a $(LIBS) $(TOPDIR)/arch/sparc64/prom/promlib.a \
+	$(TOPDIR)/arch/sparc64/lib/lib.a
+
+INITOBJ = $(TOPDIR)/arch/sparc64/kernel/initobj.o
+FINITOBJ = $(TOPDIR)/arch/sparc64/kernel/finitobj.o
+
+archclean:
+
+archdep:
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/config.in linux/arch/sparc64/config.in
--- v2.1.18/linux/arch/sparc64/config.in	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/config.in	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,149 @@
+# $Id: config.in,v 1.1 1996/12/27 17:28:19 davem Exp $
+# For a description of the syntax of this configuration file,
+# see the Configure script.
+#
+mainmenu_name "Linux/SPARC Kernel Configuration"
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+  bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
+  bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+
+bool 'Support for AP1000 multicomputer' CONFIG_AP1000
+
+if [ "$CONFIG_AP1000" = "y" ]; then
+	define_bool CONFIG_NO_KEYBOARD y
+	define_bool CONFIG_APFDDI y
+	define_bool CONFIG_APBLOCK y
+	define_bool CONFIG_APBIF y
+	tristate 'OPIU DDV Driver' CONFIG_DDV
+else
+	# Global things across all Sun machines.
+	define_bool CONFIG_SBUS y
+	define_bool CONFIG_SBUSCHAR y
+	define_bool CONFIG_SUN_MOUSE y
+	define_bool CONFIG_SERIAL y
+	define_bool CONFIG_SUN_SERIAL y
+	define_bool CONFIG_SUN_KEYBOARD y
+	define_bool CONFIG_SUN_CONSOLE y
+	define_bool CONFIG_SUN_AUXIO y
+	define_bool CONFIG_SUN_IO y
+	source drivers/sbus/char/Config.in
+fi
+
+tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS
+bool 'Networking support' CONFIG_NET
+bool 'System V IPC' CONFIG_SYSVIPC
+tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Floppy, IDE, and other block devices'
+
+bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD
+
+bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD
+if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
+  tristate '   Linear (append) mode' CONFIG_MD_LINEAR
+  tristate '   RAID-0 (striping) mode' CONFIG_MD_STRIPED
+#  tristate '   RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
+fi
+
+tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
+if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
+  bool '   Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
+fi
+
+tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
+
+endmenu
+
+if [ "$CONFIG_NET" = "y" ]; then
+	source net/Config.in
+fi
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+	comment 'SCSI support type (disk, tape, CDrom)'
+
+	dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
+	dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
+	dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
+	if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
+	  bool '  Enable vendor-specific extentions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
+	fi
+	dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
+
+	comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
+
+	bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
+
+	bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
+
+	mainmenu_option next_comment
+	comment 'SCSI low-level drivers'
+
+	bool 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI
+	tristate 'PTI Qlogic,ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI
+	endmenu
+fi
+endmenu
+
+if [ "$CONFIG_NET" = "y" ]; then
+	mainmenu_option next_comment
+	comment 'Network device support'
+
+	bool 'Network device support' CONFIG_NETDEVICES
+	if [ "$CONFIG_NETDEVICES" = "y" ]; then
+		tristate 'Dummy net driver support' CONFIG_DUMMY
+		tristate 'PPP (point-to-point) support' CONFIG_PPP
+		if [ ! "$CONFIG_PPP" = "n" ]; then
+		   comment 'CCP compressors for PPP are only built as modules.'
+		fi
+		tristate 'SLIP (serial line) support' CONFIG_SLIP
+		if [ "$CONFIG_SLIP" != "n" ]; then
+		  bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
+		  bool ' Keepalive and linefill' CONFIG_SLIP_SMART
+		  bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6
+		fi
+		bool 'Sun LANCE support' CONFIG_SUNLANCE
+		tristate 'Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL
+		tristate 'Sun QuadEthernet support' CONFIG_SUNQE
+		tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS
+#		bool 'FDDI driver support' CONFIG_FDDI
+#		if [ "$CONFIG_FDDI" = "y" ]; then
+#		fi
+	fi
+	endmenu
+fi
+
+source fs/Config.in
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Kernel profiling support' CONFIG_PROFILE
+if [ "$CONFIG_PROFILE" = "y" ]; then
+	int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+fi
+endmenu
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.1.18/linux/arch/sparc64/defconfig	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/defconfig	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,195 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+# CONFIG_AP1000 is not set
+CONFIG_SBUS=y
+CONFIG_SBUSCHAR=y
+CONFIG_SUN_MOUSE=y
+CONFIG_SERIAL=y
+CONFIG_SUN_SERIAL=y
+CONFIG_SUN_KEYBOARD=y
+CONFIG_SUN_CONSOLE=y
+CONFIG_SUN_AUXIO=y
+CONFIG_SUN_IO=y
+
+#
+# SBUS Frame Buffer support
+#
+SUN_FBS_IN_PROCFS=y
+CONFIG_SUN_FB_DISPLAY=y
+SUN_FB_CGSIX=y
+SUN_FB_TCX=y
+SUN_FB_CGTHREE=y
+SUN_FB_CGFOURTEEN=y
+SUN_FB_BWTWO=y
+SUN_FB_LEO=y
+TADPOLE_FB_WEITEK=y
+SUN_FB_FAST_ONE=y
+SUN_FB_FAST_TWO=y
+SUN_FB_FAST_MONO=y
+SUN_FB_GENERIC=y
+
+#
+# Misc Linux/SPARC drivers
+#
+CONFIG_SUN_OPENPROMIO=y
+CONFIG_SUN_MOSTEK_RTC=y
+CONFIG_SUN_OPENPROMFS=y
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_JAVA=y
+
+#
+# Floppy, IDE, and other block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_STRIPED=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_LOOP=y
+
+#
+# Networking options
+#
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_FIREWALL=y
+CONFIG_NET_ALIAS=y
+CONFIG_INET=y
+CONFIG_IP_FORWARD=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_FIREWALL=y
+# CONFIG_IP_FIREWALL_NETLINK is not set
+# CONFIG_IP_FIREWALL_VERBOSE is not set
+CONFIG_IP_MASQUERADE=y
+
+#
+# Protocol-specific masquerading support will be built as modules.
+#
+# CONFIG_IP_TRANSPARENT_PROXY is not set
+# CONFIG_IP_ALWAYS_DEFRAG is not set
+# CONFIG_IP_ACCT is not set
+# CONFIG_IP_ROUTER is not set
+CONFIG_NET_IPIP=y
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+# CONFIG_ARPD is not set
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_INET_PCTCP is not set
+CONFIG_INET_RARP=y
+# CONFIG_PATH_MTU_DISCOVERY is not set
+CONFIG_IP_NOSR=y
+CONFIG_SKB_LARGE=y
+CONFIG_IPV6=y
+
+#
+#  
+#
+CONFIG_IPX=y
+# CONFIG_IPX_INTERN is not set
+# CONFIG_IPX_PPROP_ROUTING is not set
+CONFIG_ATALK=y
+# CONFIG_AX25 is not set
+CONFIG_X25=y
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CDrom)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SCSI_SUNESP=y
+CONFIG_SCSI_QLOGICPTI=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_PPP=y
+
+#
+# CCP compressors for PPP are only built as modules.
+#
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_SUNLANCE=y
+CONFIG_HAPPYMEAL=y
+CONFIG_SUNQE=y
+CONFIG_MYRI_SBUS=y
+
+#
+# Filesystems
+#
+CONFIG_QUOTA=y
+CONFIG_MINIX_FS=y
+CONFIG_EXT_FS=y
+CONFIG_EXT2_FS=y
+CONFIG_XIA_FS=y
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_UMSDOS_FS=y
+CONFIG_PROC_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_RNFS_BOOTP=y
+CONFIG_RNFS_RARP=y
+CONFIG_SMB_FS=y
+CONFIG_SMB_WIN95=y
+CONFIG_NCP_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_HPFS_FS=y
+CONFIG_SYSV_FS=y
+CONFIG_AFFS_FS=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_UFS_FS=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_SMD_DISKLABEL=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PROFILE is not set
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/Makefile linux/arch/sparc64/kernel/Makefile
--- v2.1.18/linux/arch/sparc64/kernel/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/Makefile	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,32 @@
+# $Id: Makefile,v 1.1 1996/12/26 10:16:41 davem Exp $
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+.S.s:
+	$(CPP) -D__ASSEMBLY__ -ansi $< -o $*.s
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ -ansi -c $< -o $*.o
+
+all: kernel.o head.o initobj.o finitobj.o
+
+O_TARGET := kernel.o
+O_OBJS   := etrap.o rtrap.o signal32.o
+OX_OBJS  := sparc64_ksyms.o
+
+head.o: head.S
+	$(CC) -D__ASSEMBLY__ -ansi -c $*.S -o $*.o
+
+initobj.o: initobj.S
+	$(CC) -D__ASSEMBLY__ -ansi -c initobj.S -o initobj.o
+
+finitobj.o: initobj.S
+	$(CC) -D__ASSEMBLY__ -ansi -c finitobj.S -o finitobj.o
+
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/dtlb_miss.S linux/arch/sparc64/kernel/dtlb_miss.S
--- v2.1.18/linux/arch/sparc64/kernel/dtlb_miss.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/dtlb_miss.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,94 @@
+/* $Id: dtlb_miss.S,v 1.4 1996/12/28 18:39:40 davem Exp $
+ * dtlb_miss.S:	Data TLB miss code, this is included directly
+ *              into the trap table.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+	/* We are in the MMU globals, %g7 contains the physical
+	 * address of current->mm->pgd at all times.
+	 *
+	 * Many subtle things are done here.  The high bits of
+	 * the virtual address missed are most easily obtained
+	 * from the tag target (it is at address zero in ASI_IMMU
+	 * so no address formation is necessary to get at this).
+	 * This is used to compute the pgd and pmd table offsets.
+	 *
+	 * Even more clever is that physical page zero is always
+	 * a page full of zeroes.  This means we can just follow
+	 * through with all the page table traversals even if nothing
+	 * is mapped because we'll just do loads from page zero
+	 * and get yet another zero.  We only need to do the check
+	 * for the valid bit being set in the final pte we obtain.
+	 *
+	 * Furthermore, we set the TSB base register to the address
+	 * zero, and we use the 8KB tsb ptr to calculate the pte
+	 * offset.  Again it is at address zero in ASI_IMMU_TSB_8KB_PTR
+	 * so no address formation is necessary, saves more instructions.
+	 *
+	 * We use physical address accesses to get at the page
+	 * tables, and this is for two reasons.  This makes it
+	 * impossible to take a fault while we are servicing the
+	 * miss.  Also this physical bypass access only allocates
+	 * in the E-cache, and thus we prevent D-cache pollution
+	 * from the miss handlers probing the page tables.
+	 *
+	 * It looks very hairy and slow.  But I take only 1 more
+	 * overhead of loads from ram than the Solaris version, and
+	 * my version is one instruction quicker for a true TLB miss.
+	 * And more importantly, all true TLB misses under Linux will be
+	 * serviced in _constant_ time.  When using the TSB in the
+	 * manner it was intended to be used (like solaris does) the
+	 * overhead for a TLB miss is _indeterminate_ especially during
+	 * processes startup when the TSB is cold.
+	 *
+	 * XXX I think I can knock off two more instructions here...
+	 */
+
+dtlb_miss:
+	/* I-cache line 0 */
+	ldxa		[%g0] ASI_DMMU, %g1		! grab Tag Target either way
+	brlz,pnt	%g1, 3f				! special kernel processing
+	 srlx		%g1, 8, %g3			! put high vaddr bits in place
+
+1:
+	and		%g3, %g2, %g3			! get offset
+	ldxa		[%g7 + %g3] ASI_PHYS_USE_EC, %g5! load pgd
+	sllx		%g1, 2, %g4			! begin pmd_offset formation
+	and		%g4, %g2, %g3			! and now mask it
+	ldxa		[%g5 + %g3] ASI_PHYS_USE_EC, %g4! load pmd
+	/* I-cache line 1 */
+	ldxa		[%g0] ASI_DMMU_TSB_8KB_PTR, %g1	! get 8KB pointer bits
+	srlx		%g1, 1, %g1			! shift right to get pte_offset
+	ldxa		[%g4 + %g1] ASI_PHYS_USE_EC, %g3! load pte
+	brlz,a,pt	%g3, 2f				! is valid bit clear?
+	 stxa		%g3, [%g0] ASI_DTLB_DATA_IN	! nope, load TTE into DTLB
+
+	ba,a,pt		%xcc, sparc64_dtlb_refbit_catch	! longer processing needed
+2:
+	retry						! return from trap
+
+#define KTTE_HIGH_BITS	(_PAGE_VALID | _PAGE_SZ4MB)
+#define KTTE_LOW_BITS	(_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W | _PAGE_G)
+
+	nop						! align next insn on cache line
+3:
+	/* I-cache line 2 */
+	srax		%g1, 19, %g5			! mask down high bits
+	cmp		%g5, -1				! if -1 this is VMALLOC area
+	be,pnt		%xcc, 1b			! yep
+	 sethi		%uhi(KTTE_HIGH_BITS), %g4	! begin pte formation
+
+	sllx		%g1, 23, %g1			! begin masking for physpage
+	sllx		%g4, 32, %g4			! high protection TTE bits
+	or		%g4, (KTTE_LOW_BITS), %g4	! low protection TTE bits
+	srlx		%g1, 41, %g1			! put physpage into place
+	/* I-cache line 3 */
+	or		%g4, %g1, %g1			! finish TTE computation
+	stxa		%g1, [%g0] ASI_DTLB_DATA_IN	! load TTE into DTLB
+	retry						! return from trap
+
+	nop; nop; nop; nop; nop;
+
+#undef KTTE_HIGH_BITS
+#undef KTTE_LOW_BITS
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/dtlb_prot.S linux/arch/sparc64/kernel/dtlb_prot.S
--- v2.1.18/linux/arch/sparc64/kernel/dtlb_prot.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/dtlb_prot.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,63 @@
+/* $Id: dtlb_prot.S,v 1.3 1996/12/28 18:39:41 davem Exp $
+ * dtlb_prot.S:	Fast TLB protection trap processing.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+	/* We are in the MMU globals, %g7 contains the physical
+	 * address of current->mm->pgd at all times.  %g2 is
+	 * also preloaded with the mask 0x1ff8 to make things
+	 * even quicker.
+	 *
+	 * Many subtle things are done here.  The high bits of
+	 * the virtual address missed are most easily obtained
+	 * from the tag target (it is at address zero in ASI_IMMU
+	 * so no address formation is necessary to get at this).
+	 * This is used to compute the pgd and pmd table offsets.
+	 *
+	 * Even more clever is that physical page zero is always
+	 * a page full of zeroes.  This means we can just follow
+	 * through with all the page table traversals even if nothing
+	 * is mapped because we'll just do loads from page zero
+	 * and get yet another zero.  We only need to do the check
+	 * for the valid bit being set in the final pte we obtain.
+	 *
+	 * Furthermore, we set the TSB base register to the address
+	 * zero, and we use the 8KB tsb ptr to calculate the pte
+	 * offset.  Again it is at address zero in ASI_IMMU_TSB_8KB_PTR
+	 * so no address formation is necessary, saves more instructions.
+	 *
+	 * We use physical address accesses to get at the page
+	 * tables, and this is for two reasons.  This makes it
+	 * impossible to take a fault while we are servicing the
+	 * miss.  Also this physical bypass access only allocates
+	 * in the E-cache, and thus we prevent D-cache pollution
+	 * from the miss handlers probing the page tables.
+	 */
+
+dtlb_prot:
+	/* I-cache line 0 */
+	ldxa		[%g0] ASI_DMMU, %g1
+	srlx		%g1, 8, %g3
+	and		%g3, %g2, %g3
+	ldxa		[%g7 + %g3] ASI_PHYS_USE_EC, %g5
+	sllx		%g1, 2, %g4
+	and		%g4, %g2, %g3
+	ldxa		[%g5 + %g3] ASI_PHYS_USE_EC, %g4
+	ldxa		[%g0] ASI_DMMU_TSB_8KB_PTR, %g1
+	/* I-cache line 1 */
+	srlx		%g1, 1, %g1
+	ldxa		[%g4 + %g1] ASI_PHYS_USE_EC, %g3
+	andcc		%g3, _PAGE_WRITE, %g0
+	be,pnt		%xcc, sparc64_dtlb_fault
+	 or		%g3, (_PAGE_WRITE|_PAGE_W|_PAGE_MODIFIED|_PAGE_ACCESSED), %g3
+
+	/* Blamo... */
+	stxa		%g3, [%g4 + %g1] %asi
+	stxa		%g3, [%g0] ASI_DTLB_DATA_IN
+	retry
+
+	/* I-cache line 2 */
+	nop; nop; nop; nop; nop; nop; nop; nop;
+	/* I-cache line 3 */
+	nop; nop; nop; nop; nop; nop; nop; nop;
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/etrap.S linux/arch/sparc64/kernel/etrap.S
--- v2.1.18/linux/arch/sparc64/kernel/etrap.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/etrap.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,52 @@
+/* $Id: etrap.S,v 1.1 1996/12/26 10:16:42 davem Exp $
+ * etrap.S: Preparing for entry into the kernel on Sparc V9.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/pstate.h>
+#include <asm/ptrace.h>
+
+	.text
+	.align	4
+	.globl	etrap
+etrap:
+	sethi	%uhi(current_set), %g6
+	rd	%tstate, %g1
+	or	%g6, %ulo(current_set), %g6
+	rd	%tpc, %g2
+	sllx	%g6, 32, %g6
+	rd	%tnpc, %g3
+	sethi	%hi(current_set), %g4
+	or	%g4, %lo(current_set), %g4
+	or	%g6, %g4, %g6
+	rd	%y, %g4
+	ldx	[%g6 + THREAD_KSTACK], %g5
+	stx	%g1, [%g5 + REGWIN_SZ + PT_TSTATE]
+	stx	%g2, [%g5 + REGWIN_SZ + PT_TPC]
+	stx	%g3, [%g5 + REGWIN_SZ + PT_TNPC]
+	stx	%g4, [%g5 + REGWIN_SZ + PT_Y]
+	rd	%pstate, %g1
+	andn	%g1, (PSTATE_IG | PSTATE_MG | PSTATE_AG), %g2
+	save	%g5, 0x0, %sp
+	mov	%g2, %l1
+	wr	%g0, 0x0, %tl
+	mov	%g7, %l2
+	wr	%l1, 0x0, %pstate
+	stx	%g1, [%sp + REGWIN_SZ + PT_G1]
+	stx	%g2, [%sp + REGWIN_SZ + PT_G2]
+	stx	%g3, [%sp + REGWIN_SZ + PT_G3]
+	stx	%g4, [%sp + REGWIN_SZ + PT_G4]
+	stx	%g5, [%sp + REGWIN_SZ + PT_G5]
+	stx	%g6, [%sp + REGWIN_SZ + PT_G6]
+	stx	%g7, [%sp + REGWIN_SZ + PT_G7]
+	stx	%i0, [%sp + REGWIN_SZ + PT_I0]
+	stx	%i1, [%sp + REGWIN_SZ + PT_I1]
+	stx	%i2, [%sp + REGWIN_SZ + PT_I2]
+	stx	%i3, [%sp + REGWIN_SZ + PT_I3]
+	stx	%i4, [%sp + REGWIN_SZ + PT_I4]
+	stx	%i5, [%sp + REGWIN_SZ + PT_I5]
+	stx	%i6, [%sp + REGWIN_SZ + PT_I6]
+	stx	%i7, [%sp + REGWIN_SZ + PT_I7]
+	jmpl	%l2 + 0x4, %g0
+	 wr	%l1, PSTATE_IE, %pstate
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/finitobj.S linux/arch/sparc64/kernel/finitobj.S
--- v2.1.18/linux/arch/sparc64/kernel/finitobj.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/finitobj.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,6 @@
+	.section	".text.init",#alloc,#execinstr
+	.globl	text_init_end
+text_init_end:
+	.section	".data.init",#alloc,#write
+	.globl	data_init_end
+data_init_end:
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/head.S linux/arch/sparc64/kernel/head.S
--- v2.1.18/linux/arch/sparc64/kernel/head.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/head.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,114 @@
+/* $Id: head.S,v 1.4 1996/12/28 18:39:42 davem Exp $
+ * head.S: Initial boot code for the Sparc64 port of Linux.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/pstate.h>
+#include <asm/spitfire.h>
+#include <asm/pgtable.h>
+
+	.text
+
+#include "ttable.S"
+
+sparc64_boot:
+	rdpr	%ver, %g1			/* Get VERSION register.	*/
+	mov	%o4, %g2			/* Get OpenPROM vector.		*/
+
+	/* We must be careful, 32-bit OpenBOOT will get confused if it
+	 * tries to save away a register window to a 64-bit kernel
+	 * stack address.  Flush all windows, disable interrupts,
+	 * remap if necessary, jump onto kernel trap table, then kernel
+	 * stack, or else we die.
+	 */
+	flushw					/* Flush register file.      */
+	wrpr	%g0, 0xf, %pil			/* Interrupts off.           */
+
+	/* Remap ourselves to upper 64-bit addresses if necessary.
+	 * SILO64 will have loaded us to the right location already.
+	 */
+	mov	%o7, %g4
+current_pc:
+	call	1f
+	 mov	%o7, %g3
+1:
+	mov	%g4, %o7
+
+	set	current_pc, %g7
+	cmp	%g3, %g7
+	be	go_to_highmem
+	 nop
+
+	/* Remap ourselves into high addresses. */
+	set	PAGE_OFFSET, %g4
+	sethi	%uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
+	sllx	%g5, 32, %g5
+	or	%g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W | _PAGE_G | _PAGE_L), %g5
+
+	/* Be real fucking anal... */
+	stxa	%g0, [%g4] ASI_IMMU_DEMAP
+	stxa	%g0, [%g4] ASI_DMMU_DEMAP
+	membar	#Sync
+	flush	%g4
+
+	mov	TLB_TAG_ACCESS, %g6
+	stxa	%g4, [%g6] ASI_IMMU
+	stxa	%g5, [%g0] ASI_ITLB_DATA_IN
+	membar	#Sync
+	flush	%g4
+
+	stxa	%g4, [%g6] ASI_DMMU
+	stxa	%g5, [%g0] ASI_DTLB_DATA_IN
+	membar	#Sync
+	flush	%g4
+
+go_to_highmem:
+	set	execute_in_high_mem, %g7
+	jmpl	%g7, %g0
+	 nop
+
+execute_in_high_mem:
+
+	set	nwindows, %g7
+	and	%g1, VERS_MAXWIN, %g5
+	add	%g5, 1, %g4
+	stx	%g4, [%g7]
+	set	nwindowsm1, %g6
+	stx	%g5, [%g6]
+	set	romvec, %g7
+	stx	%g2, [%g7]
+	set	prom_sp, %g7
+	stx	%sp, [%g7]
+	set	swapper_pg_dir, %g6
+	set	PAGE_OFFSET, %g4		! this stays here for a long time
+	sub	%g6, %g4, %g5
+	set	init_task, %g6			! g6 usage is fixed as well
+
+	set	sparc64_ttable_tl0, %g5
+	wrpr	%g5, %tba
+
+	set	bootup_kernel_stack, %sp
+	mov	0, %fp
+	wrpr	%g0, PSTATE_KERNEL, %pstate
+	wrpr	%g0, WSTATE_KERNEL, %wstate
+	wrpr	%g0, 0x0, %tl
+
+	/* XXX Map in PROM 32-bit trampoline code. */
+	
+	call	prom_init
+	 mov	%o4, %o0
+
+	/* Off we go.... */
+	call	start_kernel
+	 nop
+
+	/* Not reached... */
+
+	.data
+	.align	4
+	.globl	nwindows, nwindowsm1, romvec, prom_sp
+nwindows:	.xword	0
+nwindowsm1:	.xword	0
+romvec:		.xword	0
+prom_sp:	.xword	0
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/idprom.c linux/arch/sparc64/kernel/idprom.c
--- v2.1.18/linux/arch/sparc64/kernel/idprom.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/idprom.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,51 @@
+/* $Id: idprom.c,v 1.1 1996/12/28 18:39:38 davem Exp $
+ * idprom.c: Routines to load the idprom into kernel addresses and
+ *           interpret the data contained within.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <asm/oplib.h>
+#include <asm/idprom.h>
+
+struct idprom *idprom;
+static struct idprom idprom_buffer;
+
+/* Calculate the IDPROM checksum (xor of the data bytes). */
+__initfunc(static unsigned char calc_idprom_cksum(struct idprom *idprom))
+{
+	unsigned char cksum, i, *ptr = (unsigned char *)idprom;
+
+	for (i = cksum = 0; i <= 0x0E; i++)
+		cksum ^= *ptr++;
+
+	return cksum;
+}
+
+/* Create a local IDPROM copy and verify integrity. */
+__initfunc(void idprom_init(void))
+{
+	prom_get_idprom((char *) &idprom_buffer, sizeof(idprom_buffer));
+
+	idprom = &idprom_buffer;
+
+	if (idprom->id_format != 0x01)  {
+		prom_printf("IDPROM: Unknown format type!\n");
+		prom_halt();
+	}
+
+	if (idprom->id_cksum != calc_idprom_cksum(idprom)) {
+		prom_printf("IDPROM: Checksum failure (nvram=%x, calc=%x)!\n",
+			    idprom->id_cksum, calc_idprom_cksum(idprom));
+		prom_halt();
+	}
+
+	printk("Ethernet address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+	       idprom->id_ethaddr[0], idprom->id_ethaddr[1],
+	       idprom->id_ethaddr[2], idprom->id_ethaddr[3],
+	       idprom->id_ethaddr[4], idprom->id_ethaddr[5]);
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/initobj.S linux/arch/sparc64/kernel/initobj.S
--- v2.1.18/linux/arch/sparc64/kernel/initobj.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/initobj.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,15 @@
+#include <asm/errno.h>
+
+	.section	".text.init",#alloc,#execinstr
+	.globl	text_init_begin
+text_init_begin:
+	.section	".data.init",#alloc,#write
+	.globl	data_init_begin
+data_init_begin:
+
+	.section	".fixup",#alloc,#execinstr
+	.globl	__ret_efault
+__ret_efault:
+	ret
+	 restore %g0, -EFAULT, %o0
+
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/ioport.c linux/arch/sparc64/kernel/ioport.c
--- v2.1.18/linux/arch/sparc64/kernel/ioport.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/ioport.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,133 @@
+/* $Id: ioport.c,v 1.1 1996/12/28 18:39:39 davem Exp $
+ * ioport.c:  Simple io mapping allocator.
+ *
+ * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/vaddrs.h>
+#include <asm/oplib.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+/* This points to the next to use virtual memory for io mappings */
+static unsigned long dvma_next_free   = DVMA_VADDR;
+unsigned long sparc_iobase_vaddr = IOBASE_VADDR;
+
+/*
+ * sparc_alloc_io:
+ * Map and allocates an obio device.
+ * Implements a simple linear allocator, you can force the function
+ * to use your own mapping, but in practice this should not be used.
+ *
+ * Input:
+ *  address: the obio address to map
+ *  virtual: if non zero, specifies a fixed virtual address where
+ *           the mapping should take place.
+ *  len:     the length of the mapping
+ *  bus_type: The bus on which this io area sits.
+ *
+ * Returns:
+ *  The virtual address where the mapping actually took place.
+ */
+
+void *sparc_alloc_io (void *address, void *virtual, int len, char *name,
+		      int bus_type, int rdonly)
+{
+	unsigned long vaddr, base_address;
+	unsigned long addr = (unsigned long) address;
+	unsigned long offset = (addr & (~PAGE_MASK));
+
+	if (virtual) {
+		vaddr = (unsigned long) virtual;
+
+		len += offset;
+		if(((unsigned long) virtual + len) > (IOBASE_VADDR + IOBASE_LEN)) {
+			prom_printf("alloc_io: Mapping outside IOBASE area\n");
+			prom_halt();
+		}
+		if(check_region ((vaddr | offset), len)) {
+			prom_printf("alloc_io: 0x%lx is already in use\n", vaddr);
+			prom_halt();
+		}
+
+		/* Tell Linux resource manager about the mapping */
+		request_region ((vaddr | offset), len, name);
+	} else {
+		vaddr = occupy_region(sparc_iobase_vaddr, IOBASE_END,
+				(offset + len + PAGE_SIZE-1) & PAGE_MASK, PAGE_SIZE, name);
+		if (vaddr == 0) {
+			/* Usually we cannot see printks in this case. */
+			prom_printf("alloc_io: cannot occupy %d region\n", len);
+			prom_halt();
+		}
+	}
+
+	base_address = vaddr;
+	/* Do the actual mapping */
+	for (; len > 0; len -= PAGE_SIZE) {
+		mapioaddr(addr, vaddr, bus_type, rdonly);
+		vaddr += PAGE_SIZE;
+		addr += PAGE_SIZE;
+	}
+
+	return (void *) (base_address | offset);
+}
+
+void sparc_free_io (void *virtual, int len)
+{
+	unsigned long vaddr = (unsigned long) virtual & PAGE_MASK;
+	unsigned long plen = (((unsigned long)virtual & ~PAGE_MASK) + len + PAGE_SIZE-1) & PAGE_MASK;
+
+	release_region(vaddr, plen);
+
+	for (; plen != 0;) {
+		plen -= PAGE_SIZE;
+		unmapioaddr(vaddr + plen);
+	}
+}
+
+/* Does DVMA allocations with PAGE_SIZE granularity.  How this basically
+ * works is that the ESP chip can do DVMA transfers at ANY address with
+ * certain size and boundary restrictions.  But other devices that are
+ * attached to it and would like to do DVMA have to set things up in
+ * a special way, if the DVMA sees a device attached to it transfer data
+ * at addresses above DVMA_VADDR it will grab them, this way it does not
+ * now have to know the peculiarities of where to read the Lance data
+ * from. (for example)
+ */
+void *sparc_dvma_malloc (int len, char *name)
+{
+	unsigned long vaddr, base_address;
+
+	vaddr = dvma_next_free;
+	if(check_region (vaddr, len)) {
+		prom_printf("alloc_dma: 0x%lx is already in use\n", vaddr);
+		prom_halt();
+	}
+	if(vaddr + len > (DVMA_VADDR + DVMA_LEN)) {
+		prom_printf("alloc_dvma: out of dvma memory\n");
+		prom_halt();
+	}
+
+	/* Basically these can be mapped just like any old
+	 * IO pages, cacheable bit off, etc.  The physical
+	 * pages are now mapped dynamically to save space.
+	 */
+	base_address = vaddr;
+	mmu_map_dma_area(base_address, len);
+	/* Assign the memory area. */
+	dvma_next_free = PAGE_ALIGN(dvma_next_free+len);
+
+	request_region(base_address, len, name);
+
+	return (void *) base_address;
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/itlb_miss.S linux/arch/sparc64/kernel/itlb_miss.S
--- v2.1.18/linux/arch/sparc64/kernel/itlb_miss.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/itlb_miss.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,72 @@
+/* $Id: itlb_miss.S,v 1.4 1996/12/28 18:39:42 davem Exp $
+ * itlb_miss.S:	Instruction TLB miss code, this is included directly
+ *              into the trap table.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+	/* We are in the MMU globals, %g7 contains the physical
+	 * address of current->mm->pgd at all times.  %g2 is
+	 * also preloaded with the mask 0x1ff8 to make things
+	 * even quicker.
+	 *
+	 * Many subtle things are done here.  The high bits of
+	 * the virtual address missed are most easily obtained
+	 * from the tag target (it is at address zero in ASI_IMMU
+	 * so no address formation is necessary to get at this).
+	 * This is used to compute the pgd and pmd table offsets.
+	 *
+	 * Even more clever is that physical page zero is always
+	 * a page full of zeroes.  This means we can just follow
+	 * through with all the page table traversals even if nothing
+	 * is mapped because we'll just do loads from page zero
+	 * and get yet another zero.  We only need to do the check
+	 * for the valid bit being set in the final pte we obtain.
+	 *
+	 * Furthermore, we set the TSB base register to the address
+	 * zero, and we use the 8KB tsb ptr to calculate the pte
+	 * offset.  Again it is at address zero in ASI_IMMU_TSB_8KB_PTR
+	 * so no address formation is necessary, saves more instructions.
+	 *
+	 * We use physical address accesses to get at the page
+	 * tables, and this is for two reasons.  This makes it
+	 * impossible to take a fault while we are servicing the
+	 * miss.  Also this physical bypass access only allocates
+	 * in the E-cache, and thus we prevent D-cache pollution
+	 * from the miss handlers probing the page tables.
+	 *
+	 * It looks very hairy and slow.  But I take only 1 more
+	 * overhead of loads from ram than the Solaris version, and
+	 * my version is one instruction quicker for a true TLB miss.
+	 * And more importantly, all true TLB misses under Linux will be
+	 * serviced in _constant_ time.  When using the TSB in the
+	 * manner it was intended to be used (like solaris does) the
+	 * overhead for a TLB miss is _indeterminate_ especially during
+	 * processes startup when the TSB is cold.
+	 */
+
+itlb_miss:
+	/* I-cache line 0 */
+	ldxa		[%g0] ASI_IMMU, %g1		! grab Tag Target
+	srlx		%g1, 8, %g3			! put high vaddr bits in place
+	and		%g3, %g2, %g3			! get offset
+	ldxa		[%g7 + %g3] ASI_PHYS_USE_EC, %g5! load pgd
+	sllx		%g1, 2, %g4			! begin pmd_offset formation
+	and		%g4, %g2, %g3			! and now mask it
+	ldxa		[%g5 + %g3] ASI_PHYS_USE_EC, %g4! load pmd
+	ldxa		[%g0] ASI_IMMU_TSB_8KB_PTR, %g1	! get 8KB pointer bits
+	/* I-cache line 1 */
+	srlx		%g1, 1, %g1			! shift right to get pte_offset
+	ldxa		[%g4 + %g1] ASI_PHYS_USE_EC, %g2! load pte
+	brlz,a,pt	%g2, 1f				! is valid bit clear?
+	 stxa		%g2, [%g0] ASI_ITLB_DATA_IN	! nope, load TTE into ITLB
+
+	ba,a,pt		%xcc, sparc64_itlb_refbit_catch	! longer processing needed
+1:
+	retry						! return from trap
+
+	nop; nop;
+	/* I-cache line 2 */
+	nop; nop; nop; nop; nop; nop; nop; nop;
+	/* I-cache line 3 */
+	nop; nop; nop; nop; nop; nop; nop; nop;
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
--- v2.1.18/linux/arch/sparc64/kernel/process.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/process.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,582 @@
+/*  $Id: process.c,v 1.1 1996/12/28 18:39:39 davem Exp $
+ *  arch/sparc64/kernel/process.c
+ *
+ *  Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
+ *  Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be)
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#define __KERNEL_SYSCALLS__
+#include <stdarg.h>
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/config.h>
+
+#include <asm/oplib.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/delay.h>
+#include <asm/processor.h>
+#include <asm/pstate.h>
+#include <asm/elf.h>
+
+extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
+
+#ifndef __SMP__
+
+/*
+ * the idle loop on a Sparc... ;)
+ */
+asmlinkage int sys_idle(void)
+{
+	if (current->pid != 0)
+		return -EPERM;
+
+	/* endless idle loop with no priority at all */
+	current->counter = -100;
+	for (;;)
+		schedule();
+	return 0;
+}
+
+#else
+
+/*
+ * the idle loop on a SparcMultiPenguin...
+ */
+asmlinkage int sys_idle(void)
+{
+	if (current->pid != 0)
+		return -EPERM;
+
+	/* endless idle loop with no priority at all */
+	current->counter = -100;
+	schedule();
+	return 0;
+}
+
+/* This is being executed in task 0 'user space'. */
+int cpu_idle(void *unused)
+{
+	volatile int *spap = &smp_process_available;
+	volatile int cval;
+
+	while(1) {
+		if(0==*spap)
+			continue;
+		cli();
+		/* Acquire exclusive access. */
+		while((cval = smp_swap(spap, -1)) == -1)
+			while(*spap == -1)
+				;
+                if (0==cval) {
+			/* ho hum, release it. */
+			*spap = 0;
+			sti();
+                        continue;
+                }
+		/* Something interesting happened, whee... */
+		*spap = (cval - 1);
+		sti();
+		idle();
+	}
+}
+
+#endif
+
+extern char reboot_command [];
+
+#ifdef CONFIG_SUN_CONSOLE
+extern void console_restore_palette (void);
+extern int serial_console;
+#endif
+
+void halt_now(void)
+{
+	sti();
+	udelay(8000);
+	cli();
+#ifdef CONFIG_SUN_CONSOLE
+	if (!serial_console)
+		console_restore_palette ();
+#endif
+	prom_halt();
+	panic("Halt failed!");
+}
+
+void hard_reset_now(void)
+{
+	char *p;
+	
+	sti();
+	udelay(8000);
+	cli();
+
+	p = strchr (reboot_command, '\n');
+	if (p) *p = 0;
+#ifdef CONFIG_SUN_CONSOLE
+	if (!serial_console)
+		console_restore_palette ();
+#endif
+	if (*reboot_command)
+		prom_reboot (reboot_command);
+	prom_feval ("reset");
+	panic("Reboot failed!");
+}
+
+void show_regwindow(struct reg_window *rw)
+{
+	printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n"
+	       "l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n",
+	       rw->locals[0], rw->locals[1], rw->locals[2], rw->locals[3],
+	       rw->locals[4], rw->locals[5], rw->locals[6], rw->locals[7]);
+	printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n"
+	       "i4: %016lx i5: %016lx i6: %016lx i7: %016lx\n",
+	       rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3],
+	       rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]);
+}
+
+void show_regwindow32(struct reg_window32 *rw)
+{
+	printk("l0: %08lx l1: %08lx l2: %08lx l3: %08lx\n"
+	       "l4: %08lx l5: %08lx l6: %08lx l7: %08lx\n",
+	       rw->locals[0], rw->locals[1], rw->locals[2], rw->locals[3],
+	       rw->locals[4], rw->locals[5], rw->locals[6], rw->locals[7]);
+	printk("i0: %08lx i1: %08lx i2: %08lx i3: %08lx\n"
+	       "i4: %08lx i5: %08lx i6: %08lx i7: %08lx\n",
+	       rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3],
+	       rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]);
+}
+
+void show_stackframe(struct sparc_stackf *sf)
+{
+	unsigned long size;
+	unsigned long *stk;
+	int i;
+
+	printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n"
+	       "l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n",
+	       sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3],
+	       sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
+	printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n"
+	       "i4: %016lx i5: %016lx fp: %016lx ret_pc: %016lx\n",
+	       sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3],
+	       sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc);
+	printk("sp: %016lx x0: %016lx x1: %016lx x2: %016lx\n"
+	       "x3: %016lx x4: %016lx x5: %016lx xx: %016lx\n",
+	       (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1],
+	       sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
+	       sf->xxargs[0]);
+	size = ((unsigned long)sf->fp) - ((unsigned long)sf);
+	size -= STACKFRAME_SZ;
+	stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ);
+	i = 0;
+	do {
+		printk("s%d: %016lx\n", i++, *stk++);
+	} while ((size -= sizeof(unsigned long)));
+}
+
+void show_stackframe32(struct sparc_stackf32 *sf)
+{
+	unsigned long size;
+	unsigned long *stk;
+	int i;
+
+	printk("l0: %08lx l1: %08lx l2: %08lx l3: %08lx\n"
+	       "l4: %08lx l5: %08lx l6: %08lx l7: %08lx\n",
+	       sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3],
+	       sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
+	printk("i0: %08lx i1: %08lx i2: %08lx i3: %08lx\n"
+	       "i4: %08lx i5: %08lx fp: %08lx ret_pc: %08lx\n",
+	       sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3],
+	       sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc);
+	printk("sp: %08lx x0: %08lx x1: %08lx x2: %08lx\n"
+	       "x3: %08lx x4: %08lx x5: %08lx xx: %08lx\n",
+	       (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1],
+	       sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
+	       sf->xxargs[0]);
+	size = ((unsigned long)sf->fp) - ((unsigned long)sf);
+	size -= STACKFRAME_SZ;
+	stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ);
+	i = 0;
+	do {
+		printk("s%d: %08lx\n", i++, *stk++);
+	} while ((size -= sizeof(unsigned long)));
+}
+
+void show_regs(struct pt_regs * regs)
+{
+#if __MPP__
+	printk("CID: %d\n",mpp_cid());
+#endif
+        printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %016lx\n", regs->tstate,
+	       regs->tpc, regs->tnpc, regs->y);
+	printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n",
+	       regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
+	       regs->u_regs[3]);
+	printk("g4: %016lx g5: %016lx g6: %016lx g7: %016lx\n",
+	       regs->u_regs[4], regs->u_regs[5], regs->u_regs[6],
+	       regs->u_regs[7]);
+	printk("o0: %016lx o1: %016lx o2: %016lx o3: %016lx\n",
+	       regs->u_regs[8], regs->u_regs[9], regs->u_regs[10],
+	       regs->u_regs[11]);
+	printk("o4: %016lx o5: %016lx sp: %016lx ret_pc: %016lx\n",
+	       regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
+	       regs->u_regs[15]);
+	show_regwindow((struct reg_window *)regs->u_regs[14]);
+}
+
+void show_regs32(struct pt_regs32 *regs)
+{
+#if __MPP__
+	printk("CID: %d\n",mpp_cid());
+#endif
+        printk("PSR: %08lx PC: %08lx NPC: %08lx Y: %08lx\n", regs->psr,
+	       regs->pc, regs->npc, regs->y);
+	printk("g0: %08lx g1: %08lx g2: %08lx g3: %08lx\n",
+	       regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
+	       regs->u_regs[3]);
+	printk("g4: %08lx g5: %08lx g6: %08lx g7: %08lx\n",
+	       regs->u_regs[4], regs->u_regs[5], regs->u_regs[6],
+	       regs->u_regs[7]);
+	printk("o0: %08lx o1: %08lx o2: %08lx o3: %08lx\n",
+	       regs->u_regs[8], regs->u_regs[9], regs->u_regs[10],
+	       regs->u_regs[11]);
+	printk("o4: %08lx o5: %08lx sp: %08lx ret_pc: %08lx\n",
+	       regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
+	       regs->u_regs[15]);
+	show_regwindow32((struct reg_window32 *)regs->u_regs[14]);
+}
+
+void show_thread(struct thread_struct *tss)
+{
+	int i;
+
+	printk("kregs:             0x%016lx\n", (unsigned long)tss->kregs);
+	show_regs(tss->kregs);
+	printk("sig_address:       0x%016lx\n", tss->sig_address);
+	printk("sig_desc:          0x%016lx\n", tss->sig_desc);
+	printk("ksp:               0x%016lx\n", tss->ksp);
+	printk("kpc:               0x%016lx\n", tss->kpc);
+
+	for (i = 0; i < NSWINS; i++) {
+		if (!tss->rwbuf_stkptrs[i])
+			continue;
+		printk("reg_window[%d]:\n", i);
+		printk("stack ptr:         0x%016lx\n", tss->rwbuf_stkptrs[i]);
+		show_regwindow(&tss->reg_window[i]);
+	}
+	printk("w_saved:           0x%08lx\n", tss->w_saved);
+
+	/* XXX missing: float_regs */
+	printk("fsr:               0x%016lx\n", tss->fsr);
+	printk("fpqdepth:          0x%016lx\n", tss->fpqdepth);
+	/* XXX missing: fpqueue */
+
+	printk("sstk_info.stack:   0x%016lx\n",
+	        (unsigned long)tss->sstk_info.the_stack);
+	printk("sstk_info.status:  0x%016lx\n",
+	        (unsigned long)tss->sstk_info.cur_status);
+	printk("flags:             0x%016lx\n", tss->flags);
+	printk("current_ds:        0x%016lx\n", tss->current_ds);
+
+	/* XXX missing: core_exec */
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+	kill_user_windows();
+#ifndef __SMP__
+	if(last_task_used_math == current) {
+#else
+	if(current->flags & PF_USEDFPU) {
+#endif
+		/* Keep process from leaving FPU in a bogon state. */
+		put_psr(get_psr() | PSR_EF);
+		fpsave(&current->tss.float_regs[0], &current->tss.fsr,
+		       &current->tss.fpqueue[0], &current->tss.fpqdepth);
+#ifndef __SMP__
+		last_task_used_math = NULL;
+#else
+		current->flags &= ~PF_USEDFPU;
+#endif
+	}
+	mmu_exit_hook();
+}
+
+void flush_thread(void)
+{
+	kill_user_windows();
+	current->tss.w_saved = 0;
+	current->tss.uwinmask = 0;
+	current->tss.sstk_info.cur_status = 0;
+	current->tss.sstk_info.the_stack = 0;
+
+	/* No new signal delivery by default */
+	current->tss.new_signal = 0;
+#ifndef __SMP__
+	if(last_task_used_math == current) {
+#else
+	if(current->flags & PF_USEDFPU) {
+#endif
+		/* Clean the fpu. */
+		put_psr(get_psr() | PSR_EF);
+		fpsave(&current->tss.float_regs[0], &current->tss.fsr,
+		       &current->tss.fpqueue[0], &current->tss.fpqdepth);
+#ifndef __SMP__
+		last_task_used_math = NULL;
+#else
+		current->flags &= ~PF_USEDFPU;
+#endif
+	}
+
+	mmu_flush_hook();
+	/* Now, this task is no longer a kernel thread. */
+	current->tss.flags &= ~SPARC_FLAG_KTHREAD;
+	current->tss.current_ds = USER_DS;
+}
+
+static __inline__ void copy_regs(struct pt_regs *dst, struct pt_regs *src)
+{
+	__asm__ __volatile__("ldd\t[%1 + 0x00], %%g2\n\t"
+			     "ldd\t[%1 + 0x08], %%g4\n\t"
+			     "ldd\t[%1 + 0x10], %%o4\n\t"
+			     "std\t%%g2, [%0 + 0x00]\n\t"
+			     "std\t%%g4, [%0 + 0x08]\n\t"
+			     "std\t%%o4, [%0 + 0x10]\n\t"
+			     "ldd\t[%1 + 0x18], %%g2\n\t"
+			     "ldd\t[%1 + 0x20], %%g4\n\t"
+			     "ldd\t[%1 + 0x28], %%o4\n\t"
+			     "std\t%%g2, [%0 + 0x18]\n\t"
+			     "std\t%%g4, [%0 + 0x20]\n\t"
+			     "std\t%%o4, [%0 + 0x28]\n\t"
+			     "ldd\t[%1 + 0x30], %%g2\n\t"
+			     "ldd\t[%1 + 0x38], %%g4\n\t"
+			     "ldd\t[%1 + 0x40], %%o4\n\t"
+			     "std\t%%g2, [%0 + 0x30]\n\t"
+			     "std\t%%g4, [%0 + 0x38]\n\t"
+			     "ldd\t[%1 + 0x48], %%g2\n\t"
+			     "std\t%%o4, [%0 + 0x40]\n\t"
+			     "std\t%%g2, [%0 + 0x48]\n\t" : :
+			     "r" (dst), "r" (src) :
+			     "g2", "g3", "g4", "g5", "o4", "o5");
+}
+
+static __inline__ void copy_regwin(struct reg_window *dst, struct reg_window *src)
+{
+	__asm__ __volatile__("ldd\t[%1 + 0x00], %%g2\n\t"
+			     "ldd\t[%1 + 0x08], %%g4\n\t"
+			     "ldd\t[%1 + 0x10], %%o4\n\t"
+			     "std\t%%g2, [%0 + 0x00]\n\t"
+			     "std\t%%g4, [%0 + 0x08]\n\t"
+			     "std\t%%o4, [%0 + 0x10]\n\t"
+			     "ldd\t[%1 + 0x18], %%g2\n\t"
+			     "ldd\t[%1 + 0x20], %%g4\n\t"
+			     "ldd\t[%1 + 0x28], %%o4\n\t"
+			     "std\t%%g2, [%0 + 0x18]\n\t"
+			     "std\t%%g4, [%0 + 0x20]\n\t"
+			     "std\t%%o4, [%0 + 0x28]\n\t"
+			     "ldd\t[%1 + 0x30], %%g2\n\t"
+			     "ldd\t[%1 + 0x38], %%g4\n\t"
+			     "std\t%%g2, [%0 + 0x30]\n\t"
+			     "std\t%%g4, [%0 + 0x38]\n\t" : :
+			     "r" (dst), "r" (src) :
+			     "g2", "g3", "g4", "g5", "o4", "o5");
+}
+
+static __inline__ struct sparc_stackf *
+clone_stackframe(struct sparc_stackf *dst, struct sparc_stackf *src)
+{
+	unsigned long size;
+	struct sparc_stackf *sp;
+
+	size = ((unsigned long)src->fp) - ((unsigned long)src);
+	sp = (struct sparc_stackf *)(((unsigned long)dst) - size); 
+
+	if (copy_to_user(sp, src, size))
+		return 0;
+	if (put_user(dst, &sp->fp))
+		return 0;
+	return sp;
+}
+
+
+/* Copy a Sparc thread.  The fork() return value conventions
+ * under SunOS are nothing short of bletcherous:
+ * Parent -->  %o0 == childs  pid, %o1 == 0
+ * Child  -->  %o0 == parents pid, %o1 == 1
+ *
+ * NOTE: We have a separate fork kpsr/kwim because
+ *       the parent could change these values between
+ *       sys_fork invocation and when we reach here
+ *       if the parent should sleep while trying to
+ *       allocate the task_struct and kernel stack in
+ *       do_fork().
+ */
+extern void ret_from_syscall(void);
+
+int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+		struct task_struct *p, struct pt_regs *regs)
+{
+	struct pt_regs *childregs;
+	struct reg_window *new_stack;
+	unsigned long stack_offset;
+
+#ifndef __SMP__
+	if(last_task_used_math == current) {
+#else
+	if(current->flags & PF_USEDFPU) {
+#endif
+		put_psr(get_psr() | PSR_EF);
+		fpsave(&p->tss.float_regs[0], &p->tss.fsr,
+		       &p->tss.fpqueue[0], &p->tss.fpqdepth);
+#ifdef __SMP__
+		current->flags &= ~PF_USEDFPU;
+#endif
+	}
+
+	/* Calculate offset to stack_frame & pt_regs */
+	stack_offset = ((PAGE_SIZE<<1) - TRACEREG_SZ);
+
+	if(regs->psr & PSR_PS)
+		stack_offset -= REGWIN_SZ;
+	childregs = ((struct pt_regs *) (p->kernel_stack_page + stack_offset));
+	copy_regs(childregs, regs);
+	new_stack = (((struct reg_window *) childregs) - 1);
+	copy_regwin(new_stack, (((struct reg_window *) regs) - 1));
+
+	p->tss.ksp = p->saved_kernel_stack = (unsigned long) new_stack;
+	p->tss.kpc = (((unsigned long) ret_from_syscall) - 0x8);
+	p->tss.kpsr = current->tss.fork_kpsr;
+	p->tss.kwim = current->tss.fork_kwim;
+	p->tss.kregs = childregs;
+
+	if(regs->psr & PSR_PS) {
+		childregs->u_regs[UREG_FP] = p->tss.ksp;
+		p->tss.flags |= SPARC_FLAG_KTHREAD;
+		p->tss.current_ds = KERNEL_DS;
+		childregs->u_regs[UREG_G6] = (unsigned long) p;
+	} else {
+		childregs->u_regs[UREG_FP] = sp;
+		p->tss.flags &= ~SPARC_FLAG_KTHREAD;
+		p->tss.current_ds = USER_DS;
+
+		if (sp != current->tss.kregs->u_regs[UREG_FP]) {
+			struct sparc_stackf *childstack;
+			struct sparc_stackf *parentstack;
+
+			/*
+			 * This is a clone() call with supplied user stack.
+			 * Set some valid stack frames to give to the child.
+			 */
+			childstack = (struct sparc_stackf *)sp;
+			parentstack = (struct sparc_stackf *)
+					current->tss.kregs->u_regs[UREG_FP];
+
+#if 0
+			printk("clone: parent stack:\n");
+			show_stackframe(parentstack);
+#endif
+
+			childstack = clone_stackframe(childstack, parentstack);
+			if (!childstack)
+				return -EFAULT;
+
+#if 0
+			printk("clone: child stack:\n");
+			show_stackframe(childstack);
+#endif
+
+			childregs->u_regs[UREG_FP] = (unsigned long)childstack;
+		}
+	}
+
+	/* Set the return value for the child. */
+	childregs->u_regs[UREG_I0] = current->pid;
+	childregs->u_regs[UREG_I1] = 1;
+
+	/* Set the return value for the parent. */
+	regs->u_regs[UREG_I1] = 0;
+
+	return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+	unsigned long first_stack_page;
+
+	dump->magic = SUNOS_CORE_MAGIC;
+	dump->len = sizeof(struct user);
+	dump->regs.psr = regs->psr;
+	dump->regs.pc = regs->pc;
+	dump->regs.npc = regs->npc;
+	dump->regs.y = regs->y;
+	/* fuck me plenty */
+	memcpy(&dump->regs.regs[0], &regs->u_regs[1], (sizeof(unsigned long) * 15));
+	dump->uexec = current->tss.core_exec;
+	dump->u_tsize = (((unsigned long) current->mm->end_code) -
+		((unsigned long) current->mm->start_code)) & ~(PAGE_SIZE - 1);
+	dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1)));
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_dsize &= ~(PAGE_SIZE - 1);
+	first_stack_page = (regs->u_regs[UREG_FP] & ~(PAGE_SIZE - 1));
+	dump->u_ssize = (TASK_SIZE - first_stack_page) & ~(PAGE_SIZE - 1);
+	memcpy(&dump->fpu.fpstatus.fregs.regs[0], &current->tss.float_regs[0], (sizeof(unsigned long) * 32));
+	dump->fpu.fpstatus.fsr = current->tss.fsr;
+	dump->fpu.fpstatus.flags = dump->fpu.fpstatus.extra = 0;
+	dump->fpu.fpstatus.fpq_count = current->tss.fpqdepth;
+	memcpy(&dump->fpu.fpstatus.fpq[0], &current->tss.fpqueue[0],
+	       ((sizeof(unsigned long) * 2) * 16));
+	dump->sigcode = current->tss.sig_desc;
+}
+
+/*
+ * fill in the fpu structure for a core dump.
+ */
+int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
+{
+	/* Currently we report that we couldn't dump the fpu structure */
+	return 0;
+}
+
+/*
+ * sparc_execve() executes a new program after the asm stub has set
+ * things up for us.  This should basically do what I want it to.
+ */
+asmlinkage int sparc_execve(struct pt_regs *regs)
+{
+	int error, base = 0;
+	char *filename;
+
+	/* Check for indirect call. */
+	if(regs->u_regs[UREG_G1] == 0)
+		base = 1;
+
+	error = getname((char *) regs->u_regs[base + UREG_I0], &filename);
+	if(error)
+		return error;
+	error = do_execve(filename, (char **) regs->u_regs[base + UREG_I1],
+			  (char **) regs->u_regs[base + UREG_I2], regs);
+	putname(filename);
+	return error;
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/signal32.c linux/arch/sparc64/kernel/signal32.c
--- v2.1.18/linux/arch/sparc64/kernel/signal32.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/signal32.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,714 @@
+/*  $Id: signal32.c,v 1.1 1996/12/26 10:16:41 davem Exp $
+ *  arch/sparc64/kernel/signal32.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *  Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/mm.h>
+
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/ptrace.h>
+#include <asm/svr4.h>
+#include <asm/pgtable.h>
+
+#define _S(nr) (1<<((nr)-1))
+
+#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+
+asmlinkage int sys_waitpid(pid_t pid, unsigned long *stat_addr, int options);
+
+extern void fpsave32(unsigned long *fpregs, unsigned long *fsr,
+		     void *fpqueue, unsigned long *fpqdepth);
+extern void fpload32(unsigned long *fpregs, unsigned long *fsr);
+
+asmlinkage int do_signal32(unsigned long oldmask, struct pt_regs * regs,
+			 unsigned long orig_o0, int ret_from_syscall);
+
+/* This turned off for production... */
+/* #define DEBUG_SIGNALS 1 */
+
+/* Signal frames: the original one (compatible with SunOS):
+ *
+ * Set up a signal frame... Make the stack look the way SunOS
+ * expects it to look which is basically:
+ *
+ * ---------------------------------- <-- %sp at signal time
+ * Struct sigcontext
+ * Signal address
+ * Ptr to sigcontext area above
+ * Signal code
+ * The signal number itself
+ * One register window
+ * ---------------------------------- <-- New %sp
+ */
+struct signal_sframe32 {
+	struct reg_window_32 sig_window;
+	int sig_num;
+	int sig_code;
+	struct sigcontext_32 *sig_scptr;
+	int sig_address;
+	struct sigcontext_32 sig_context;
+};
+
+/* 
+ * And the new one, intended to be used for Linux applications only
+ * (we have enough in there to work with clone).
+ * All the interesting bits are in the info field.
+ */
+
+struct new_signal_frame32 {
+	struct      sparc_stackf_32 ss;
+	__siginfo32_t info;
+	unsigned    int __pad;
+	unsigned    int insns [2];
+};
+
+/* Align macros */
+#define SF_ALIGNEDSZ  (((sizeof(struct signal_sframe32) + 7) & (~7)))
+#define NF_ALIGNEDSZ  (((sizeof(struct new_signal_frame32) + 7) & (~7)))
+
+/*
+ * atomically swap in the new signal mask, and wait for a signal.
+ * This is really tricky on the Sparc, watch out...
+ */
+asmlinkage inline void _sigpause32_common(unsigned int set, struct pt_regs *regs)
+{
+	unsigned int mask;
+
+	mask = current->blocked;
+	current->blocked = set & _BLOCKABLE;
+	regs->tpc = regs->tnpc;
+	regs->tnpc += 4;
+
+	/* Condition codes and return value where set here for sigpause,
+	 * and so got used by setup_frame, which again causes sigreturn()
+	 * to return -EINTR.
+	 */
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		/*
+		 * Return -EINTR and set condition code here,
+		 * so the interrupted system call actually returns
+		 * these.
+		 */
+		regs->tstate |= TSTATE_ICARRY;
+		regs->u_regs[UREG_I0] = EINTR;
+		if (do_signal32(mask, regs, 0, 0))
+			return;
+	}
+}
+
+asmlinkage void do_sigpause32(unsigned int set, struct pt_regs *regs)
+{
+	_sigpause32_common(set, regs);
+}
+
+asmlinkage void do_sigsuspend32(struct pt_regs *regs)
+{
+	_sigpause32_common(regs->u_regs[UREG_I0], regs);
+}
+
+void do_new_sigreturn32(struct pt_regs *regs)
+{
+	struct new_signal_frame32 *sf;
+	unsigned long up_tstate;
+	
+	sf = (struct new_signal_frame32 *) regs->u_regs [UREG_FP];
+	/* 1. Make sure we are not getting garbage from the user */
+	if (verify_area (VERIFY_READ, sf, sizeof (*sf))){
+		do_exit (SIGSEGV);
+		return;
+	}
+	if (((uint) sf) & 3){
+		do_exit (SIGSEGV);
+		return;
+	}
+	if ((sf->info.si_regs.pc | sf->info.si_regs.npc) & 3){
+		do_exit (SIGSEGV);
+		return;
+	}
+	
+	/* 2. Restore the state */
+	copy_32bit_to_kernel_ptregs (regs, &sf->info.si_regs, sizeof (struct pt_regs));
+
+	/* User can only change condition codes and FPU enabling in the %tstate. */
+	regs->tstate &= ~(TSTATE_ICC | TSTATE_PEF);
+	regs->tstate |= psr_to_tstate_icc(sf->info.si_regs.psr);
+	regs->tstate |= (sf->info.si_regs.psr & PSR_EF);
+
+	if (regs->tstate & TSTATE_PEF) {
+		regs->psr &= ~(TSTATE_PEF);
+#ifndef __SMP__
+		if(current == last_task_used_math)
+			last_task_used_math = 0;
+#endif
+		current->used_math = 1;
+		current->flags &= ~(PF_USEDFPU);
+
+		/* Copy signal FPU state into thread struct FPU state. */
+		copy_32bit_to_kernel_fpuregs(&current->tss.float_regs[0],
+					     &sf->info.si_float_regs[0],
+					     (sizeof(unsigned int) * 64));
+		current->tss.fsr = sf->info.si_fsr;
+		if((current->tss.fpqdepth = sf->info.si_fpqdepth) != 0)
+		    memcpy(&current->tss.fpqueue[0], &sf->info.si_fpqueue[0],
+		           ((sizeof(unsigned int) + (sizeof(unsigned int *))) * 16));
+	}
+	current->blocked = sf->info.si_mask & _BLOCKABLE;
+}
+
+asmlinkage void do_sigreturn32(struct pt_regs *regs)
+{
+	struct sigcontext *scptr;
+	unsigned long pc, npc, psr;
+
+	synchronize_user_stack();
+	if (current->tss.new_signal)
+		return do_new_sigreturn32(regs);
+
+	scptr = (struct sigcontext *) regs->u_regs[UREG_I0];
+	/* Check sanity of the user arg. */
+	if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext)) ||
+	   (((unsigned long) scptr) & 3)) {
+		printk("%s [%d]: do_sigreturn, scptr is invalid at "
+		       "pc<%08lx> scptr<%p>\n",
+		       current->comm, current->pid, regs->pc, scptr);
+		do_exit(SIGSEGV);
+	}
+	__get_user(pc, &scptr->sigc_pc);
+	__get_user(npc, &scptr->sigc_npc);
+	if((pc | npc) & 3)
+		do_exit(SIGSEGV); /* Nice try. */
+
+	__get_user(current->blocked, &scptr->sigc_mask);
+	current->blocked &= _BLOCKABLE;
+	__get_user(current->tss.sstk_info.cur_status, &scptr->sigc_onstack);
+	current->tss.sstk_info.cur_status &= 1;
+	regs->pc = pc;
+	regs->npc = npc;
+	__get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp);
+	__get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0);
+	__get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1);
+
+	/* User can only change condition codes in %psr. */
+	__get_user(psr, &scptr->sigc_psr);
+	regs->psr &= ~(PSR_ICC);
+	regs->psr |= (psr & PSR_ICC);
+}
+
+/* Checks if the fp is valid */
+static int invalid_frame_pointer(void *fp, int fplen)
+{
+	if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
+		return 1;
+	return 0;
+}
+
+static inline void
+setup_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
+	      struct pt_regs *regs, int signr, unsigned long oldmask)
+{
+	struct signal_sframe32 *sframep;
+	struct sigcontext *sc;
+	int window = 0;
+	int old_status = current->tss.sstk_info.cur_status;
+
+	synchronize_user_stack();
+	sframep = (struct signal_sframe32 *) regs->u_regs[UREG_FP];
+	sframep = (struct signal_sframe32 *) (((unsigned long) sframep)-SF_ALIGNEDSZ);
+	if (invalid_frame_pointer (sframep, sizeof(*sframep))){
+#ifdef DEBUG_SIGNALS /* fills up the console logs during crashme runs, yuck... */
+		printk("%s [%d]: User has trashed signal stack\n",
+		       current->comm, current->pid);
+		printk("Sigstack ptr %p handler at pc<%08lx> for sig<%d>\n",
+		       sframep, pc, signr);
+#endif
+		/* Don't change signal code and address, so that
+		 * post mortem debuggers can have a look.
+		 */
+		do_exit(SIGILL);
+		return;
+	}
+
+	sc = &sframep->sig_context;
+
+	/* We've already made sure frame pointer isn't in kernel space... */
+	__put_user(old_status, &sc->sigc_onstack);
+	__put_user(oldmask, &sc->sigc_mask);
+	__put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
+	__put_user(pc, &sc->sigc_pc);
+	__put_user(npc, &sc->sigc_npc);
+	__put_user(regs->psr, &sc->sigc_psr);
+	__put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
+	__put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
+	__put_user(current->tss.w_saved, &sc->sigc_oswins);
+	if(current->tss.w_saved)
+		for(window = 0; window < current->tss.w_saved; window++) {
+			sc->sigc_spbuf[window] =
+				(char *)current->tss.rwbuf_stkptrs[window];
+			copy_to_user(&sc->sigc_wbuf[window],
+			       &current->tss.reg_window[window],
+			       sizeof(struct reg_window));
+		}
+	else
+		copy_to_user(sframep, (char *)regs->u_regs[UREG_FP],
+		       sizeof(struct reg_window));
+
+	current->tss.w_saved = 0; /* So process is allowed to execute. */
+	__put_user(signr, &sframep->sig_num);
+	if(signr == SIGSEGV ||
+	   signr == SIGILL ||
+	   signr == SIGFPE ||
+	   signr == SIGBUS ||
+	   signr == SIGEMT) {
+		__put_user(current->tss.sig_desc, &sframep->sig_code);
+		__put_user(current->tss.sig_address, &sframep->sig_address);
+	} else {
+		__put_user(0, &sframep->sig_code);
+		__put_user(0, &sframep->sig_address);
+	}
+	__put_user(sc, &sframep->sig_scptr);
+	regs->u_regs[UREG_FP] = (unsigned long) sframep;
+	regs->pc = (unsigned long) sa->sa_handler;
+	regs->npc = (regs->pc + 4);
+}
+
+/* To align the structure properly. */
+
+static inline void
+new_setup_frame32(struct sigaction *sa, struct pt_regs *regs,
+		  int signo, unsigned long oldmask)
+{
+	struct new_signal_frame32 *sf;
+
+	/* 1. Make sure everything is clean */
+	synchronize_user_stack();
+	sf = (struct new_signal_frame *) regs->u_regs[UREG_FP];
+	sf = (struct new_signal_frame *) (((unsigned long) sf)-NF_ALIGNEDSZ);
+	
+	if (invalid_frame_pointer (sf, sizeof(struct new_signal_frame))){
+		do_exit(SIGILL);
+		return;
+	}
+
+	if (current->tss.w_saved != 0){
+		printk ("%s[%d]: Invalid user stack frame for signal delivery.\n",
+			current->comm, current->pid);
+		do_exit (SIGILL);
+		return;
+	}
+
+	/* 2. Save the current process state */
+	memcpy (&sf->info.si_regs, regs, sizeof (struct pt_regs));
+#ifdef __SMP__
+	if(current->flags & PF_USEDFPU) {
+		put_psr(get_psr() | PSR_EF);
+		fpsave (&sf->info.si_float_regs [0], &sf->info.si_fsr,
+			&sf->info.si_fpqueue[0], &sf->info.si_fpqdepth);
+
+		/* Save a copy into thread struct as well. */
+		memcpy(&current->tss.float_regs[0], &sf->info.si_float_regs[0],
+		       (sizeof(unsigned long) * 64));
+		current->tss.fsr = sf->info.si_fsr;
+		if((current->tss.fpqdepth = sf->info.si_fpqdepth) != 0)
+		    memcpy(&current->tss.fpqueue[0], &sf->info.si_fpqueue[0],
+			   ((sizeof(unsigned long) + (sizeof(unsigned long *))) * 16));
+
+		regs->psr &= ~(PSR_EF);
+		current->flags &= ~(PF_USEDFPU);
+	}
+#else
+	if(current == last_task_used_math) {
+		put_psr(get_psr() | PSR_EF);
+		fpsave (&sf->info.si_float_regs [0], &sf->info.si_fsr,
+			&sf->info.si_fpqueue[0], &sf->info.si_fpqdepth);
+
+		/* Save a copy into thread struct as well. */
+		memcpy(&current->tss.float_regs[0], &sf->info.si_float_regs[0],
+		       (sizeof(unsigned long) * 64));
+		current->tss.fsr = sf->info.si_fsr;
+		if((current->tss.fpqdepth = sf->info.si_fpqdepth) != 0)
+		    memcpy(&current->tss.fpqueue[0], &sf->info.si_fpqueue[0],
+			   ((sizeof(unsigned long) + (sizeof(unsigned long *))) * 16));
+
+		last_task_used_math = NULL;
+		regs->psr &= ~(PSR_EF);
+	}
+#endif
+
+	/* This new thread of control has not used the FPU. */
+	current->used_math = 0;
+
+	sf->info.si_mask = oldmask;
+	memcpy (sf, (char *) regs->u_regs [UREG_FP], sizeof (struct reg_window));
+	
+	/* 3. return to kernel instructions */
+	sf->insns [0] = 0x821020d8; /* mov __NR_sigreturn,%g1 */
+	sf->insns [1] = 0x91d02010; /* t 0x10 */
+
+	/* 4. signal handler back-trampoline and parameters */
+	regs->u_regs[UREG_FP] = (unsigned long) sf;
+	regs->u_regs[UREG_I0] = signo;
+	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+	regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
+
+	/* 5. signal handler */
+	regs->pc = (unsigned long) sa->sa_handler;
+	regs->npc = (regs->pc + 4);
+
+	/* Flush instruction space. */
+	flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
+}
+
+/* Setup a Solaris stack frame */
+static inline void
+setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
+		   struct pt_regs *regs, int signr, unsigned long oldmask)
+{
+	svr4_signal_frame_t *sfp;
+	svr4_gregset_t  *gr;
+	svr4_siginfo_t  *si;
+	svr4_mcontext_t *mc;
+	svr4_gwindows_t *gw;
+	svr4_ucontext_t *uc;
+	int window = 0;
+
+	synchronize_user_stack();
+	sfp = (svr4_signal_frame_t *) regs->u_regs[UREG_FP] - REGWIN_SZ;
+	sfp = (svr4_signal_frame_t *) (((unsigned long) sfp)-SVR4_SF_ALIGNED);
+
+	if (invalid_frame_pointer (sfp, sizeof (*sfp))){
+#ifdef DEBUG_SIGNALS
+		printk ("Invalid stack frame\n");
+#endif
+		do_exit(SIGILL);
+		return;
+	}
+
+	/* Start with a clean frame pointer and fill it */
+	clear_user(sfp, sizeof (*sfp));
+
+	/* Setup convenience variables */
+	si = &sfp->si;
+	uc = &sfp->uc;
+	gw = &sfp->gw;
+	mc = &uc->mcontext;
+	gr = &mc->greg;
+	
+	/* FIXME: where am I supposed to put this?
+	 * sc->sigc_onstack = old_status;
+	 * anyways, it does not look like it is used for anything at all.
+	 */
+	__put_user(oldmask, &uc->sigmask.sigbits [0]);
+
+	/* Store registers */
+	__put_user(regs->pc, &((*gr) [SVR4_PC]));
+	__put_user(regs->npc, &((*gr) [SVR4_NPC]));
+	__put_user(regs->psr, &((*gr) [SVR4_PSR]));
+	__put_user(regs->y, &((*gr) [SVR4_Y]));
+	
+	/* Copy g [1..7] and o [0..7] registers */
+	copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs [UREG_G1], sizeof (long) * 7);
+	copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs [UREG_I0], sizeof (long) * 8);
+
+	/* Setup sigaltstack, FIXME */
+	__put_user(0xdeadbeef, &uc->stack.sp);
+	__put_user(0, &uc->stack.size);
+	__put_user(0, &uc->stack.flags);	/* Possible: ONSTACK, DISABLE */
+
+	/* Save the currently window file: */
+
+	/* 1. Link sfp->uc->gwins to our windows */
+	__put_user(gw, &mc->gwin);
+	    
+	/* 2. Number of windows to restore at setcontext (): */
+	__put_user(current->tss.w_saved, &gw->count);
+
+	/* 3. Save each valid window
+	 *    Currently, it makes a copy of the windows from the kernel copy.
+	 *    David's code for SunOS, makes the copy but keeps the pointer to
+	 *    the kernel.  My version makes the pointer point to a userland 
+	 *    copy of those.  Mhm, I wonder if I shouldn't just ignore those
+	 *    on setcontext and use those that are on the kernel, the signal
+	 *    handler should not be modyfing those, mhm.
+	 *
+	 *    These windows are just used in case synchronize_user_stack failed
+	 *    to flush the user windows.
+	 */
+	for(window = 0; window < current->tss.w_saved; window++) {
+		__put_user((int *) &(gw->win [window]), &gw->winptr [window]);
+		copy_to_user(&gw->win [window], &current->tss.reg_window [window], sizeof (svr4_rwindow_t));
+		__put_user(0, gw->winptr [window]);
+	}
+
+	/* 4. We just pay attention to the gw->count field on setcontext */
+	current->tss.w_saved = 0; /* So process is allowed to execute. */
+
+	/* Setup the signal information.  Solaris expects a bunch of
+	 * information to be passed to the signal handler, we don't provide
+	 * that much currently, should use those that David already
+	 * is providing with tss.sig_desc
+	 */
+	__put_user(signr, &si->siginfo.signo);
+	__put_user(SVR4_SINOINFO, &si->siginfo.code);
+
+	regs->u_regs[UREG_FP] = (unsigned long) sfp;
+	regs->pc = (unsigned long) sa->sa_handler;
+	regs->npc = (regs->pc + 4);
+
+#ifdef DEBUG_SIGNALS
+	printk ("Solaris-frame: %x %x\n", (int) regs->pc, (int) regs->npc);
+#endif
+	/* Arguments passed to signal handler */
+	if (regs->u_regs [14]){
+		struct reg_window *rw = (struct reg_window *) regs->u_regs [14];
+
+		__put_user(signr, &rw->ins [0]);
+		__put_user(si, &rw->ins [1]);
+		__put_user(uc, &rw->ins [2]);
+		__put_user(sfp, &rw->ins [6]);	/* frame pointer */
+		regs->u_regs[UREG_I0] = signr;
+		regs->u_regs[UREG_I1] = (uint) si;
+		regs->u_regs[UREG_I2] = (uint) uc;
+	}
+}
+
+asmlinkage int
+svr4_getcontext32(svr4_ucontext_t *uc, struct pt_regs *regs)
+{
+	svr4_gregset_t  *gr;
+	svr4_mcontext_t *mc;
+
+	synchronize_user_stack();
+	if (current->tss.w_saved){
+		printk ("Uh oh, w_saved is not zero (%ld)\n", current->tss.w_saved);
+		do_exit (SIGSEGV);
+	}
+	if(clear_user(uc, sizeof (*uc)))
+		return -EFAULT;
+
+	/* Setup convenience variables */
+	mc = &uc->mcontext;
+	gr = &mc->greg;
+	
+	/* We only have < 32 signals, fill the first slot only */
+	__put_user(current->sig->action->sa_mask, &uc->sigmask.sigbits [0]);
+
+	/* Store registers */
+	__put_user(regs->pc, &uc->mcontext.greg [SVR4_PC]);
+	__put_user(regs->npc, &uc->mcontext.greg [SVR4_NPC]);
+	__put_user(regs->psr, &uc->mcontext.greg [SVR4_PSR]);
+        __put_user(regs->y, &uc->mcontext.greg [SVR4_Y]);
+	
+	/* Copy g [1..7] and o [0..7] registers */
+	copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs [UREG_G1], sizeof (uint) * 7);
+	copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs [UREG_I0], sizeof (uint) * 8);
+
+	/* Setup sigaltstack, FIXME */
+	__put_user(0xdeadbeef, &uc->stack.sp);
+	__put_user(0, &uc->stack.size);
+	__put_user(0, &uc->stack.flags);	/* Possible: ONSTACK, DISABLE */
+
+	/* The register file is not saved
+	 * we have already stuffed all of it with sync_user_stack
+	 */
+	return 0;
+}
+
+
+/* Set the context for a svr4 application, this is Solaris way to sigreturn */
+asmlinkage int svr4_setcontext32(svr4_ucontext_t *c, struct pt_regs *regs)
+{
+	struct thread_struct *tp = &current->tss;
+	svr4_gregset_t  *gr;
+	unsigned long pc, npc, psr;
+	
+	/* Fixme: restore windows, or is this already taken care of in
+	 * svr4_setup_frame when sync_user_windows is done?
+	 */
+	flush_user_windows();
+	
+	if (tp->w_saved){
+		printk ("Uh oh, w_saved is: 0x%lx\n", tp->w_saved);
+		do_exit(SIGSEGV);
+	}
+	if (((uint) c) & 3){
+		printk ("Unaligned structure passed\n");
+		do_exit (SIGSEGV);
+	}
+
+	if(!__access_ok((unsigned long)c, sizeof(*c))) {
+		/* Miguel, add nice debugging msg _here_. ;-) */
+		do_exit(SIGSEGV);
+	}
+
+	/* Check for valid PC and nPC */
+	gr = &c->mcontext.greg;
+	__get_user(pc, &((*gr)[SVR4_PC]));
+	__get_user(npc, &((*gr)[SVR4_NPC]));
+	if((pc | npc) & 3) {
+	        printk ("setcontext, PC or nPC were bogus\n");
+		do_exit (SIGSEGV);
+	}
+	/* Retrieve information from passed ucontext */
+	    /* note that nPC is ored a 1, this is used to inform entry.S */
+	    /* that we don't want it to mess with our PC and nPC */
+	__get_user(current->blocked, &c->sigmask.sigbits [0]);
+	current->blocked &= _BLOCKABLE;
+	regs->pc = pc;
+	regs->npc = npc | 1;
+	__get_user(regs->y, &((*gr) [SVR4_Y]));
+	__get_user(psr, &((*gr) [SVR4_PSR]));
+	regs->psr &= ~(PSR_ICC);
+	regs->psr |= (psr & PSR_ICC);
+
+	/* Restore g[1..7] and o[0..7] registers */
+	copy_from_user(&regs->u_regs [UREG_G1], &(*gr)[SVR4_G1], sizeof (long) * 7);
+	copy_from_user(&regs->u_regs [UREG_I0], &(*gr)[SVR4_O0], sizeof (long) * 8);
+
+	return -EINTR;
+}
+
+static inline void handle_signal32(unsigned long signr, struct sigaction *sa,
+				   unsigned long oldmask, struct pt_regs *regs,
+				   int svr4_signal)
+{
+	if(svr4_signal)
+		setup_svr4_frame32(sa, regs->pc, regs->npc, regs, signr, oldmask);
+	else {
+		if (current->tss.new_signal)
+			new_setup_frame32(sa, regs, signr, oldmask);
+		else
+			setup_frame32(sa, regs->pc, regs->npc, regs, signr, oldmask);
+	}
+	if(sa->sa_flags & SA_ONESHOT)
+		sa->sa_handler = NULL;
+	if(!(sa->sa_flags & SA_NOMASK))
+		current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE;
+}
+
+static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
+				     struct sigaction *sa)
+{
+	switch(regs->u_regs[UREG_I0]) {
+		case ERESTARTNOHAND:
+		no_system_call_restart:
+			regs->u_regs[UREG_I0] = EINTR;
+			regs->psr |= PSR_C;
+			break;
+		case ERESTARTSYS:
+			if(!(sa->sa_flags & SA_RESTART))
+				goto no_system_call_restart;
+		/* fallthrough */
+		case ERESTARTNOINTR:
+			regs->u_regs[UREG_I0] = orig_i0;
+			regs->pc -= 4;
+			regs->npc -= 4;
+	}
+}
+
+/* Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+asmlinkage int do_signal32(unsigned long oldmask, struct pt_regs * regs,
+			   unsigned long orig_i0, int restart_syscall)
+{
+	unsigned long signr, mask = ~current->blocked;
+	struct sigaction *sa;
+	int svr4_signal = current->personality == PER_SVR4;
+	
+	while ((signr = current->signal & mask) != 0) {
+		signr = ffz(~signr);
+		clear_bit(signr, &current->signal);
+		sa = current->sig->action + signr;
+		signr++;
+		if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current);
+			schedule();
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+			if (signr == SIGSTOP)
+				continue;
+			if (_S(signr) & current->blocked) {
+				current->signal |= _S(signr);
+				continue;
+			}
+			sa = current->sig->action + signr - 1;
+		}
+		if(sa->sa_handler == SIG_IGN) {
+			if(signr != SIGCHLD)
+				continue;
+			while(sys_waitpid(-1,NULL,WNOHANG) > 0);
+			continue;
+		}
+		if(sa->sa_handler == SIG_DFL) {
+			if(current->pid == 1)
+				continue;
+			switch(signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+
+			case SIGSTOP:
+				if (current->flags & PF_PTRACED)
+					continue;
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if(!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags &
+				     SA_NOCLDSTOP))
+					notify_parent(current);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
+				if(current->binfmt && current->binfmt->core_dump) {
+					if(current->binfmt->core_dump(signr, regs))
+						signr |= 0x80;
+				}
+#ifdef DEBUG_SIGNALS
+				/* Very useful to debug dynamic linker problems */
+				printk ("Sig ILL going...\n");
+				show_regs (regs);
+#endif
+				/* fall through */
+			default:
+				current->signal |= _S(signr & 0x7f);
+				current->flags |= PF_SIGNALED;
+				do_exit(signr);
+			}
+		}
+		if(restart_syscall)
+			syscall_restart32(orig_i0, regs, sa);
+		handle_signal32(signr, sa, oldmask, regs, svr4_signal);
+		return 1;
+	}
+	if(restart_syscall &&
+	   (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+	    regs->u_regs[UREG_I0] == ERESTARTSYS ||
+	    regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+		/* replay the system call when we are done */
+		regs->u_regs[UREG_I0] = orig_i0;
+		regs->tpc -= 4;
+		regs->tnpc -= 4;
+	}
+	return 0;
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/systbls.S linux/arch/sparc64/kernel/systbls.S
--- v2.1.18/linux/arch/sparc64/kernel/systbls.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/systbls.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,322 @@
+/* $Id: systbls.S,v 1.1 1996/12/28 18:39:36 davem Exp $
+ * systbls.S: System call entry point tables for OS compatibility.
+ *            The native Linux system call table lives here also.
+ *
+ * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * Based upon preliminary work which is:
+ *
+ * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
+ */
+
+	.data
+	.align	8
+
+	/* First, the 32-bit Linux native syscall table. */
+
+	.globl C_LABEL(sys_call_table32)
+C_LABEL(sys_call_table32):
+/*0*/	.xword C_LABEL(sys_setup), C_LABEL(sys_exit), C_LABEL(sys_fork)
+	.xword C_LABEL(sys_read), C_LABEL(sys_write)
+/*5*/	.xword C_LABEL(sys_open), C_LABEL(sys_close), C_LABEL(sys_wait4)
+	.xword C_LABEL(sys_creat), C_LABEL(sys_link)
+/*10*/  .xword C_LABEL(sys_unlink), C_LABEL(sunos_execv), C_LABEL(sys_chdir)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_mknod)
+/*15*/	.xword C_LABEL(sys_chmod), C_LABEL(sys_chown), C_LABEL(sparc_brk)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_lseek)
+/*20*/	.xword C_LABEL(sys_getpid), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_setuid), C_LABEL(sys_getuid)
+/*25*/	.xword C_LABEL(sys_time), C_LABEL(sys_ptrace), C_LABEL(sys_alarm)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_pause)
+/*30*/	.xword C_LABEL(sys_utime), C_LABEL(sys_stty), C_LABEL(sys_gtty)
+	.xword C_LABEL(sys_access), C_LABEL(sys_nice), C_LABEL(sys_ftime)
+	.xword C_LABEL(sys_sync), C_LABEL(sys_kill), C_LABEL(sys_newstat)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_newlstat), C_LABEL(sys_dup)
+	.xword C_LABEL(sys_pipe), C_LABEL(sys_times), C_LABEL(sys_profil)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_setgid), C_LABEL(sys_getgid)
+	.xword C_LABEL(sys_signal), C_LABEL(sys_geteuid)
+/*50*/	.xword C_LABEL(sys_getegid), C_LABEL(sys_acct), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_ioctl), C_LABEL(sys_reboot)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_symlink), C_LABEL(sys_readlink)
+	.xword C_LABEL(sys_execve), C_LABEL(sys_umask), C_LABEL(sys_chroot)
+	.xword C_LABEL(sys_newfstat), C_LABEL(sys_nis_syscall), C_LABEL(sys_getpagesize)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_vfork), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_mmap), C_LABEL(sys_nis_syscall), C_LABEL(sys_munmap)
+	.xword C_LABEL(sys_mprotect), C_LABEL(sys_nis_syscall), C_LABEL(sys_vhangup)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_getgroups)
+	.xword C_LABEL(sys_setgroups), C_LABEL(sys_getpgrp), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_setitimer), C_LABEL(sys_nis_syscall), C_LABEL(sys_swapon)
+	.xword C_LABEL(sys_getitimer), C_LABEL(sys_nis_syscall), C_LABEL(sys_sethostname)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_dup2), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_fcntl), C_LABEL(sys_select), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_fsync), C_LABEL(sys_setpriority), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+/*100*/	.xword C_LABEL(sys_getpriority), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_gettimeofday), C_LABEL(sys_getrusage)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_readv)
+	.xword C_LABEL(sys_writev), C_LABEL(sys_settimeofday), C_LABEL(sys_fchown)
+	.xword C_LABEL(sys_fchmod), C_LABEL(sys_nis_syscall), C_LABEL(sys_setreuid)
+	.xword C_LABEL(sys_setregid), C_LABEL(sys_rename), C_LABEL(sys_truncate)
+	.xword C_LABEL(sys_ftruncate), C_LABEL(sys_flock), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_mkdir), C_LABEL(sys_rmdir), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_getrlimit)
+	.xword C_LABEL(sys_setrlimit), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+/*150*/	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_statfs), C_LABEL(sys_fstatfs)
+	.xword C_LABEL(sys_umount), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_setdomainname)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_quotactl), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_mount), C_LABEL(sys_ustat), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_getdents), C_LABEL(sys_setsid)
+	.xword C_LABEL(sys_fchdir), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_sigpending), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_setpgid), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_newuname), C_LABEL(sys_init_module)
+	.xword C_LABEL(sys_personality), C_LABEL(sys_prof), C_LABEL(sys_break)
+	.xword C_LABEL(sys_lock), C_LABEL(sys_mpx), C_LABEL(sys_ulimit)
+	.xword C_LABEL(sys_getppid), C_LABEL(sparc_sigaction), C_LABEL(sys_sgetmask)
+/*200*/	.xword C_LABEL(sys_ssetmask), C_LABEL(sys_sigsuspend), C_LABEL(sys_newlstat)
+	.xword C_LABEL(sys_uselib), C_LABEL(old_readdir), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_socketcall), C_LABEL(sys_syslog), C_LABEL(sys_olduname)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_idle), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_waitpid), C_LABEL(sys_swapoff), C_LABEL(sys_sysinfo)
+	.xword C_LABEL(sys_ipc), C_LABEL(sys_sigreturn), C_LABEL(sys_clone)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_adjtimex), C_LABEL(sys_sigprocmask)
+	.xword C_LABEL(sys_create_module), C_LABEL(sys_delete_module)
+	.xword C_LABEL(sys_get_kernel_syms), C_LABEL(sys_getpgid), C_LABEL(sys_bdflush)
+	.xword C_LABEL(sys_sysfs), C_LABEL(sys_nis_syscall), C_LABEL(sys_setfsuid)
+	.xword C_LABEL(sys_setfsgid), C_LABEL(sys_llseek), C_LABEL(sys_time)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_stime), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_llseek)
+	/* "We are the Knights of the Forest of Ni!!" */
+	.xword C_LABEL(sys_mlock), C_LABEL(sys_munlock), C_LABEL(sys_mlockall)
+	.xword C_LABEL(sys_munlockall), C_LABEL(sys_sched_setparam)
+	.xword C_LABEL(sys_sched_getparam), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_sched_get_priority_max), C_LABEL(sys_sched_get_priority_min)
+	.xword C_LABEL(sys_sched_rr_get_interval), C_LABEL(sys_nanosleep)
+/*250*/	.xword C_LABEL(sys_mremap)
+	.xword C_LABEL(sys_sysctl)
+	.xword C_LABEL(sys_getsid), C_LABEL(sys_fdatasync), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_aplib), C_LABEL(sys_nis_syscall)
+
+	/* Now the 64-bit native Linux syscall table. */
+
+	.globl C_LABEL(sys_call_table64)
+C_LABEL(sys_call_table64):
+/*0*/	.xword C_LABEL(sys_setup), C_LABEL(sys_exit), C_LABEL(sys_fork)
+	.xword C_LABEL(sys_read), C_LABEL(sys_write)
+/*5*/	.xword C_LABEL(sys_open), C_LABEL(sys_close), C_LABEL(sys_wait4)
+	.xword C_LABEL(sys_creat), C_LABEL(sys_link)
+/*10*/  .xword C_LABEL(sys_unlink), C_LABEL(sunos_execv), C_LABEL(sys_chdir)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_mknod)
+/*15*/	.xword C_LABEL(sys_chmod), C_LABEL(sys_chown), C_LABEL(sparc_brk)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_lseek)
+/*20*/	.xword C_LABEL(sys_getpid), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_setuid), C_LABEL(sys_getuid)
+/*25*/	.xword C_LABEL(sys_time), C_LABEL(sys_ptrace), C_LABEL(sys_alarm)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_pause)
+/*30*/	.xword C_LABEL(sys_utime), C_LABEL(sys_stty), C_LABEL(sys_gtty)
+	.xword C_LABEL(sys_access), C_LABEL(sys_nice), C_LABEL(sys_ftime)
+	.xword C_LABEL(sys_sync), C_LABEL(sys_kill), C_LABEL(sys_newstat)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_newlstat), C_LABEL(sys_dup)
+	.xword C_LABEL(sys_pipe), C_LABEL(sys_times), C_LABEL(sys_profil)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_setgid), C_LABEL(sys_getgid)
+	.xword C_LABEL(sys_signal), C_LABEL(sys_geteuid)
+/*50*/	.xword C_LABEL(sys_getegid), C_LABEL(sys_acct), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_ioctl), C_LABEL(sys_reboot)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_symlink), C_LABEL(sys_readlink)
+	.xword C_LABEL(sys_execve), C_LABEL(sys_umask), C_LABEL(sys_chroot)
+	.xword C_LABEL(sys_newfstat), C_LABEL(sys_nis_syscall), C_LABEL(sys_getpagesize)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_vfork), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_mmap), C_LABEL(sys_nis_syscall), C_LABEL(sys_munmap)
+	.xword C_LABEL(sys_mprotect), C_LABEL(sys_nis_syscall), C_LABEL(sys_vhangup)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_getgroups)
+	.xword C_LABEL(sys_setgroups), C_LABEL(sys_getpgrp), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_setitimer), C_LABEL(sys_nis_syscall), C_LABEL(sys_swapon)
+	.xword C_LABEL(sys_getitimer), C_LABEL(sys_nis_syscall), C_LABEL(sys_sethostname)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_dup2), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_fcntl), C_LABEL(sys_select), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_fsync), C_LABEL(sys_setpriority), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+/*100*/	.xword C_LABEL(sys_getpriority), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_gettimeofday), C_LABEL(sys_getrusage)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_readv)
+	.xword C_LABEL(sys_writev), C_LABEL(sys_settimeofday), C_LABEL(sys_fchown)
+	.xword C_LABEL(sys_fchmod), C_LABEL(sys_nis_syscall), C_LABEL(sys_setreuid)
+	.xword C_LABEL(sys_setregid), C_LABEL(sys_rename), C_LABEL(sys_truncate)
+	.xword C_LABEL(sys_ftruncate), C_LABEL(sys_flock), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_mkdir), C_LABEL(sys_rmdir), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_getrlimit)
+	.xword C_LABEL(sys_setrlimit), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+/*150*/	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_statfs), C_LABEL(sys_fstatfs)
+	.xword C_LABEL(sys_umount), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_setdomainname)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_quotactl), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_mount), C_LABEL(sys_ustat), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_getdents), C_LABEL(sys_setsid)
+	.xword C_LABEL(sys_fchdir), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_sigpending), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_setpgid), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_newuname), C_LABEL(sys_init_module)
+	.xword C_LABEL(sys_personality), C_LABEL(sys_prof), C_LABEL(sys_break)
+	.xword C_LABEL(sys_lock), C_LABEL(sys_mpx), C_LABEL(sys_ulimit)
+	.xword C_LABEL(sys_getppid), C_LABEL(sparc_sigaction), C_LABEL(sys_sgetmask)
+/*200*/	.xword C_LABEL(sys_ssetmask), C_LABEL(sys_sigsuspend), C_LABEL(sys_newlstat)
+	.xword C_LABEL(sys_uselib), C_LABEL(old_readdir), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_socketcall), C_LABEL(sys_syslog), C_LABEL(sys_olduname)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_idle), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_waitpid), C_LABEL(sys_swapoff), C_LABEL(sys_sysinfo)
+	.xword C_LABEL(sys_ipc), C_LABEL(sys_sigreturn), C_LABEL(sys_clone)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_adjtimex), C_LABEL(sys_sigprocmask)
+	.xword C_LABEL(sys_create_module), C_LABEL(sys_delete_module)
+	.xword C_LABEL(sys_get_kernel_syms), C_LABEL(sys_getpgid), C_LABEL(sys_bdflush)
+	.xword C_LABEL(sys_sysfs), C_LABEL(sys_nis_syscall), C_LABEL(sys_setfsuid)
+	.xword C_LABEL(sys_setfsgid), C_LABEL(sys_llseek), C_LABEL(sys_time)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_stime), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_llseek)
+	/* "We are the Knights of the Forest of Ni!!" */
+	.xword C_LABEL(sys_mlock), C_LABEL(sys_munlock), C_LABEL(sys_mlockall)
+	.xword C_LABEL(sys_munlockall), C_LABEL(sys_sched_setparam)
+	.xword C_LABEL(sys_sched_getparam), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_sched_get_priority_max), C_LABEL(sys_sched_get_priority_min)
+	.xword C_LABEL(sys_sched_rr_get_interval), C_LABEL(sys_nanosleep)
+/*250*/	.xword C_LABEL(sys_mremap)
+	.xword C_LABEL(sys_sysctl)
+	.xword C_LABEL(sys_getsid), C_LABEL(sys_fdatasync), C_LABEL(sys_nis_syscall)
+	.xword C_LABEL(sys_aplib), C_LABEL(sys_nis_syscall)
+
+	/* Now the 32-bit SunOS syscall table. */
+
+	.align 4
+	.globl C_LABEL(sunos_sys_table)
+C_LABEL(sunos_sys_table):
+/*0*/	.xword C_LABEL(sunos_indir), C_LABEL(sys_exit), C_LABEL(sys_fork)
+	.xword C_LABEL(sunos_read), C_LABEL(sunos_write), C_LABEL(sunos_open)
+	.xword C_LABEL(sys_close), C_LABEL(sunos_wait4), C_LABEL(sys_creat)
+	.xword C_LABEL(sys_link), C_LABEL(sys_unlink), C_LABEL(sunos_execv)
+	.xword C_LABEL(sys_chdir), C_LABEL(sunos_nosys), C_LABEL(sys_mknod)
+	.xword C_LABEL(sys_chmod), C_LABEL(sys_chown), C_LABEL(sunos_brk)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sys_lseek), C_LABEL(sunos_getpid)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_getuid), C_LABEL(sunos_nosys), C_LABEL(sys_ptrace)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sys_access), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sys_sync), C_LABEL(sys_kill), C_LABEL(sys_newstat)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sys_newlstat), C_LABEL(sys_dup)
+	.xword C_LABEL(sys_pipe), C_LABEL(sunos_nosys), C_LABEL(sys_profil)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_getgid)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+/*50*/	.xword C_LABEL(sunos_nosys), C_LABEL(sys_acct), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_mctl), C_LABEL(sunos_ioctl), C_LABEL(sys_reboot)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sys_symlink), C_LABEL(sys_readlink)
+	.xword C_LABEL(sys_execve), C_LABEL(sys_umask), C_LABEL(sys_chroot)
+	.xword C_LABEL(sys_newfstat), C_LABEL(sunos_nosys), C_LABEL(sys_getpagesize)
+	.xword C_LABEL(sys_msync), C_LABEL(sys_vfork), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_sbrk), C_LABEL(sunos_sstk)
+	.xword C_LABEL(sunos_mmap), C_LABEL(sunos_vadvise), C_LABEL(sys_munmap)
+	.xword C_LABEL(sys_mprotect), C_LABEL(sunos_madvise), C_LABEL(sys_vhangup)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_mincore), C_LABEL(sys_getgroups)
+	.xword C_LABEL(sys_setgroups), C_LABEL(sys_getpgrp), C_LABEL(sunos_setpgrp)
+	.xword C_LABEL(sys_setitimer), C_LABEL(sunos_nosys), C_LABEL(sys_swapon)
+	.xword C_LABEL(sys_getitimer), C_LABEL(sys_gethostname), C_LABEL(sys_sethostname)
+	.xword C_LABEL(sunos_getdtablesize), C_LABEL(sys_dup2), C_LABEL(sunos_nop)
+	.xword C_LABEL(sys_fcntl), C_LABEL(sunos_select), C_LABEL(sunos_nop)
+	.xword C_LABEL(sys_fsync), C_LABEL(sys_setpriority), C_LABEL(sys_socket)
+	.xword C_LABEL(sys_connect), C_LABEL(sunos_accept)
+/*100*/	.xword C_LABEL(sys_getpriority), C_LABEL(sunos_send), C_LABEL(sunos_recv)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sys_bind), C_LABEL(sunos_setsockopt)
+	.xword C_LABEL(sys_listen), C_LABEL(sunos_nosys), C_LABEL(sunos_sigaction)
+	.xword C_LABEL(sunos_sigblock), C_LABEL(sunos_sigsetmask), C_LABEL(sys_sigpause)
+	.xword C_LABEL(sys_sigstack), C_LABEL(sys_recvmsg), C_LABEL(sys_sendmsg)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sys_gettimeofday), C_LABEL(sys_getrusage)
+	.xword C_LABEL(sunos_getsockopt), C_LABEL(sunos_nosys), C_LABEL(sunos_readv)
+	.xword C_LABEL(sunos_writev), C_LABEL(sys_settimeofday), C_LABEL(sys_fchown)
+	.xword C_LABEL(sys_fchmod), C_LABEL(sys_recvfrom), C_LABEL(sys_setreuid)
+	.xword C_LABEL(sys_setregid), C_LABEL(sys_rename), C_LABEL(sys_truncate)
+	.xword C_LABEL(sys_ftruncate), C_LABEL(sys_flock), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sys_sendto), C_LABEL(sys_shutdown), C_LABEL(sys_socketpair)
+	.xword C_LABEL(sys_mkdir), C_LABEL(sys_rmdir), C_LABEL(sys_utimes)
+	.xword C_LABEL(sys_sigreturn), C_LABEL(sunos_nosys), C_LABEL(sys_getpeername)
+	.xword C_LABEL(sunos_gethostid), C_LABEL(sunos_nosys), C_LABEL(sys_getrlimit)
+	.xword C_LABEL(sys_setrlimit), C_LABEL(sunos_killpg), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+/*150*/	.xword C_LABEL(sys_getsockname), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_poll), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_getdirentries), C_LABEL(sys_statfs), C_LABEL(sys_fstatfs)
+	.xword C_LABEL(sys_umount), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_getdomainname), C_LABEL(sys_setdomainname)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sys_quotactl), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_mount), C_LABEL(sys_ustat), C_LABEL(sunos_semsys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_shmsys), C_LABEL(sunos_audit)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_getdents), C_LABEL(sys_setsid)
+	.xword C_LABEL(sys_fchdir), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sys_sigpending), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sys_setpgid), C_LABEL(sunos_pathconf), C_LABEL(sunos_fpathconf)
+	.xword C_LABEL(sunos_sysconf), C_LABEL(sunos_uname), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+/*200*/	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+/*250*/	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+	.xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sys_aplib)
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/kernel/ttable.S linux/arch/sparc64/kernel/ttable.S
--- v2.1.18/linux/arch/sparc64/kernel/ttable.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/kernel/ttable.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,254 @@
+/* $Id: ttable.S,v 1.3 1996/12/28 18:39:43 davem Exp $
+ * ttable.S: Sparc V9 Trap Table(s) with SpitFire extensions.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+	.globl	start, _start
+	.globl	sparc64_ttable_tl0, sparc64_ttable_tl1
+_start:
+start:
+sparc64_ttable_tl0:
+tl0_resv000:	BOOT_KERNEL BTRAP(0x1) BTRAP(0x2) BTRAP(0x3)
+tl0_resv004:	BTRAP(0x4)  BTRAP(0x5) BTRAP(0x6) BTRAP(0x7)
+tl0_iax:	TRAP(do_iax)
+tl0_resv009:	BTRAP(0x9)
+tl0_iae:	TRAP(do_iae)
+tl0_resv00b:	BTRAP(0xb) BTRAP(0xc) BTRAP(0xd) BTRAP(0xe) BTRAP(0xf)
+tl0_ill:	TRAP(do_ill)
+tl0_privop:	TRAP(do_privop)
+tl0_resv012:	BTRAP(0x12) BTRAP(0x13) BTRAP(0x14) BTRAP(0x15) BTRAP(0x16) BTRAP(0x17)
+tl0_resv018:	BTRAP(0x18) BTRAP(0x19) BTRAP(0x1a) BTRAP(0x1b) BTRAP(0x1c) BTRAP(0x1d)
+tl0_resv01e:	BTRAP(0x1e) BTRAP(0x1f)
+tl0_fpdis:	TRAP(do_fpdis)
+tl0_fpieee:	TRAP(do_fpieee)
+tl0_fpother:	TRAP(do_fpother)
+tl0_tof:	TRAP(do_tof)
+tl0_cwin:	CLEAN_WINDOW
+tl0_div0:	TRAP(do_div0)
+tl0_resv029:	BTRAP(0x29) BTRAP(0x2a) BTRAP(0x2b) BTRAP(0x2c) BTRAP(0x2d) BTRAP(0x2e)
+tl0_resv02f:	BTRAP(0x2f)
+tl0_dax:	TRAP(do_dax)
+tl0_resv031:	BTRAP(0x31)
+tl0_dae:	TRAP(do_dae)
+tl0_resv033:	BTRAP(0x33)
+tl0_mna:	TRAP(do_mna)
+tl0_lddfmna:	TRAP(do_lddfmna)
+tl0_stdfmna:	TRAP(do_stdfmna)
+tl0_privact:	TRAP(do_privact)
+tl0_resv038:	BTRAP(0x38) BTRAP(0x39) BTRAP(0x3a) BTRAP(0x3b) BTRAP(0x3c) BTRAP(0x3d)
+tl0_resv03e:	BTRAP(0x3e) BTRAP(0x3f) BTRAP(0x40)
+tl0_irq1:	TRAP_IRQ(do_irq, 1)  TRAP_IRQ(do_irq, 2)  TRAP_IRQ(do_irq, 3)
+tl0_irq4:	TRAP_IRQ(do_irq, 4)  TRAP_IRQ(do_irq, 5)  TRAP_IRQ(do_irq, 6)
+tl0_irq7:	TRAP_IRQ(do_irq, 7)  TRAP_IRQ(do_irq, 8)  TRAP_IRQ(do_irq, 9)
+tl0_irq10:	TRAP_IRQ(do_irq, 10) TRAP_IRQ(do_irq, 11) TRAP_IRQ(do_irq, 12)
+tl0_irq13:	TRAP_IRQ(do_irq, 13) TRAP_IRQ(do_irq, 14) TRAP_IRQ(do_irq, 15)
+tl0_resv050:	BTRAP(0x50) BTRAP(0x51) BTRAP(0x52) BTRAP(0x53) BTRAP(0x54) BTRAP(0x55)
+tl0_resv056:	BTRAP(0x56) BTRAP(0x57) BTRAP(0x58) BTRAP(0x59) BTRAP(0x5a) BTRAP(0x5b)
+tl0_resv05c:	BTRAP(0x5c) BTRAP(0x5d) BTRAP(0x5e) BTRAP(0x5f)
+tl0_ivec:	TRAP(do_ivec)
+tl0_paw:	TRAP(do_paw)
+tl0_vaw:	TRAP(do_vaw)
+tl0_cee:	TRAP(do_cee)
+tl0_iamiss:
+#include	"itlb_miss.S"
+tl0_damiss:
+#include	"dtlb_miss.S"
+tl0_daprot:
+#include	"dtlb_prot.S"
+tl0_resv070:	BTRAP(0x70) BTRAP(0x71) BTRAP(0x72) BTRAP(0x73) BTRAP(0x74) BTRAP(0x75)
+tl0_resv076:	BTRAP(0x76) BTRAP(0x77) BTRAP(0x78) BTRAP(0x79) BTRAP(0x7a) BTRAP(0x7b)
+tl0_resv07c:	BTRAP(0x7c) BTRAP(0x7d) BTRAP(0x7e) BTRAP(0x7f)
+tl0_s0n:	SPILL_0_NORMAL
+tl0_s1n:	SPILL_1_NORMAL
+tl0_s2n:	SPILL_2_NORMAL
+tl0_s3n:	SPILL_3_NORMAL
+tl0_s4n:	SPILL_4_NORMAL
+tl0_s5n:	SPILL_5_NORMAL
+tl0_s6n:	SPILL_6_NORMAL
+tl0_s7n:	SPILL_7_NORMAL
+tl0_s0o:	SPILL_0_OTHER
+tl0_s1o:	SPILL_1_OTHER
+tl0_s2o:	SPILL_2_OTHER
+tl0_s3o:	SPILL_3_OTHER
+tl0_s4o:	SPILL_4_OTHER
+tl0_s5o:	SPILL_5_OTHER
+tl0_s6o:	SPILL_6_OTHER
+tl0_s7o:	SPILL_7_OTHER
+tl0_f0n:	FILL_0_NORMAL
+tl0_f1n:	FILL_1_NORMAL
+tl0_f2n:	FILL_2_NORMAL
+tl0_f3n:	FILL_3_NORMAL
+tl0_f4n:	FILL_4_NORMAL
+tl0_f5n:	FILL_5_NORMAL
+tl0_f6n:	FILL_6_NORMAL
+tl0_f7n:	FILL_7_NORMAL
+tl0_f0o:	FILL_0_OTHER
+tl0_f1o:	FILL_1_OTHER
+tl0_f2o:	FILL_2_OTHER
+tl0_f3o:	FILL_3_OTHER
+tl0_f4o:	FILL_4_OTHER
+tl0_f5o:	FILL_5_OTHER
+tl0_f6o:	FILL_6_OTHER
+tl0_f7o:	FILL_7_OTHER
+tl0_sunos:	SUNOS_SYSCALL_TRAP
+tl0_bkpt:	BREAKPOINT_TRAP
+tl0_resv102:	BTRAP(0x102)
+tl0_flushw:	FLUSH_WINDOW_TRAP
+tl0_resv103:	BTRAP(0x103) BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107)
+tl0_solaris:	SOLARIS_SYSCALL_TRAP
+tl0_netbsd:	NETBSD_SYSCALL_TRAP
+tl0_resv10a:	BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d) BTRAP(0x10e)
+tl0_resv10f:	BTRAP(0x10f)
+tl0_linux32:	LINUX_32BIT_SYSCALL_TRAP
+tl0_linux64:	LINUX_64BIT_SYSCALL_TRAP
+tl0_resv112:	BTRAP(0x112) BTRAP(0x113) BTRAP(0x114) BTRAP(0x115) BTRAP(0x116)
+tl0_resv117:	BTRAP(0x117) BTRAP(0x118) BTRAP(0x119) BTRAP(0x11a) BTRAP(0x11b)
+tl0_resv11c:	BTRAP(0x11c) BTRAP(0x11d) BTRAP(0x11e) BTRAP(0x11f)
+tl0_getcc:	GETCC_TRAP
+tl0_setcc:	SETCC_TRAP
+tl0_resv122:	BTRAP(0x122) BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126)
+tl0_solindir:	INDIRECT_SOLARIS_SYSCALL(156)
+tl0_resv128:	BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c)
+tl0_resv12d:	BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131)
+tl0_resv132:	BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136)
+tl0_resv137:	BTRAP(0x137) BTRAP(0x138) BTRAP(0x139) BTRAP(0x13a) BTRAP(0x13b)
+tl0_resv13c:	BTRAP(0x13c) BTRAP(0x13d) BTRAP(0x13e) BTRAP(0x13f) BTRAP(0x140)
+tl0_resv141:	BTRAP(0x141) BTRAP(0x142) BTRAP(0x143) BTRAP(0x144) BTRAP(0x145)
+tl0_resv146:	BTRAP(0x146) BTRAP(0x147) BTRAP(0x148) BTRAP(0x149) BTRAP(0x14a)
+tl0_resv14b:	BTRAP(0x14b) BTRAP(0x14c) BTRAP(0x14d) BTRAP(0x14e) BTRAP(0x14f)
+tl0_resv150:	BTRAP(0x150) BTRAP(0x151) BTRAP(0x152) BTRAP(0x153) BTRAP(0x154)
+tl0_resv155:	BTRAP(0x155) BTRAP(0x156) BTRAP(0x157) BTRAP(0x158) BTRAP(0x159)
+tl0_resv15a:	BTRAP(0x15a) BTRAP(0x15b) BTRAP(0x15c) BTRAP(0x15d) BTRAP(0x15e)
+tl0_resv15f:	BTRAP(0x15f) BTRAP(0x160) BTRAP(0x161) BTRAP(0x162) BTRAP(0x163)
+tl0_resv164:	BTRAP(0x164) BTRAP(0x165) BTRAP(0x166) BTRAP(0x167) BTRAP(0x168)
+tl0_resv169:	BTRAP(0x169) BTRAP(0x16a) BTRAP(0x16b) BTRAP(0x16c) BTRAP(0x16d)
+tl0_resv16e:	BTRAP(0x16e) BTRAP(0x16f) BTRAP(0x170) BTRAP(0x171) BTRAP(0x172)
+tl0_resv173:	BTRAP(0x173) BTRAP(0x174) BTRAP(0x175) BTRAP(0x176) BTRAP(0x177)
+tl0_resv178:	BTRAP(0x178) BTRAP(0x179) BTRAP(0x17a) BTRAP(0x17b) BTRAP(0x17c)
+tl0_resv17d:	BTRAP(0x17d) BTRAP(0x17e) BTRAP(0x17f)
+
+sparc64_ttable_tl1:
+tl1_resv000:	BOOT_KERNEL    BTRAPTL1(0x1) BTRAPTL1(0x2) BTRAPTL1(0x3)
+tl1_resv004:	BTRAPTL1(0x4)  BTRAPTL1(0x5) BTRAPTL1(0x6) BTRAPTL1(0x7)
+tl1_iax:	TRAP(do_iax_tl1)
+tl1_resv009:	BTRAPTL1(0x9)
+tl1_iae:	TRAP(do_iae_tl1)
+tl1_resv00b:	BTRAPTL1(0xb) BTRAPTL1(0xc) BTRAPTL1(0xd) BTRAPTL1(0xe) BTRAPTL1(0xf)
+tl1_ill:	TRAP(do_ill_tl1)
+tl1_privop:	BAD_TRAP(0x11)
+tl1_resv012:	BTRAPTL1(0x12) BTRAPTL1(0x13) BTRAPTL1(0x14) BTRAPTL1(0x15)
+tl1_resv016:	BTRAPTL1(0x16) BTRAPTL1(0x17) BTRAPTL1(0x18) BTRAPTL1(0x19)
+tl1_resv01a:	BTRAPTL1(0x1a) BTRAPTL1(0x1b) BTRAPTL1(0x1c) BTRAPTL1(0x1d)
+tl1_resv01e:	BTRAPTL1(0x1e) BTRAPTL1(0x1f)
+tl1_fpdis:	TRAP(do_fpdis_tl1)
+tl1_fpieee:	TRAP(do_fpieee_tl1)
+tl1_fpother:	TRAP(do_fpother_tl1)
+tl1_tof:	TRAP(do_tof_tl1)
+tl1_cwin:	CLEAN_WINDOW
+tl1_div0:	TRAP(do_div0_tl1)
+tl1_resv029:	BTRAPTL1(0x29) BTRAPTL1(0x2a) BTRAPTL1(0x2b) BTRAPTL1(0x2c)
+tl1_resv02d:	BTRAPTL1(0x2d) BTRAPTL1(0x2e) BTRAPTL1(0x2f)
+tl1_dax:	TRAP(do_dax_tl1)
+tl1_resv031:	BTRAPTL1(0x31)
+tl1_dae:	TRAP(do_dae_tl1)
+tl1_resv033:	BTRAPTL1(0x33)
+tl1_mna:	TRAP(do_mna_tl1)
+tl1_lddfmna:	TRAP(do_lddfmna_tl1)
+tl1_stdfmna:	TRAP(do_stdfmna_tl1)
+tl1_privact:	BTRAPTL1(0x37)
+tl1_resv038:	BTRAPTL1(0x38) BTRAPTL1(0x39) BTRAPTL1(0x3a) BTRAPTL1(0x3b)
+tl1_resv03c:	BTRAPTL1(0x3c) BTRAPTL1(0x3d) BTRAPTL1(0x3e) BTRAPTL1(0x3f)
+tl1_resv040:	BTRAPTL1(0x40)
+tl1_irq1:	TRAP_IRQ(do_irq_tl1, 1)  TRAP_IRQ(do_irq_tl1, 2)  TRAP_IRQ(do_irq_tl1, 3)
+tl1_irq4:	TRAP_IRQ(do_irq_tl1, 4)  TRAP_IRQ(do_irq_tl1, 5)  TRAP_IRQ(do_irq_tl1, 6)
+tl1_irq7:	TRAP_IRQ(do_irq_tl1, 7)  TRAP_IRQ(do_irq_tl1, 8)  TRAP_IRQ(do_irq_tl1, 9)
+tl1_irq10:	TRAP_IRQ(do_irq_tl1, 10) TRAP_IRQ(do_irq_tl1, 11)
+tl1_irq12:	TRAP_IRQ(do_irq_tl1, 12) TRAP_IRQ(do_irq_tl1, 13)
+tl1_irq14:	TRAP_IRQ(do_irq_tl1, 14) TRAP_IRQ(do_irq_tl1, 15)
+tl1_resv050:	BTRAPTL1(0x50) BTRAPTL1(0x51) BTRAPTL1(0x52) BTRAPTL1(0x53)
+tl1_resv054:	BTRAPTL1(0x54) BTRAPTL1(0x55) BTRAPTL1(0x56) BTRAPTL1(0x57)
+tl1_resv058:	BTRAPTL1(0x58) BTRAPTL1(0x59) BTRAPTL1(0x5a) BTRAPTL1(0x5b)
+tl1_resv05c:	BTRAPTL1(0x5c) BTRAPTL1(0x5d) BTRAPTL1(0x5e) BTRAPTL1(0x5f)
+tl1_ivec:	TRAP(do_ivec_tl1)
+tl1_paw:	TRAP(do_paw_tl1)
+tl1_vaw:	TRAP(do_vaw_tl1)
+tl1_cee:	TRAP(do_cee_tl1)
+tl1_iamiss:
+#include	"itlb_miss.S"
+tl1_damiss:
+#include	"dtlb_miss.S"
+tl1_daprot:
+#include	"dtlb_prot.S"
+tl1_resv070:	BTRAPTL1(0x70) BTRAPTL1(0x71) BTRAPTL1(0x72) BTRAPTL1(0x73)
+tl1_resv074:	BTRAPTL1(0x74) BTRAPTL1(0x75) BTRAPTL1(0x76) BTRAPTL1(0x77)
+tl1_resv078:	BTRAPTL1(0x78) BTRAPTL1(0x79) BTRAPTL1(0x7a) BTRAPTL1(0x7b)
+tl1_resv07c:	BTRAPTL1(0x7c) BTRAPTL1(0x7d) BTRAPTL1(0x7e) BTRAPTL1(0x7f)
+tl1_s0n:	SPILL_0_NORMAL_TL1
+tl1_s1n:	SPILL_1_NORMAL_TL1
+tl1_s2n:	SPILL_2_NORMAL_TL1
+tl1_s3n:	SPILL_3_NORMAL_TL1
+tl1_s4n:	SPILL_4_NORMAL_TL1
+tl1_s5n:	SPILL_5_NORMAL_TL1
+tl1_s6n:	SPILL_6_NORMAL_TL1
+tl1_s7n:	SPILL_7_NORMAL_TL1
+tl1_s0o:	SPILL_0_OTHER_TL1
+tl1_s1o:	SPILL_1_OTHER_TL1
+tl1_s2o:	SPILL_2_OTHER_TL1
+tl1_s3o:	SPILL_3_OTHER_TL1
+tl1_s4o:	SPILL_4_OTHER_TL1
+tl1_s5o:	SPILL_5_OTHER_TL1
+tl1_s6o:	SPILL_6_OTHER_TL1
+tl1_s7o:	SPILL_7_OTHER_TL1
+tl1_f0n:	FILL_0_NORMAL_TL1
+tl1_f1n:	FILL_1_NORMAL_TL1
+tl1_f2n:	FILL_2_NORMAL_TL1
+tl1_f3n:	FILL_3_NORMAL_TL1
+tl1_f4n:	FILL_4_NORMAL_TL1
+tl1_f5n:	FILL_5_NORMAL_TL1
+tl1_f6n:	FILL_6_NORMAL_TL1
+tl1_f7n:	FILL_7_NORMAL_TL1
+tl1_f0o:	FILL_0_OTHER_TL1
+tl1_f1o:	FILL_1_OTHER_TL1
+tl1_f2o:	FILL_2_OTHER_TL1
+tl1_f3o:	FILL_3_OTHER_TL1
+tl1_f4o:	FILL_4_OTHER_TL1
+tl1_f5o:	FILL_5_OTHER_TL1
+tl1_f6o:	FILL_6_OTHER_TL1
+tl1_f7o:	FILL_7_OTHER_TL1
+tl1_sunos:	BTRAPTL1(0x100)
+tl1_bkpt:	BREAKPOINT_TRAP
+tl1_resv102:	BTRAPTL1(0x102)
+tl1_flushw:	FLUSH_WINDOW_TRAP
+tl1_resv103:	BTRAPTL1(0x103) BTRAPTL1(0x104) BTRAPTL1(0x105) BTRAPTL1(0x106)
+tl1_resv107:	BTRAPTL1(0x107) BTRAPTL1(0x108) BTRAPTL1(0x109) BTRAPTL1(0x10a)
+tl1_resv10b:	BTRAPTL1(0x10b) BTRAPTL1(0x10c) BTRAPTL1(0x10d) BTRAPTL1(0x10e)
+tl1_resv10f:	BTRAPTL1(0x10f) BTRAPTL1(0x110) BTRAPTL1(0x111) BTRAPTL1(0x112)
+tl1_resv113:	BTRAPTL1(0x113) BTRAPTL1(0x114) BTRAPTL1(0x115) BTRAPTL1(0x116)
+tl1_resv117:	BTRAPTL1(0x117) BTRAPTL1(0x118) BTRAPTL1(0x119) BTRAPTL1(0x11a)
+tl1_resv11b:	BTRAPTL1(0x11b) BTRAPTL1(0x11c) BTRAPTL1(0x11d) BTRAPTL1(0x11e)
+tl1_resv11f:	BTRAPTL1(0x11f) BTRAPTL1(0x120) BTRAPTL1(0x121) BTRAPTL1(0x122)
+tl1_resv123:	BTRAPTL1(0x123) BTRAPTL1(0x124) BTRAPTL1(0x125) BTRAPTL1(0x126)
+tl1_solindir:	BTRAPTL1(0x127) BTRAPTL1(0x128) BTRAPTL1(0x129) BTRAPTL1(0x12a)
+tl1_resv12b:	BTRAPTL1(0x12b) BTRAPTL1(0x12c) BTRAPTL1(0x12d) BTRAPTL1(0x12e)
+tl1_resv12f:	BTRAPTL1(0x12f) BTRAPTL1(0x130) BTRAPTL1(0x131) BTRAPTL1(0x132)
+tl1_resv133:	BTRAPTL1(0x133) BTRAPTL1(0x134) BTRAPTL1(0x135) BTRAPTL1(0x136)
+tl1_resv137:	BTRAPTL1(0x137) BTRAPTL1(0x138) BTRAPTL1(0x139) BTRAPTL1(0x13a)
+tl1_resv13b:	BTRAPTL1(0x13b) BTRAPTL1(0x13c) BTRAPTL1(0x13d) BTRAPTL1(0x13e)
+tl1_resv13f:	BTRAPTL1(0x13f) BTRAPTL1(0x140) BTRAPTL1(0x141) BTRAPTL1(0x142)
+tl1_resv143:	BTRAPTL1(0x143) BTRAPTL1(0x144) BTRAPTL1(0x145) BTRAPTL1(0x146)
+tl1_resv147:	BTRAPTL1(0x147) BTRAPTL1(0x148) BTRAPTL1(0x149) BTRAPTL1(0x14a)
+tl1_resv14b:	BTRAPTL1(0x14b) BTRAPTL1(0x14c) BTRAPTL1(0x14d) BTRAPTL1(0x14e)
+tl1_resv14f:	BTRAPTL1(0x14f) BTRAPTL1(0x150) BTRAPTL1(0x151) BTRAPTL1(0x152)
+tl1_resv153:	BTRAPTL1(0x153) BTRAPTL1(0x154) BTRAPTL1(0x155) BTRAPTL1(0x156)
+tl1_resv157:	BTRAPTL1(0x157) BTRAPTL1(0x158) BTRAPTL1(0x159) BTRAPTL1(0x15a)
+tl1_resv15b:	BTRAPTL1(0x15b) BTRAPTL1(0x15c) BTRAPTL1(0x15d) BTRAPTL1(0x15e)
+tl1_resv15f:	BTRAPTL1(0x15f) BTRAPTL1(0x160) BTRAPTL1(0x161) BTRAPTL1(0x162)
+tl1_resv163:	BTRAPTL1(0x163) BTRAPTL1(0x164) BTRAPTL1(0x165) BTRAPTL1(0x166)
+tl1_resv167:	BTRAPTL1(0x167) BTRAPTL1(0x168) BTRAPTL1(0x169) BTRAPTL1(0x16a)
+tl1_resv16b:	BTRAPTL1(0x16b) BTRAPTL1(0x16c) BTRAPTL1(0x16d) BTRAPTL1(0x16e)
+tl1_resv16f:	BTRAPTL1(0x16f) BTRAPTL1(0x170) BTRAPTL1(0x171) BTRAPTL1(0x172)
+tl1_resv173:	BTRAPTL1(0x173) BTRAPTL1(0x174) BTRAPTL1(0x175) BTRAPTL1(0x176)
+tl1_resv177:	BTRAPTL1(0x177) BTRAPTL1(0x178) BTRAPTL1(0x179) BTRAPTL1(0x17a)
+tl1_resv17b:	BTRAPTL1(0x17b) BTRAPTL1(0x17c)	BTRAPTL1(0x17d) BTRAPTL1(0x17e)
+tl1_resv17f:	BTRAPTL1(0x17f)
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/lib/Makefile linux/arch/sparc64/lib/Makefile
--- v2.1.18/linux/arch/sparc64/lib/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/lib/Makefile	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,21 @@
+# $Id: Makefile,v 1.1 1996/12/27 17:28:35 davem Exp $
+# Makefile for Sparc library files..
+#
+
+CFLAGS := $(CFLAGS) -ansi
+
+OBJS  = memset.o blockops.o
+
+lib.a: $(OBJS)
+	$(AR) rcs lib.a $(OBJS)
+	sync
+
+blockops.o: blockops.S
+	$(CC) -ansi -c -o blockops.o blockops.S
+
+memset.o: memset.S
+	$(CC) -D__ASSEMBLY__ -ansi -c -o memset.o memset.S
+
+dep:
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/lib/blockops.S linux/arch/sparc64/lib/blockops.S
--- v2.1.18/linux/arch/sparc64/lib/blockops.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/lib/blockops.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,89 @@
+/* $Id: blockops.S,v 1.1 1996/12/22 07:42:15 davem Exp $
+ * arch/sparc64/lib/blockops.S: UltraSparc block zero optimized routines.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/asi.h>
+
+	/* Zero out 64 bytes of memory at (buf + offset). */
+#define BLAST_BLOCK(buf, offset)				\
+	stx		%g0, [buf + offset + 0x38];		\
+	stx		%g0, [buf + offset + 0x30];		\
+	stx		%g0, [buf + offset + 0x28];		\
+	stx		%g0, [buf + offset + 0x20];		\
+	stx		%g0, [buf + offset + 0x18];		\
+	stx		%g0, [buf + offset + 0x10];		\
+	stx		%g0, [buf + offset + 0x08];		\
+	stx		%g0, [buf + offset + 0x00];
+
+	/* Copy 32 bytes of memory at (src + offset) to
+	 * (dst + offset).
+	 */
+#define MIRROR_BLOCK(dst, src, offset, t0, t1, t2, t3)		\
+	ldx		[src + offset + 0x18], t0;		\
+	ldx		[src + offset + 0x10], t1;		\
+	ldx		[src + offset + 0x08], t2;		\
+	ldx		[src + offset + 0x00], t3;		\
+	stx		t0, [dst + offset + 0x18];		\
+	stx		t1, [dst + offset + 0x10];		\
+	stx		t2, [dst + offset + 0x08];		\
+	stx		t3, [dst + offset + 0x00];
+
+	.text
+	.align	4
+
+	.globl	C_LABEL(bzero_2page), C_LABEL(bzero_1page)
+C_LABEL(bzero_2page):
+	/* %o0 = buf */
+	or		%o0, %g0, %o1
+	or		%g0, 0x40, %g2
+1:
+	BLAST_BLOCK(%o0, 0x00)
+	BLAST_BLOCK(%o0, 0x40)
+	BLAST_BLOCK(%o0, 0x80)
+	BLAST_BLOCK(%o0, 0xc0)
+	subcc		%g2, 1, %g2
+	bne,pt		%icc, 1b
+	 add		%o0, 0x100, %o0
+
+	retl
+	 mov		%o1, %o0
+
+C_LABEL(bzero_1page):
+	/* %o0 = buf */
+	or		%o0, %g0, %o1
+	or		%g0, 0x20, %g2
+1:
+	BLAST_BLOCK(%o0, 0x00)
+	BLAST_BLOCK(%o0, 0x40)
+	BLAST_BLOCK(%o0, 0x80)
+	BLAST_BLOCK(%o0, 0xc0)
+	subcc		%g2, 1, %g2
+	bne,pt		%icc, 1b
+	 add		%o0, 0x100, %o0
+
+	retl
+	 mov		%o1, %o0
+
+	.globl	C_LABEL(__copy_1page)
+C_LABEL(__copy_1page):
+	/* %o0 = dst, %o1 = src */
+	or		%g0, 0x10, %g1
+1:
+	MIRROR_BLOCK(%o0, %o1, 0x00, %o2, %o3, %o4, %o5)
+	MIRROR_BLOCK(%o0, %o1, 0x20, %o2, %o3, %o4, %o5)
+	MIRROR_BLOCK(%o0, %o1, 0x40, %o2, %o3, %o4, %o5)
+	MIRROR_BLOCK(%o0, %o1, 0x60, %o2, %o3, %o4, %o5)
+	MIRROR_BLOCK(%o0, %o1, 0x80, %o2, %o3, %o4, %o5)
+	MIRROR_BLOCK(%o0, %o1, 0xa0, %o2, %o3, %o4, %o5)
+	MIRROR_BLOCK(%o0, %o1, 0xc0, %o2, %o3, %o4, %o5)
+	MIRROR_BLOCK(%o0, %o1, 0xe0, %o2, %o3, %o4, %o5)
+	subcc		%g1, 1, %g1
+	add		%o0, 0x100, %o0
+	bne,pt		%icc, 1b
+	 add		%o1, 0x100, %o1
+
+	retl
+	 nop
+
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/lib/memset.S linux/arch/sparc64/lib/memset.S
--- v2.1.18/linux/arch/sparc64/lib/memset.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/lib/memset.S	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,133 @@
+/* $Id: memset.S,v 1.1 1996/12/22 07:42:16 davem Exp $
+ * arch/sparc64/lib/memset.S: UltraSparc optimized memset and bzero code
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/asi.h>
+
+	/* Store 64 bytes at (BASE + OFFSET) using value SOURCE. */
+#define ZERO_BIG_BLOCK(base, offset, source)    \
+	stx	source, [base + offset + 0x00]; \
+	stx	source, [base + offset + 0x08]; \
+	stx	source, [base + offset + 0x10]; \
+	stx	source, [base + offset + 0x18]; \
+	stx	source, [base + offset + 0x20]; \
+	stx	source, [base + offset + 0x28]; \
+	stx	source, [base + offset + 0x30]; \
+	stx	source, [base + offset + 0x38];
+
+#define ZERO_LAST_BLOCKS(base, offset, source)	\
+	stx	source, [base - offset - 0x38]; \
+	stx	source, [base - offset - 0x30]; \
+	stx	source, [base - offset - 0x28]; \
+	stx	source, [base - offset - 0x20]; \
+	stx	source, [base - offset - 0x18]; \
+	stx	source, [base - offset - 0x10]; \
+	stx	source, [base - offset - 0x08]; \
+	stx	source, [base - offset - 0x00];
+
+	.text
+	.align 4
+
+	.globl	C_LABEL(__bzero), C_LABEL(__memset), C_LABEL(memset)
+C_LABEL(__memset):
+C_LABEL(memset):
+	and		%o1, 0xff, %g3
+	sll		%g3, 8, %g2
+	or		%g3, %g2, %g3
+	sll		%g3, 16, %g2
+	or		%g3, %g2, %g3
+	sllx		%g3, 32, %g2
+	or		%g3, %g2, %g3
+	b		1f
+	 mov		%o2, %o1
+
+3:
+	cmp		%o2, 3
+	be		2f
+	 stb		%g3, [%o0]
+
+	cmp		%o2, 2
+	be		2f
+	 stb		%g3, [%o0 + 0x01]
+
+	stb		%g3, [%o0 + 0x02]
+2:
+	sub		%o2, 4, %o2
+	add		%o1, %o2, %o1
+	b		4f
+	 sub		%o0, %o2, %o0
+
+C_LABEL(__bzero):
+	mov		%g0, %g3
+1:
+	cmp		%o1, 7
+	bleu,pnt	%icc, 7f
+	 mov		%o0, %g1
+
+	andcc		%o0, 3, %o2
+	bne,pnt		%icc, 3b
+4:
+	 andcc		%o0, 4, %g0
+
+	be,a,pt		%icc, 2f
+	 andcc		%o1, 0xffffff80, %o3	! everything 8 aligned, o1 is len to run
+
+	stw		%g3, [%o0]
+	sub		%o1, 4, %o1
+	add		%o0, 4, %o0
+	andcc		%o1, 0xffffff80, %o3	! everything 8 aligned, o1 is len to run
+2:
+	be		9f
+	 andcc		%o1, 0x78, %o2
+4:
+	ZERO_BIG_BLOCK(%o0, 0x00, %g2)
+	subcc		%o3, 128, %o3
+	ZERO_BIG_BLOCK(%o0, 0x40, %g2)
+	bne,pt		%icc, 4b
+	 add		%o0, 128, %o0
+
+	orcc		%o2, %g0, %g0
+9:
+	be,pnt		%icc, 6f
+	 andcc		%o1, 7, %o1
+
+	srl		%o2, 1, %o3
+	set		bzero_table + 64, %o4
+	sub		%o4, %o3, %o4
+	jmp		%o4
+	 add		%o0, %o2, %o0
+
+bzero_table:
+	ZERO_LAST_BLOCKS(%o0, 0x48, %g2)
+	ZERO_LAST_BLOCKS(%o0, 0x08, %g2)
+
+6:
+	be,pt		%icc, 8f
+	 andcc		%o1, 4, %g0
+
+	be,pnt		%icc, 1f
+	 andcc		%o1, 2, %g0
+
+	stw		%g3, [%o0]
+	add		%o0, 4, %o0
+1:
+	be,pt		%icc, 1f
+	 andcc		%o1, 1, %g0
+
+	sth		%g3, [%o0]
+	add		%o0, 2, %o0
+1:
+	bne,a,pnt	%icc, 8f
+	 stb		%g3, [%o0]
+8:
+	retl
+	 mov		%g1, %o0
+
+/* Don't care about alignment here. It is highly 
+ * unprobable and at most two traps may happen
+ */
+7:
+	ba,pt		%xcc, 6b
+	 orcc		%o1, 0, %g0
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/mm/Makefile linux/arch/sparc64/mm/Makefile
--- v2.1.18/linux/arch/sparc64/mm/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/mm/Makefile	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,13 @@
+# $Id: Makefile,v 1.1 1996/12/26 10:24:22 davem Exp $
+# Makefile for the linux Sparc64-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := mm.o
+O_OBJS   := fault.o init.o generic.o asyncd.o extable.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/mm/asyncd.c linux/arch/sparc64/mm/asyncd.c
--- v2.1.18/linux/arch/sparc64/mm/asyncd.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/mm/asyncd.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,272 @@
+/*  $Id: asyncd.c,v 1.1 1996/12/26 10:24:24 davem Exp $
+ *  The asyncd kernel daemon. This handles paging on behalf of 
+ *  processes that receive page faults due to remote (async) memory
+ *  accesses. 
+ *
+ *  Idea and skeleton code courtesy of David Miller (bless his cotton socks)
+ *
+ *  Implemented by tridge
+ */
+
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/sched.h>
+#include <linux/head.h>
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/swap.h>
+#include <linux/fs.h>
+#include <linux/config.h>
+#include <linux/interrupt.h>
+
+#include <asm/dma.h>
+#include <asm/system.h> /* for cli()/sti() */
+#include <asm/segment.h> /* for memcpy_to/fromfs */
+#include <asm/bitops.h>
+#include <asm/pgtable.h>
+
+#define DEBUG 0
+
+#define WRITE_LIMIT 100
+#define LOOP_LIMIT 200
+
+static struct {
+	int faults, read, write, success, failure, errors;
+} stats;
+
+/* 
+ * The wait queue for waking up the async daemon:
+ */
+static struct wait_queue * asyncd_wait = NULL;
+
+struct async_job {
+	volatile struct async_job *next;
+	int taskid;
+	struct mm_struct *mm;
+	unsigned long address;
+	int write;
+	void (*callback)(int,unsigned long,int,int);
+};
+
+static volatile struct async_job *async_queue = NULL;
+static volatile struct async_job *async_queue_end = NULL;
+
+static void add_to_async_queue(int taskid,
+			       struct mm_struct *mm,
+			       unsigned long address,
+			       int write,
+			       void (*callback)(int,unsigned long,int,int))
+{
+	struct async_job *a = kmalloc(sizeof(*a),GFP_ATOMIC);
+
+	if (!a) {
+		printk("ERROR: out of memory in asyncd\n");
+		a->callback(taskid,address,write,1);
+		return;
+	}
+
+	if (write)
+		stats.write++;
+	else
+		stats.read++;
+
+	a->next = NULL;
+	a->taskid = taskid;
+	a->mm = mm;
+	a->address = address;
+	a->write = write;
+	a->callback = callback;
+
+	if (!async_queue) {
+		async_queue = a;
+	} else {
+		async_queue_end->next = a;
+	}
+	async_queue_end = a;
+}
+
+
+void async_fault(unsigned long address, int write, int taskid,
+		 void (*callback)(int,unsigned long,int,int))
+{
+	struct task_struct *tsk = task[taskid];
+	struct mm_struct *mm = tsk->mm;
+
+	stats.faults++;
+
+#if 0
+	printk("paging in %x for task=%d\n",address,taskid);
+#endif
+
+	add_to_async_queue(taskid, mm, address, write, callback);
+	wake_up(&asyncd_wait);  
+	mark_bh(TQUEUE_BH);
+}
+
+static int fault_in_page(int taskid,
+			 struct vm_area_struct *vma,
+			 unsigned address,int write)
+{
+	static unsigned last_address;
+	static int last_task, loop_counter;
+	struct task_struct *tsk = task[taskid];
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	if (!tsk || !tsk->mm)
+		return 1;
+
+	if (!vma || (write && !(vma->vm_flags & VM_WRITE)))
+	  goto bad_area;
+	if (vma->vm_start > address)
+	  goto bad_area;
+
+	if (address == last_address && taskid == last_task) {
+		loop_counter++;
+	} else {
+		loop_counter = 0;
+		last_address = address; 
+		last_task = taskid;
+	}
+
+	if (loop_counter == WRITE_LIMIT && !write) {
+		printk("MSC bug? setting write request\n");
+		stats.errors++;
+		write = 1;
+	}
+
+	if (loop_counter == LOOP_LIMIT) {
+		printk("MSC bug? failing request\n");
+		stats.errors++;
+		return 1;
+	}
+
+	pgd = pgd_offset(vma->vm_mm, address);
+	pmd = pmd_alloc(pgd,address);
+	if(!pmd)
+		goto no_memory;
+	pte = pte_alloc(pmd, address);
+	if(!pte)
+		goto no_memory;
+	if(!pte_present(*pte)) {
+		do_no_page(tsk, vma, address, write);
+		goto finish_up;
+	}
+	set_pte(pte, pte_mkyoung(*pte));
+	flush_tlb_page(vma, address);
+	if(!write)
+		goto finish_up;
+	if(pte_write(*pte)) {
+		set_pte(pte, pte_mkdirty(*pte));
+		flush_tlb_page(vma, address);
+		goto finish_up;
+	}
+	do_wp_page(tsk, vma, address, write);
+
+	/* Fall through for do_wp_page */
+finish_up:
+	stats.success++;
+	update_mmu_cache(vma, address, *pte);
+	return 0;
+
+no_memory:
+	stats.failure++;
+	oom(tsk);
+	return 1;
+	
+bad_area:	  
+	stats.failure++;
+	tsk->tss.sig_address = address;
+	tsk->tss.sig_desc = SUBSIG_NOMAPPING;
+	send_sig(SIGSEGV, tsk, 1);
+	return 1;
+}
+
+
+/* Note the semaphore operations must be done here, and _not_
+ * in async_fault().
+ */
+static void run_async_queue(void)
+{
+	int ret;
+	unsigned flags;
+
+	while (async_queue) {
+		volatile struct async_job *a;
+		struct mm_struct *mm;
+		struct vm_area_struct *vma;
+
+		save_flags(flags); cli();
+		a = async_queue;
+		async_queue = async_queue->next;
+		restore_flags(flags);
+
+		mm = a->mm;
+
+		down(&mm->mmap_sem);
+		vma = find_vma(mm, a->address);
+		ret = fault_in_page(a->taskid,vma,a->address,a->write);
+#if DEBUG
+		printk("fault_in_page(task=%d addr=%x write=%d) = %d\n",
+		       a->taskid,a->address,a->write,ret);
+#endif
+		a->callback(a->taskid,a->address,a->write,ret);
+		up(&mm->mmap_sem);
+		kfree_s((void *)a,sizeof(*a));
+	}
+}
+
+
+#if CONFIG_AP1000
+static void asyncd_info(void)
+{
+	printk("CID(%d) faults: total=%d  read=%d  write=%d  success=%d fail=%d err=%d\n",
+	       mpp_cid(),stats.faults, stats.read, stats.write, stats.success,
+	       stats.failure, stats.errors);
+}
+#endif
+
+
+/*
+ * The background async daemon.
+ * Started as a kernel thread from the init process.
+ */
+int asyncd(void *unused)
+{
+	current->session = 1;
+	current->pgrp = 1;
+	sprintf(current->comm, "asyncd");
+	current->blocked = ~0UL; /* block all signals */
+  
+	/* Give asyncd a realtime priority. */
+	current->policy = SCHED_FIFO;
+	current->priority = 32;  /* Fixme --- we need to standardise our
+				    namings for POSIX.4 realtime scheduling
+				    priorities.  */
+  
+	printk("Started asyncd\n");
+
+#if CONFIG_AP1000
+	bif_add_debug_key('a',asyncd_info,"stats on asyncd");
+#endif
+
+	while (1) {
+		unsigned flags;
+
+		save_flags(flags); cli();
+
+		while (!async_queue) {
+			current->signal = 0;
+			interruptible_sleep_on(&asyncd_wait);
+		}
+
+		restore_flags(flags);
+
+		run_async_queue();
+	}
+}
+
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/mm/extable.c linux/arch/sparc64/mm/extable.c
--- v2.1.18/linux/arch/sparc64/mm/extable.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/mm/extable.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,70 @@
+/* $Id: extable.c,v 1.1 1996/12/26 10:24:24 davem Exp $
+ * linux/arch/sparc/mm/extable.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static unsigned long
+search_one_table(const struct exception_table_entry *start,
+		 const struct exception_table_entry *last,
+		 unsigned long value, unsigned long *g2)
+{
+	const struct exception_table_entry *first = start;
+	const struct exception_table_entry *mid;
+	long diff = 0;
+        while (first <= last) {
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+                if (diff == 0) {
+                	if (!mid->fixup) {
+                		*g2 = 0;
+                		return (mid + 1)->fixup;
+                	} else
+	                        return mid->fixup;
+                } else if (diff < 0)
+                        first = mid+1;
+                else
+                        last = mid-1;
+        }
+        if (last->insn < value && !last->fixup && (last + 1)->insn > value) {
+        	*g2 = (value - last->insn)/4;
+        	return (last + 1)->fixup;
+        }
+        if (first > start && (first-1)->insn < value && !(first-1)->fixup && first->insn < value) {
+        	*g2 = (value - (first-1)->insn)/4;
+        	return first->fixup;
+        }
+        return 0;
+}
+
+unsigned long
+search_exception_table(unsigned long addr, unsigned long *g2)
+{
+	unsigned long ret;
+#ifdef CONFIG_MODULES
+	struct module *mp;
+#endif
+
+	/* Search the kernel's table first.  */
+	ret = search_one_table(__start___ex_table,
+			       __stop___ex_table-1, addr, g2);
+	if (ret)
+		return ret;
+
+#ifdef CONFIG_MODULES
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->exceptinfo.start != NULL) {
+			ret = search_one_table(mp->exceptinfo.start,
+				mp->exceptinfo.stop-1, addr, g2);
+			if (ret)
+				return ret;
+		}
+	}
+#endif
+	return 0;
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/mm/fault.c linux/arch/sparc64/mm/fault.c
--- v2.1.18/linux/arch/sparc64/mm/fault.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/mm/fault.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,196 @@
+/* $Id: fault.c,v 1.2 1996/12/26 18:03:04 davem Exp $
+ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
+
+extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
+extern int prom_node_root;
+
+/* Nice, simple, prom library does all the sweating for us. ;) */
+unsigned int prom_probe_memory (void)
+{
+	register struct linux_mlist_v0 *mlist;
+	register unsigned int bytes, base_paddr, tally;
+	register int i;
+
+	i = 0;
+	mlist= *prom_meminfo()->v0_available;
+	bytes = tally = mlist->num_bytes;
+	base_paddr = (unsigned int) mlist->start_adr;
+  
+	sp_banks[0].base_addr = base_paddr;
+	sp_banks[0].num_bytes = bytes;
+
+	while (mlist->theres_more != (void *) 0){
+		i++;
+		mlist = mlist->theres_more;
+		bytes = mlist->num_bytes;
+		tally += bytes;
+		if (i >= SPARC_PHYS_BANKS-1) {
+			printk ("The machine has more banks than "
+				"this kernel can support\n"
+				"Increase the SPARC_PHYS_BANKS "
+				"setting (currently %d)\n",
+				SPARC_PHYS_BANKS);
+			i = SPARC_PHYS_BANKS-1;
+			break;
+		}
+    
+		sp_banks[i].base_addr = (unsigned int) mlist->start_adr;
+		sp_banks[i].num_bytes = mlist->num_bytes;
+	}
+
+	i++;
+	sp_banks[i].base_addr = 0xdeadbeef;
+	sp_banks[i].num_bytes = 0;
+
+	/* Now mask all bank sizes on a page boundary, it is all we can
+	 * use anyways.
+	 */
+	for(i=0; sp_banks[i].num_bytes != 0; i++)
+		sp_banks[i].num_bytes &= PAGE_MASK;
+
+	return tally;
+}
+
+/* Traverse the memory lists in the prom to see how much physical we
+ * have.
+ */
+unsigned int
+probe_memory(void)
+{
+	unsigned int total;
+
+	total = prom_probe_memory();
+
+	/* Oh man, much nicer, keep the dirt in promlib. */
+	return total;
+}
+
+asmlinkage void do_sparc64_fault(struct pt_regs *regs, int text_fault, int write,
+				 unsigned long address)
+{
+	struct vm_area_struct *vma;
+	struct task_struct *tsk = current;
+	struct mm_struct *mm = tsk->mm;
+	unsigned int fixup;
+	unsigned long g2;
+	int from_user = !(regs->tstate & TSTATE_PRIV);
+
+	down(&mm->mmap_sem);
+	vma = find_vma(mm, address);
+	if(!vma)
+		goto bad_area;
+	if(vma->vm_start <= address)
+		goto good_area;
+	if(!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+	if(expand_stack(vma, address))
+		goto bad_area;
+	/*
+	 * Ok, we have a good vm_area for this memory access, so
+	 * we can handle it..
+	 */
+good_area:
+	if(write) {
+		if(!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	} else {
+		/* Allow reads even for write-only mappings */
+		if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
+			goto bad_area;
+	}
+	handle_mm_fault(vma, address, write);
+	up(&mm->mmap_sem);
+	return;
+
+	vma = find_vma(mm, address);
+	if(!vma)
+		goto bad_area;
+	if(vma->vm_start <= address)
+		goto good_area;
+	if(!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+	if(expand_stack(vma, address))
+		goto bad_area;
+	/*
+	 * Ok, we have a good vm_area for this memory access, so
+	 * we can handle it..
+	 */
+good_area:
+	if(write) {
+		if(!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	} else {
+		/* Allow reads even for write-only mappings */
+		if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
+			goto bad_area;
+	}
+	handle_mm_fault(vma, address, write);
+	up(&mm->mmap_sem);
+	return;
+	/*
+	 * Something tried to access memory that isn't in our memory map..
+	 * Fix it, but check if it's kernel or user first..
+	 */
+bad_area:
+	up(&mm->mmap_sem);
+	/* Is this in ex_table? */
+	
+	g2 = regs->u_regs[UREG_G2];
+	if (!from_user && (fixup = search_exception_table (regs->pc, &g2))) {
+		printk("Exception: PC<%08lx> faddr<%08lx>\n", regs->pc, address);
+		printk("EX_TABLE: insn<%08lx> fixup<%08x> g2<%08lx>\n",
+			regs->pc, fixup, g2);
+		regs->pc = fixup;
+		regs->npc = regs->pc + 4;
+		regs->u_regs[UREG_G2] = g2;
+		return;
+	}
+	/* Did we have an exception handler installed? */
+	if(current->tss.ex.count == 1) {
+		if(from_user) {
+			printk("Yieee, exception signalled from user mode.\n");
+		} else {
+			/* Set pc to %g1, set %g1 to -EFAULT and %g2 to
+			 * the faulting address so we can cleanup.
+			 */
+			printk("Exception: PC<%08lx> faddr<%08lx>\n", regs->pc, address);
+			printk("EX: count<%d> pc<%08lx> expc<%08lx> address<%08lx>\n",
+			       (int) current->tss.ex.count, current->tss.ex.pc,
+			       current->tss.ex.expc, current->tss.ex.address);
+			current->tss.ex.count = 0;
+			regs->pc = current->tss.ex.expc;
+			regs->npc = regs->pc + 4;
+			regs->u_regs[UREG_G1] = -EFAULT;
+			regs->u_regs[UREG_G2] = address - current->tss.ex.address;
+			regs->u_regs[UREG_G3] = current->tss.ex.pc;
+			return;
+		}
+	}
+	if(from_user) {
+#if 0
+		printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n",
+		       tsk->comm, tsk->pid, address, regs->pc);
+#endif
+		tsk->tss.sig_address = address;
+		tsk->tss.sig_desc = SUBSIG_NOMAPPING;
+		send_sig(SIGSEGV, tsk, 1);
+		return;
+	}
+	if((unsigned long) address < PAGE_SIZE) {
+		printk(KERN_ALERT "Unable to handle kernel NULL "
+		       "pointer dereference");
+	} else {
+		printk(KERN_ALERT "Unable to handle kernel paging request "
+		       "at virtual address %08lx\n", address);
+	}
+	printk(KERN_ALERT "tsk->mm->context = %08lx\n",
+	       (unsigned long) tsk->mm->context);
+	printk(KERN_ALERT "tsk->mm->pgd = %08lx\n",
+	       (unsigned long) tsk->mm->pgd);
+	die_if_kernel("Oops", regs);
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/mm/generic.c linux/arch/sparc64/mm/generic.c
--- v2.1.18/linux/arch/sparc64/mm/generic.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/mm/generic.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,124 @@
+/* $Id: generic.c,v 1.1 1996/12/26 10:24:23 davem Exp $
+ * generic.c: Generic Sparc mm routines that are not dependent upon
+ *            MMU type but are Sparc specific.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+
+/* Allocate a block of RAM which is aligned to its size.
+ * This procedure can be used until the call to mem_init().
+ */
+void *sparc_init_alloc(unsigned long *kbrk, unsigned long size)
+{
+        unsigned long mask = size - 1;
+        unsigned long ret;
+
+        if(!size)
+                return 0x0;
+        if(size & mask) {
+                prom_printf("panic: sparc_init_alloc botch\n");
+                prom_halt();
+        }
+        ret = (*kbrk + mask) & ~mask;
+        *kbrk = ret + size;
+        memset((void*) ret, 0, size);
+        return (void*) ret;
+}
+
+static inline void forget_pte(pte_t page)
+{
+	if (pte_none(page))
+		return;
+	if (pte_present(page)) {
+		unsigned long addr = pte_page(page);
+		if (MAP_NR(addr) >= max_mapnr || PageReserved(mem_map+MAP_NR(addr)))
+			return;
+		free_page(addr);
+		if (current->mm->rss <= 0)
+			return;
+		current->mm->rss--;
+		return;
+	}
+	swap_free(pte_val(page));
+}
+
+/* Remap IO memory, the same way as remap_page_range(), but use
+ * the obio memory space.
+ *
+ * They use a pgprot that sets PAGE_IO and does not check the
+ * mem_map table as this is independent of normal memory.
+ */
+static inline void io_remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
+	unsigned long offset, pgprot_t prot, int space)
+{
+	unsigned long end;
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	do {
+		pte_t oldpage = *pte;
+		pte_clear(pte);
+		set_pte(pte, mk_pte_io(offset, prot, space));
+		forget_pte(oldpage);
+		address += PAGE_SIZE;
+		offset += PAGE_SIZE;
+		pte++;
+	} while (address < end);
+}
+
+static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigned long size,
+	unsigned long offset, pgprot_t prot, int space)
+{
+	unsigned long end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	offset -= address;
+	do {
+		pte_t * pte = pte_alloc(pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		io_remap_pte_range(pte, address, end - address, address + offset, prot, space);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address < end);
+	return 0;
+}
+
+int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space)
+{
+	int error = 0;
+	pgd_t * dir;
+	unsigned long beg = from;
+	unsigned long end = from + size;
+
+	prot = __pgprot(pg_iobits);
+	offset -= from;
+	dir = pgd_offset(current->mm, from);
+	flush_cache_range(current->mm, beg, end);
+	while (from < end) {
+		pmd_t *pmd = pmd_alloc(dir, from);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		error = io_remap_pmd_range(pmd, from, end - from, offset + from, prot, space);
+		if (error)
+			break;
+		from = (from + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	}
+	flush_tlb_range(current->mm, beg, end);
+	return error;
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- v2.1.18/linux/arch/sparc64/mm/init.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/mm/init.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,219 @@
+/*  $Id: init.c,v 1.1 1996/12/26 10:24:23 davem Exp $
+ *  arch/sparc64/mm/init.c
+ *
+ *  Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+extern void show_net_buffers(void);
+
+struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving an inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+pte_t *__bad_pagetable(void)
+{
+	memset((void *) EMPTY_PGT, 0, PAGE_SIZE);
+	return (pte_t *) EMPTY_PGT;
+}
+
+pte_t __bad_page(void)
+{
+	memset((void *) EMPTY_PGE, 0, PAGE_SIZE);
+	return pte_mkdirty(mk_pte((unsigned long) EMPTY_PGE, PAGE_SHARED));
+}
+
+void show_mem(void)
+{
+	int i,free = 0,total = 0,reserved = 0;
+	int shared = 0;
+
+	printk("\nMem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+	i = max_mapnr;
+	while (i-- > 0) {
+		total++;
+		if (PageReserved(mem_map + i))
+			reserved++;
+		else if (!mem_map[i].count)
+			free++;
+		else
+			shared += mem_map[i].count-1;
+	}
+	printk("%d pages of RAM\n",total);
+	printk("%d free pages\n",free);
+	printk("%d reserved pages\n",reserved);
+	printk("%d pages shared\n",shared);
+	show_buffers();
+#ifdef CONFIG_NET
+	show_net_buffers();
+#endif
+}
+
+__initfunc(unsigned long sparc_context_init(unsigned long start_mem, int numctx))
+{
+	int ctx;
+
+	ctx_list_pool = (struct ctx_list *) start_mem;
+	start_mem += (numctx * sizeof(struct ctx_list));
+	for(ctx = 0; ctx < numctx; ctx++) {
+		struct ctx_list *clist;
+
+		clist = (ctx_list_pool + ctx);
+		clist->ctx_number = ctx;
+		clist->ctx_mm = 0;
+	}
+	ctx_free.next = ctx_free.prev = &ctx_free;
+	ctx_used.next = ctx_used.prev = &ctx_used;
+	for(ctx = 0; ctx < numctx; ctx++)
+		add_to_free_ctxlist(ctx_list_pool + ctx);
+	return start_mem;
+}
+
+/* paging_init() sets up the page tables */
+
+__initfunc(unsigned long 
+paging_init(unsigned long start_mem, unsigned long end_mem))
+{
+}
+
+extern int min_free_pages;
+extern int free_pages_low;
+extern int free_pages_high;
+
+__initfunc(static void taint_real_pages(unsigned long start_mem, unsigned long end_mem))
+{
+	unsigned long addr, tmp2 = 0;
+
+	for(addr = PAGE_OFFSET; addr < end_mem; addr += PAGE_SIZE) {
+		if(addr >= KERNBASE && addr < start_mem)
+			addr = start_mem;
+		for(tmp2=0; sp_banks[tmp2].num_bytes != 0; tmp2++) {
+			unsigned long phys_addr = (addr - PAGE_OFFSET);
+			unsigned long base = sp_banks[tmp2].base_addr;
+			unsigned long limit = base + sp_banks[tmp2].num_bytes;
+
+			if((phys_addr >= base) && (phys_addr < limit) &&
+			   ((phys_addr + PAGE_SIZE) < limit))
+				mem_map[MAP_NR(addr)].flags &= ~(1<<PG_reserved);
+		}
+	}
+}
+
+__initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
+{
+	int codepages = 0;
+	int datapages = 0;
+	unsigned long tmp2, addr;
+	extern char etext;
+
+	/* Saves us work later. */
+	memset((void *) ZERO_PAGE, 0, PAGE_SIZE);
+
+	end_mem &= PAGE_MASK;
+	max_mapnr = MAP_NR(end_mem);
+	high_memory = (void *) end_mem;
+
+	start_mem = PAGE_ALIGN(start_mem);
+	num_physpages = (start_mem - KERNBASE) >> PAGE_SHIFT;
+
+	addr = KERNBASE;
+	while(addr < start_mem) {
+#ifdef CONFIG_BLK_DEV_INITRD
+		if (initrd_below_start_ok && addr >= initrd_start && addr < initrd_end)
+			mem_map[MAP_NR(addr)].flags &= ~(1<<PG_reserved);
+		else
+#endif	
+			mem_map[MAP_NR(addr)].flags |= (1<<PG_reserved);
+		addr += PAGE_SIZE;
+	}
+
+	taint_real_pages(start_mem, end_mem);
+	for (addr = PAGE_OFFSET; addr < end_mem; addr += PAGE_SIZE) {
+		if(PageReserved(mem_map + MAP_NR(addr))) {
+			if ((addr < (unsigned long) &etext) && (addr >= KERNBASE))
+				codepages++;
+			else if((addr < start_mem) && (addr >= KERNBASE))
+				datapages++;
+			continue;
+		}
+		mem_map[MAP_NR(addr)].count = 1;
+		num_physpages++;
+#ifdef CONFIG_BLK_DEV_INITRD
+		if (!initrd_start ||
+		    (addr < initrd_start || addr >= initrd_end))
+#endif
+			free_page(addr);
+	}
+
+	tmp2 = nr_free_pages << PAGE_SHIFT;
+
+	printk("Memory: %luk available (%dk kernel code, %dk data) [%08lx,%08lx]\n",
+	       tmp2 >> 10,
+	       codepages << (PAGE_SHIFT-10),
+	       datapages << (PAGE_SHIFT-10), PAGE_OFFSET, end_mem);
+
+	min_free_pages = nr_free_pages >> 7;
+	if(min_free_pages < 16)
+		min_free_pages = 16;
+	free_pages_low = min_free_pages + (min_free_pages >> 1);
+	free_pages_high = min_free_pages + min_free_pages;
+}
+
+void free_initmem (void)
+{
+	extern int text_init_begin, text_init_end, data_init_begin, data_init_end;
+	unsigned long addr, addrend;
+	int savec, saved;
+	
+	addr = PAGE_ALIGN((unsigned long)(&text_init_begin));
+	addrend = ((unsigned long)(&text_init_end)) & PAGE_MASK;
+	for (savec = addrend - addr; addr < addrend; addr += PAGE_SIZE) {
+		mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
+		mem_map[MAP_NR(addr)].count = 1;
+		free_page(addr);
+	}
+	if (savec < 0) savec = 0;
+	addr = PAGE_ALIGN((unsigned long)(&data_init_begin));
+	addrend = ((unsigned long)(&data_init_end)) & PAGE_MASK;
+	for (saved = addrend - addr; addr < addrend; addr += PAGE_SIZE) {
+		mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
+		mem_map[MAP_NR(addr)].count = 1;
+		free_page(addr);
+	}
+	if (saved < 0) saved = 0;
+	printk ("Freeing unused kernel memory: %dk code, %dk data\n",
+        	savec >> 10, saved >> 10);
+}
+
+void si_meminfo(struct sysinfo *val)
+{
+	int i;
+
+	i = MAP_NR(high_memory);
+	val->totalram = 0;
+	val->sharedram = 0;
+	val->freeram = nr_free_pages << PAGE_SHIFT;
+	val->bufferram = buffermem;
+	while (i-- > 0)  {
+		if (PageReserved(mem_map + i))
+			continue;
+		val->totalram++;
+		if (!mem_map[i].count)
+			continue;
+		val->sharedram += mem_map[i].count-1;
+	}
+	val->totalram <<= PAGE_SHIFT;
+	val->sharedram <<= PAGE_SHIFT;
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/prom/Makefile linux/arch/sparc64/prom/Makefile
--- v2.1.18/linux/arch/sparc64/prom/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/prom/Makefile	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,23 @@
+# $Id: Makefile,v 1.1 1996/12/27 08:49:10 jj Exp $
+# Makefile for the Sun Boot PROM interface library under
+# Linux.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+OBJS  = bootstr.o devops.o init.o memory.o misc.o mp.o \
+        ranges.o tree.o console.o printf.o
+
+all: promlib.a
+
+promlib.a: $(OBJS)
+	$(AR) rcs promlib.a $(OBJS)
+	sync
+
+dep:
+	$(CPP) -M *.c > .depend
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/prom/bootstr.c linux/arch/sparc64/prom/bootstr.c
--- v2.1.18/linux/arch/sparc64/prom/bootstr.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/prom/bootstr.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,24 @@
+/* $Id: bootstr.c,v 1.1 1996/12/27 08:49:10 jj Exp $
+ * bootstr.c:  Boot string/argument acquisition from the PROM.
+ *
+ * Copyright(C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright(C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <asm/oplib.h>
+
+#define BARG_LEN  256
+static char barg_buf[BARG_LEN];
+static char fetched = 0;
+
+char *
+prom_getbootargs(void)
+{
+	/* This check saves us from a panic when bootfd patches args. */
+	if (fetched) return barg_buf;
+	prom_getstring(prom_finddevice ("/chosen"), "bootargs", barg_buf, BARG_LEN);
+	fetched = 1;
+	return barg_buf;
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/prom/console.c linux/arch/sparc64/prom/console.c
--- v2.1.18/linux/arch/sparc64/prom/console.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/prom/console.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,123 @@
+/* $Id: console.c,v 1.1 1996/12/27 08:49:11 jj Exp $
+ * console.c: Routines that deal with sending and receiving IO
+ *            to/from the current console device using the PROM.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+#include <asm/system.h>
+#include <linux/string.h>
+
+extern int prom_stdin, prom_stdout;
+
+/* Non blocking get character from console input device, returns -1
+ * if no input was taken.  This can be used for polling.
+ */
+__inline__ int
+prom_nbgetchar(void)
+{
+	char inc;
+
+	if ((*prom_command)("read", P1275_ARG(1,P1275_ARG_IN_BUF)|
+				    P1275_INOUT(3,1),
+				    prom_stdin, &inc, P1275_SIZE(1)) == 1)
+		return inc;
+	else
+		return -1;
+}
+
+/* Non blocking put character to console device, returns -1 if
+ * unsuccessful.
+ */
+__inline__ int
+prom_nbputchar(char c)
+{
+	char outc;
+	
+	outc = c;
+	if ((*prom_command)("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
+				     P1275_INOUT(3,1),
+				     prom_stdin, &inc, P1275_SIZE(1)) == 1)
+		return 0;
+	else
+		return -1;
+}
+
+/* Blocking version of get character routine above. */
+char
+prom_getchar(void)
+{
+	int character;
+	while((character = prom_nbgetchar()) == -1) ;
+	return (char) character;
+}
+
+/* Blocking version of put character routine above. */
+void
+prom_putchar(char c)
+{
+	while(prom_nbputchar(c) == -1) ;
+	return;
+}
+
+/* Query for input device type */
+enum prom_input_device
+prom_query_input_device()
+{
+	int st_p;
+	char propb[64];
+	char *p;
+
+	st_p = prom_inst2pkg(prom_stdin);
+	if(prom_node_has_property(st_p, "keyboard"))
+		return PROMDEV_IKBD;
+	prom_getproperty(st_p, "device_type", propb, sizeof(propb));
+	if(strncmp(propb, "serial", sizeof("serial")))
+		return PROMDEV_I_UNK;
+	/* FIXME: Is there any better way how to find out? */	
+	st_p = prom_finddevice ("/options");
+	prom_getproperty(st_p, "input-device", propb, sizeof(propb));
+	if (strncmp (propb, "tty", 3) || !propb[3] || propb[4])
+		return PROMDEV_I_UNK;
+	switch (propb[3]) {
+		case 'a': return PROMDEV_ITTYA;
+		case 'b': return PROMDEV_ITTYB;
+		default: return PROMDEV_I_UNK;
+	}
+}
+
+/* Query for output device type */
+
+enum prom_output_device
+prom_query_output_device()
+{
+	int st_p;
+	char propb[64];
+	char *p;
+	int propl;
+
+	st_p = prom_inst2pkg(prom_stdout);
+	propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
+	if (propl >= 0 && propl == sizeof("display") &&
+	    strncmp("display", propb, sizeof("display")) == 0)
+		return PROMDEV_OSCREEN;
+	if(strncmp("serial", propb, sizeof("serial")))
+		return PROMDEV_O_UNK;
+	/* FIXME: Is there any better way how to find out? */	
+	st_p = prom_finddevice ("/options");
+	prom_getproperty(st_p, "output-device", propb, sizeof(propb));
+	if (strncmp (propb, "tty", 3) || !propb[3] || propb[4])
+		return PROMDEV_O_UNK;
+	switch (propb[3]) {
+		case 'a': return PROMDEV_OTTYA;
+		case 'b': return PROMDEV_OTTYB;
+		default: return PROMDEV_O_UNK;
+	}
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/prom/devops.c linux/arch/sparc64/prom/devops.c
--- v2.1.18/linux/arch/sparc64/prom/devops.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/prom/devops.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,41 @@
+/* $Id: devops.c,v 1.1 1996/12/27 08:49:11 jj Exp $
+ * devops.c:  Device operations using the PROM.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+/* Open the device described by the string 'dstr'.  Returns the handle
+ * to that device used for subsequent operations on that device.
+ * Returns -1 on failure.
+ */
+int
+prom_devopen(char *dstr)
+{
+	return (*prom_command)("open", P1275_ARG(0,P1275_ARG_IN_STRING)|
+				       P1275_INOUT(1,1),
+				       dstr);
+}
+
+/* Close the device described by device handle 'dhandle'. */
+int
+prom_devclose(int dhandle)
+{
+	(*prom_command)("close", P1275_INOUT(1,0), dhandle);
+	return 0;
+}
+
+/* Seek to specified location described by 'seekhi' and 'seeklo'
+ * for device 'dhandle'.
+ */
+void
+prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
+{
+	(*prom_command)("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo);
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/prom/init.c linux/arch/sparc64/prom/init.c
--- v2.1.18/linux/arch/sparc64/prom/init.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/prom/init.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,77 @@
+/* $Id: init.c,v 1.1 1996/12/27 08:49:11 jj Exp $
+ * init.c:  Initialize internal variables used by the PROM
+ *          library functions.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+enum prom_major_version prom_vers;
+unsigned int prom_rev, prom_prev;
+
+/* The root node of the prom device tree. */
+int prom_root_node;
+int prom_stdin, prom_stdout;
+(long)(*prom_command)(char *, long, ...);
+
+/* You must call prom_init() before you attempt to use any of the
+ * routines in the prom library.  It returns 0 on success, 1 on
+ * failure.  It gets passed the pointer to the PROM vector.
+ */
+
+extern void prom_meminit(void);
+extern void prom_ranges_init(void);
+extern void prom_cif_init(void *, void *);
+
+__initfunc(void prom_init(void *cif_handler, void *cif_stack))
+{
+	char buffer[80];
+	int node;
+	
+	prom_vers = PROM_P1275;
+	
+	prom_cif_init(cif_handler, cif_stack);
+
+	prom_root_node = prom_getsibling(0);
+	if((prom_root_node == 0) || (prom_root_node == -1))
+		prom_halt();
+
+	node = prom_finddevice("/chosen");
+	if (!node || node == -1)
+		prom_halt();
+		
+	prom_stdin = prom_getint (node, "stdin");
+	prom_stdout = prom_getint (node, "stdout");
+
+	node = prom_finddevice("/openprom");
+	if (!node || node == -1)
+		prom_halt();
+		
+	prom_getstring (openprom_node, "version", buffer, sizeof (buffer));
+	if (strncmp (buffer, "OPB ", 4) || buffer[5] != '.' || buffer[7] != '.') {
+		prom_printf ("Strange OPB version.\n");
+		prom_halt ();
+	}
+	/* Version field is expected to be 'OPB x.y.z date...' */
+	
+	prom_rev = buffer[6] - '0';
+	prom_prev = ((buffer[4] - '0') << 16) | 
+		    ((buffer[6] - '0') << 8) |
+		    (buffer[8] - '0');
+		    
+	prom_meminit();
+
+	prom_ranges_init();
+
+	printk("PROMLIB: Sun IEEE Boot Prom %s\n",
+	       buffer + 4);
+
+	/* Initialization successful. */
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/prom/k1275d.c linux/arch/sparc64/prom/k1275d.c
--- v2.1.18/linux/arch/sparc64/prom/k1275d.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/prom/k1275d.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,123 @@
+/* $Id: k1275d.c,v 1.1 1996/12/27 08:49:12 jj Exp $
+ * k1275d.c: Sun IEEE 1275 PROM kernel daemon
+ *
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+#define p1275sect __attribute__ ((__section__ (".p1275")))
+
+static void prom_doit (void) p1275sect;
+
+static void prom_doit (void)
+{
+	/* FIXME: The PROM stack is grossly misaligned.
+	 * It needs some special way of handling spills/fills.
+	 * Either using %otherwin or doing flushw; wrpr somevalue, %wstate
+	 * should be done here to make difference between PROM stack
+	 * saving (32bit, misaligned stack) and kernel fill/spill).
+	 */
+	__asm__ __volatile__ ("
+	save	%%sp, -0xc0, %%sp;
+	mov	%%sp, %%l1;
+	mov	%0, %%sp;
+	call	%1;
+	 mov	%0, %%o0;
+	mov	%%l1, %%sp;
+	restore;
+	" : : "r" (prom_cif_stack), "r" (prom_cif_handler));
+}
+
+static void (*prom_cif_handler)(long *) p1275sect;
+static void prom_cif_stack;
+static void (*prom_do_it)(void);
+static long prom_args [23] p1275sect;
+static char prom_buffer [4096] p1275sect;
+
+long prom_handle_command(char *service, long fmt, ...)
+{
+	char *p = prom_buffer;
+	unsigned long flags;
+	int nargs, nrets, i;
+	va_list list;
+	long attrs, x;
+	
+	save_and_cli(flags);
+	prom_args[0] = p;				/* service */
+	strcpy (p, function);
+	p = strchr (p, 0) + 1;
+	prom_args[1] = nargs = (fmt & 0x0f);		/* nargs */
+	prom_args[2] = nrets = ((fmt & 0xf0) >> 4); 	/* nrets */
+	attrs = (fmt & (~0xff));
+	va_start(list, fmt);
+	for (i = 0; i < nargs; i++, attrs >>= 3) {
+		switch (attrs & 0x7) {
+		case P1275_ARG_NUMBER:
+			prom_args[i + 3] = va_arg(list, long); break;
+		case P1275_ARG_IN_STRING:
+			strcpy (p, va_arg(list, char *));
+			prom_args[i + 3] = p;
+			p = strchr (p, 0) + 1;
+			break;
+		case P1275_ARG_OUT_BUF:
+			va_arg(list, char *);
+			prom_args[i + 3] = p;
+			x = va_arg(list, long);
+			i++; attrs >>= 3;
+			p += (int)x;
+			prom_args[i + 3] = x;
+			break;
+		case P1275_ARG_OUT_32B:
+			va_arg(list, char *);
+			prom_args[i + 3] = p;
+			p += 32;
+			break;
+		case P1275_ARG_IN_FUNCTION:
+			/* FIXME: This should make a function in our <4G
+			 * section, which will call the argument,
+			 * so that PROM can call it.
+			 */
+			prom_args[i + 3] = va_arg(list, long); break;
+		}
+	}
+	va_end(list);
+	(*prom_do_it)();
+	attrs = fmt & (~0xff);
+	va_start(list, fmt);
+	for (i = 0; i < nargs; i++, attrs >>= 3) {
+		switch (attrs & 0x7) {
+		case P1275_ARG_NUMBER:
+		case P1275_ARG_IN_STRING:
+		case P1275_ARG_IN_FUNCTION:
+			break;
+		case P1275_ARG_OUT_BUF:
+			p = va_arg(list, char *);
+			x = va_arg(list, long);
+			memcpy (p, (char *)prom_args[i + 3], (int)x);
+			i++; attrs >>= 3;
+			break;
+		case P1275_ARG_OUT_32B:
+			p = va_arg(list, char *);
+			memcpy (p, (char *)prom_args[i + 3], 32);
+			break;
+		}
+	}
+	va_end(list);
+	x = prom_args [nargs + 3];
+	restore_flags(flags);
+	return x;
+}
+
+void prom_cif_init(void *cif_handler, void *cif_stack)
+{
+	prom_cif_handler = (void (*)(long *))cif_handler;
+	prom_cif_stack = cif_stack;
+	prom_command = prom_handle_command;
+        prom_do_it = prom_doit;
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/prom/misc.c linux/arch/sparc64/prom/misc.c
--- v2.1.18/linux/arch/sparc64/prom/misc.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/prom/misc.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,124 @@
+/* $Id: misc.c,v 1.1 1996/12/27 08:49:12 jj Exp $
+ * misc.c:  Miscellaneous prom functions that don't belong
+ *          anywhere else.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+/* Reset and reboot the machine with the command 'bcommand'. */
+void
+prom_reboot(char *bcommand)
+{
+	(*prom_command)("boot", P1275_ARG(0,P1275_ARG_IN_STRING)|
+				P1275_INOUT(1,0), bcommand);
+}
+
+/* Forth evaluate the expression contained in 'fstring'. */
+void
+prom_feval(char *fstring)
+{
+	if(!fstring || fstring[0] == 0)
+		return;
+	(*prom_command)("interpret", P1275_ARG(0,P1275_ARG_IN_STRING)|
+				     P1275_INOUT(1,1), fstring);
+}
+
+/* We want to do this more nicely some day. */
+#ifdef CONFIG_SUN_CONSOLE
+extern void console_restore_palette(void);
+extern void set_palette(void);
+extern int serial_console;
+#endif
+
+/* Drop into the prom, with the chance to continue with the 'go'
+ * prom command.
+ */
+void
+prom_cmdline(void)
+{
+	extern void kernel_enter_debugger(void);
+	extern void install_obp_ticker(void);
+	extern void install_linux_ticker(void);
+	unsigned long flags;
+    
+	kernel_enter_debugger();
+#ifdef CONFIG_SUN_CONSOLE
+	if(!serial_console)
+		console_restore_palette ();
+#endif
+	install_obp_ticker();
+	save_flags(flags); cli();
+	(*prom_command)("enter", P1275_INOUT(0,0));
+	restore_flags(flags);
+	install_linux_ticker();
+#ifdef CONFIG_SUN_CONSOLE
+	if(!serial_console)
+		set_palette ();
+#endif
+}
+
+/* Drop into the prom, but completely terminate the program.
+ * No chance of continuing.
+ */
+void
+prom_halt(void)
+{
+	(*prom_command)("exit", P1275_INOUT(0,0));
+}
+
+typedef void (*sfunc_t)(void);
+
+/* Set prom sync handler to call function 'funcp'. */
+void
+prom_setsync(sfunc_t funcp)
+{
+	if(!funcp) return;
+	(*prom_command)("set-callback", P1275_ARG(0,P1275_IN_FUNCTION)|
+					P1275_INOUT(1,1), funcp);
+}
+
+/* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
+ * format type.  'num_bytes' is the number of bytes that your idbuf
+ * has space for.  Returns 0xff on error.
+ */
+unsigned char
+prom_get_idprom(char *idbuf, int num_bytes)
+{
+	int len;
+
+	len = prom_getproplen(prom_root_node, "idprom");
+	if((len>num_bytes) || (len==-1)) return 0xff;
+	if(!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes))
+		return idbuf[0];
+
+	return 0xff;
+}
+
+/* Get the major prom version number. */
+int
+prom_version(void)
+{
+	return PROM_P1275;
+}
+
+/* Get the prom plugin-revision. */
+int
+prom_getrev(void)
+{
+	return prom_rev;
+}
+
+/* Get the prom firmware print revision. */
+int
+prom_getprev(void)
+{
+	return prom_prev;
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/prom/printf.c linux/arch/sparc64/prom/printf.c
--- v2.1.18/linux/arch/sparc64/prom/printf.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/prom/printf.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,39 @@
+/* $Id: printf.c,v 1.1 1996/12/27 08:49:13 jj Exp $
+ * printf.c:  Internal prom library printf facility.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* This routine is internal to the prom library, no one else should know
+ * about or use it!  It's simple and smelly anyway....
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+static char ppbuf[1024];
+
+void
+prom_printf(char *fmt, ...)
+{
+	va_list args;
+	char ch, *bptr;
+	int i;
+
+	va_start(args, fmt);
+	i = vsprintf(ppbuf, fmt, args);
+
+	bptr = ppbuf;
+
+	while((ch = *(bptr++)) != 0) {
+		if(ch == '\n')
+			prom_putchar('\r');
+
+		prom_putchar(ch);
+	}
+	va_end(args);
+	return;
+}
diff -u --recursive --new-file v2.1.18/linux/arch/sparc64/prom/tree.c linux/arch/sparc64/prom/tree.c
--- v2.1.18/linux/arch/sparc64/prom/tree.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/sparc64/prom/tree.c	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,292 @@
+/* $Id: tree.c,v 1.1 1996/12/27 08:49:13 jj Exp $
+ * tree.c: Basic device tree traversal/scanning for the Linux
+ *         prom library.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+/* Return the child of node 'node' or zero if no this node has no
+ * direct descendent.
+ */
+__inline__ int
+prom_getchild(int node)
+{
+	long cnode;
+
+	if(node == -1) return 0;
+	cnode = (*prom_command)("child", P1275_INOUT(1, 1), node);
+	if(cnode == -1) return 0;
+	return (int)cnode;
+}
+
+/* Return the next sibling of node 'node' or zero if no more siblings
+ * at this level of depth in the tree.
+ */
+__inline__ int
+prom_getsibling(int node)
+{
+	long sibnode;
+
+	if(node == -1) return 0;
+	sibnode = (*prom_command)("peer", P1275_INOUT(1, 1), node);
+	if(cnode == -1) return 0;
+	return (int)sibnode;
+}
+
+/* Return the length in bytes of property 'prop' at node 'node'.
+ * Return -1 on error.
+ */
+__inline__ int
+prom_getproplen(int node, char *prop)
+{
+	if((!node) || (!prop)) return -1;
+	return (*prom_command)("getproplen", 
+			       P1275_ARG(1,P1275_ARG_IN_STRING)|
+			       P1275_INOUT(2, 1), 
+			       node, prop);
+}
+
+/* Acquire a property 'prop' at node 'node' and place it in
+ * 'buffer' which has a size of 'bufsize'.  If the acquisition
+ * was successful the length will be returned, else -1 is returned.
+ */
+__inline__ int
+prom_getproperty(int node, char *prop, char *buffer, int bufsize)
+{
+	int plen;
+
+	plen = prom_getproplen(node, prop);
+	if((plen > bufsize) || (plen == 0) || (plen == -1))
+		return -1;
+	else {
+		/* Ok, things seem all right. */
+		return (*prom_command)("getprop", 
+				       P1275_ARG(1,P1275_ARG_IN_STRING)|
+				       P1275_ARG(2,P1275_ARG_OUT_BUF)|
+				       P1275_INOUT(4, 1), 
+				       node, prop, buffer, P1275_SIZE(plen));
+	}
+}
+
+/* Acquire an integer property and return its value.  Returns -1
+ * on failure.
+ */
+__inline__ int
+prom_getint(int node, char *prop)
+{
+	int intprop;
+
+	if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
+		return intprop;
+
+	return -1;
+}
+
+/* Acquire an integer property, upon error return the passed default
+ * integer.
+ */
+
+int
+prom_getintdefault(int node, char *property, int deflt)
+{
+	int retval;
+
+	retval = prom_getint(node, property);
+	if(retval == -1) return deflt;
+
+	return retval;
+}
+
+/* Acquire a boolean property, 1=TRUE 0=FALSE. */
+int
+prom_getbool(int node, char *prop)
+{
+	int retval;
+
+	retval = prom_getproplen(node, prop);
+	if(retval == -1) return 0;
+	return 1;
+}
+
+/* Acquire a property whose value is a string, returns a null
+ * string on error.  The char pointer is the user supplied string
+ * buffer.
+ */
+void
+prom_getstring(int node, char *prop, char *user_buf, int ubuf_size)
+{
+	int len;
+
+	len = prom_getproperty(node, prop, user_buf, ubuf_size);
+	if(len != -1) return;
+	user_buf[0] = 0;
+	return;
+}
+
+
+/* Does the device at node 'node' have name 'name'?
+ * YES = 1   NO = 0
+ */
+int
+prom_nodematch(int node, char *name)
+{
+	char namebuf[128];
+	prom_getproperty(node, "name", namebuf, sizeof(namebuf));
+	if(strcmp(namebuf, name) == 0) return 1;
+	return 0;
+}
+
+/* Search siblings at 'node_start' for a node with name
+ * 'nodename'.  Return node if successful, zero if not.
+ */
+int
+prom_searchsiblings(int node_start, char *nodename)
+{
+
+	int thisnode, error;
+	char promlib_buf[128];
+
+	for(thisnode = node_start; thisnode;
+	    thisnode=prom_getsibling(thisnode)) {
+		error = prom_getproperty(thisnode, "name", promlib_buf,
+					 sizeof(promlib_buf));
+		/* Should this ever happen? */
+		if(error == -1) continue;
+		if(strcmp(nodename, promlib_buf)==0) return thisnode;
+	}
+
+	return 0;
+}
+
+/* Gets name in the {name@x,yyyyy|name (if no reg)} form */
+int 
+prom_getname (int node, char *buffer, int len)
+{
+	int i;
+	struct linux_prom_registers reg[PROMREG_MAX];
+	
+	i = prom_getproperty (node, "name", buffer, len);
+	if (i <= 0) return -1;
+	buffer [i] = 0;
+	len -= i;
+	i = prom_getproperty (node, "reg", (char *)reg, sizeof (reg));
+	if (i <= 0) return 0;
+	if (len < 11) return -1;
+	buffer = strchr (buffer, 0);
+	sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr);
+	return 0;
+}
+
+/* Return the first property type for node 'node'.
+ * buffer should be at least 32B in length
+ */
+__inline__ char *
+prom_firstprop(int node, char *buffer)
+{
+	if(node == -1) return "";
+	*buffer = 0;
+	(*prom_command)("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)|
+				    P1275_INOUT(3, 0), 
+				    node, (char *) 0x0, buffer);
+	return buffer;
+}
+
+/* Return the property type string after property type 'oprop'
+ * at node 'node' .  Returns NULL string if no more
+ * property types for this node.
+ */
+__inline__ char *
+prom_nextprop(int node, char *oprop, char *buffer)
+{
+	char buf[32];
+
+	if(node == -1) return "";
+	*buffer = 0;
+	(*prom_command)("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
+				    P1275_ARG(2,P1275_ARG_OUT_32B)|
+				    P1275_INOUT(3, 0), 
+				    node, oprop, (oprop == buffer) ? 
+				    buf : buffer);
+	if (oprop == buffer) strcpy (buffer, buf);
+	return buffer;
+}
+
+int
+prom_finddevice(char *name)
+{
+	if(!name) return 0;
+	*buffer = 0;
+	(*prom_command)("finddevice", P1275_ARG(0,P1275_ARG_IN_STRING)|
+				      P1275_INOUT(1, 1), 
+				      name);
+	return buffer;
+}
+
+int
+prom_node_has_property(int node, char *prop)
+{
+	char buf[32];
+	char *current_property = buf;
+	
+	*buf = 0;
+	do {
+		current_property = prom_nextprop(node, current_property, buf);
+		if(!strcmp(current_property, prop))
+			return 1;
+	} while (*current_property);
+	return 0;
+}
+
+/* Set property 'pname' at node 'node' to value 'value' which has a length
+ * of 'size' bytes.  Return the number of bytes the prom accepted.
+ */
+int
+prom_setprop(int node, char *pname, char *value, int size)
+{
+	unsigned long flags;
+	int ret;
+
+	if(size == 0) return 0;
+	if((pname == 0) || (value == 0)) return 0;
+	
+	return (*prom_command)("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
+					  P1275_ARG(2,P1275_ARG_OUT_BUF)|
+					  P1275_INOUT(4, 1), 
+					  node, pname, value, P1275_SIZE(size));
+}
+
+__inline__ int
+prom_inst2pkg(int inst)
+{
+	int node;
+	
+	node = (*prom_command)("instance-to-package", P1275_INOUT(1, 1), inst);
+	if (node == -1) return 0;
+	return node;
+}
+
+/* Return 'node' assigned to a particular prom 'path'
+ * FIXME: Should work for v0 as well
+ */
+int
+prom_pathtoinode(char *path)
+{
+	int node, inst;
+	
+	inst = prom_devopen (path);
+	if (inst == -1) return 0;
+	node = prom_inst2pkg (inst);
+	prom_devclose (inst);
+	if (node == -1) return 0;
+	return node;
+}
diff -u --recursive --new-file v2.1.18/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.1.18/linux/drivers/block/genhd.c	Sun Nov 10 20:12:09 1996
+++ linux/drivers/block/genhd.c	Mon Dec 30 12:06:22 1996
@@ -37,10 +37,16 @@
  */
 #include <asm/unaligned.h>
 
-#define SYS_IND(p)	get_unaligned(&p->sys_ind)
-#define NR_SECTS(p)	get_unaligned(&p->nr_sects)
-#define START_SECT(p)	get_unaligned(&p->start_sect)
-
+#define SYS_IND(p)	(get_unaligned(&p->sys_ind))
+#define NR_SECTS(p)	({ __typeof__(p->nr_sects) __a =	\
+				get_unaligned(&p->nr_sects);	\
+				le32_to_cpu(__a); \
+			})
+
+#define START_SECT(p)	({ __typeof__(p->start_sect) __a =	\
+				get_unaligned(&p->start_sect);	\
+				le32_to_cpu(__a); \
+			})
 
 struct gendisk *gendisk_head = NULL;
 
@@ -115,6 +121,8 @@
  * only for the actual data partitions.
  */
 
+#define MSDOS_LABEL_MAGIC		0xAA55
+
 static void extended_partition(struct gendisk *hd, kdev_t dev)
 {
 	struct buffer_head *bh;
@@ -138,7 +146,7 @@
 	   */
 		bh->b_state = 0;
 
-		if (*(unsigned short *) (bh->b_data+510) != 0xAA55)
+		if (le16_to_cpu(*(unsigned short *) (bh->b_data+510)) != MSDOS_LABEL_MAGIC)
 			goto done;
 
 		p = (struct partition *) (0x1BE + bh->b_data);
@@ -263,7 +271,7 @@
 #ifdef CONFIG_BLK_DEV_IDE
 check_table:
 #endif
-	if (*(unsigned short *)  (0x1fe + data) != 0xAA55) {
+	if (le16_to_cpu(*(unsigned short *) (0x1fe + data)) != MSDOS_LABEL_MAGIC) {
 		brelse(bh);
 		return 0;
 	}
@@ -275,7 +283,7 @@
 		 * Look for various forms of IDE disk geometry translation
 		 */
 		extern int ide_xlate_1024(kdev_t, int, const char *);
-		unsigned int sig = *(unsigned short *)(data + 2);
+		unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2));
 		if (SYS_IND(p) == EZD_PARTITION) {
 			/*
 			 * The remainder of the disk must be accessed using
@@ -305,12 +313,10 @@
 				brelse(bh);
 				goto read_mbr;	/* start over with new MBR */
 			}
-		} else if (sig <= 0x1ae && *(unsigned short *)(data + sig) == 0x55AA
-			 && (1 & *(unsigned char *)(data + sig + 2)) ) 
-		{
-			/*
-			 * DM6 signature in MBR, courtesy of OnTrack
-			 */
+		} else if (sig <= 0x1ae &&
+			   le16_to_cpu(*(unsigned short *)(data + sig)) == 0x55AA &&
+			   (1 & *(unsigned char *)(data + sig + 2))) {
+			/* DM6 signature in MBR, courtesy of OnTrack */
 			(void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
 		} else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) {
 			/*
@@ -373,7 +379,7 @@
 	/*
 	 *  Check for old-style Disk Manager partition table
 	 */
-	if (*(unsigned short *) (data+0xfc) == 0x55AA) {
+	if (le16_to_cpu(*(unsigned short *) (data+0xfc)) == MSDOS_LABEL_MAGIC) {
 		p = (struct partition *) (0x1be + data);
 		for (i = 4 ; i < 16 ; i++, current_minor++) {
 			p--;
@@ -492,20 +498,8 @@
 		unsigned short csum;       /* Label xor'd checksum */
 	} * label;		
 	struct sun_partition *p;
-	int other_endian;
 	unsigned long spc;
 #define SUN_LABEL_MAGIC          0xDABE
-#define SUN_LABEL_MAGIC_SWAPPED  0xBEDA
-/* No need to optimize these macros since they are called only when reading
- * the partition table. This occurs only at each disk change. */
-#define SWAP16(x)  (other_endian ? (((__u16)(x) & 0xFF) << 8) \
-				 | (((__u16)(x) & 0xFF00) >> 8) \
-				 : (__u16)(x))
-#define SWAP32(x)  (other_endian ? (((__u32)(x) & 0xFF) << 24) \
-				 | (((__u32)(x) & 0xFF00) << 8) \
-				 | (((__u32)(x) & 0xFF0000) >> 8) \
-				 | (((__u32)(x) & 0xFF000000) >> 24) \
-				 : (__u32)(x))
 
 	if(!(bh = bread(dev, 0, 1024))) {
 		printk("Dev %s: unable to read partition table\n",
@@ -514,13 +508,12 @@
 	}
 	label = (struct sun_disklabel *) bh->b_data;
 	p = label->partitions;
-	if (label->magic != SUN_LABEL_MAGIC && label->magic != SUN_LABEL_MAGIC_SWAPPED) {
+	if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
 		printk("Dev %s Sun disklabel: bad magic %04x\n",
-		       kdevname(dev), label->magic);
+		       kdevname(dev), be16_to_cpu(label->magic));
 		brelse(bh);
 		return 0;
 	}
-	other_endian = (label->magic == SUN_LABEL_MAGIC_SWAPPED);
 	/* Look at the checksum */
 	ush = ((unsigned short *) (label+1)) - 1;
 	for(csum = 0; ush >= ((unsigned short *) label);)
@@ -532,22 +525,20 @@
 		return 0;
 	}
 	/* All Sun disks have 8 partition entries */
-	spc = SWAP16(label->ntrks) * SWAP16(label->nsect);
+	spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
 	for(i=0; i < 8; i++, p++) {
 		unsigned long st_sector;
 
 		/* We register all partitions, even if zero size, so that
 		 * the minor numbers end up ok as per SunOS interpretation.
 		 */
-		st_sector = first_sector + SWAP32(p->start_cylinder) * spc;
-		add_partition(hd, current_minor, st_sector, SWAP32(p->num_sectors));
+		st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc;
+		add_partition(hd, current_minor, st_sector, be32_to_cpu(p->num_sectors));
 		current_minor++;
 	}
 	printk("\n");
 	brelse(bh);
 	return 1;
-#undef SWAP16
-#undef SWAP32
 }
 
 #endif /* CONFIG_SUN_PARTITION */
diff -u --recursive --new-file v2.1.18/linux/drivers/char/tty_ioctl.c linux/drivers/char/tty_ioctl.c
--- v2.1.18/linux/drivers/char/tty_ioctl.c	Thu Dec 12 19:37:02 1996
+++ linux/drivers/char/tty_ioctl.c	Mon Dec 30 12:44:34 1996
@@ -157,20 +157,16 @@
 		return retval;
 
 	if (opt & TERMIOS_TERMIO) {
-		struct termio tmp_termio;
 		retval = verify_area(VERIFY_READ, (void *) arg, sizeof(struct termio));
 		if (retval)
 			return retval;
-		tmp_termios = *tty->termios;
-		copy_from_user(&tmp_termio, (struct termio *) arg,
-			      sizeof (struct termio));
-		trans_from_termio(&tmp_termio, &tmp_termios);
+		memcpy(&tmp_termios, tty->termios, sizeof(struct termios));
+		user_termio_to_kernel_termios(&tmp_termios, (struct termio *) arg);
 	} else {
 		retval = verify_area(VERIFY_READ, (void *) arg, sizeof(struct termios));
 		if (retval)
 			return retval;
-		copy_from_user(&tmp_termios, (struct termios *) arg,
-			      sizeof (struct termios));
+		user_termios_to_kernel_termios(&tmp_termios, (struct termios *) arg);
 	}
 
 	if ((opt & TERMIOS_FLUSH) && tty->ldisc.flush_buffer)
@@ -189,13 +185,11 @@
 static int get_termio(struct tty_struct * tty, struct termio * termio)
 {
 	int i;
-	struct termio tmp_termio;
 
 	i = verify_area(VERIFY_WRITE, termio, sizeof (struct termio));
 	if (i)
 		return i;
-	trans_to_termio(tty->termios, &tmp_termio);
-	copy_to_user(termio, &tmp_termio, sizeof (struct termio));
+	kernel_termios_to_user_termio(termio, tty->termios);
 	return 0;
 }
 
@@ -437,9 +431,8 @@
 					     sizeof (struct termios));
 			if (retval)
 				return retval;
-			copy_to_user((struct termios *) arg,
-				    real_tty->termios,
-				    sizeof (struct termios));
+			kernel_termios_to_user_termios((struct termios *)arg,
+						       real_tty->termios);
 			return 0;
 		case TCSETSF:
 			opt |= TERMIOS_FLUSH;
@@ -531,9 +524,8 @@
 					     sizeof (struct termios));
 			if (retval)
 				return retval;
-			copy_to_user((struct termios *) arg,
-				    real_tty->termios_locked,
-				    sizeof (struct termios));
+			kernel_termios_to_user_termios((struct termios *)arg,
+						       real_tty->termios_locked);
 			return 0;
 		case TIOCSLCKTRMIOS:
 			if (!suser())
@@ -542,9 +534,8 @@
 					     sizeof (struct termios));
 			if (retval)
 				return retval;
-			copy_from_user(real_tty->termios_locked,
-				      (struct termios *) arg,
-				      sizeof (struct termios));
+			user_termios_to_kernel_termios(real_tty->termios_locked,
+						       (struct termios *) arg);
 			return 0;
 		case TIOCPKT:
 			if (tty->driver.type != TTY_DRIVER_TYPE_PTY ||
diff -u --recursive --new-file v2.1.18/linux/drivers/net/3c501.c linux/drivers/net/3c501.c
--- v2.1.18/linux/drivers/net/3c501.c	Sun Nov 10 20:12:11 1996
+++ linux/drivers/net/3c501.c	Tue Dec 31 10:29:59 1996
@@ -9,15 +9,15 @@
 
     This is a device driver for the 3Com Etherlink 3c501.
     Do not purchase this card, even as a joke.  It's performance is horrible,
-    and it breaks in many ways.  
+    and it breaks in many ways.
 
     The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
     Center of Excellence in Space Data and Information Sciences
        Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-       
+
     Fixed (again!) the missing interrupt locking on TX/RX shifting.
     		Alan Cox <Alan.Cox@linux.org>
-    		
+
     Removed calls to init_etherdev since they are no longer needed, and
     cleaned up modularization just a bit. The driver still allows only
     the default address for cards when loaded as a module, but that's
@@ -29,50 +29,50 @@
     with a TX-TX optimisation to see if we can touch 180-200K/second as seems
     theoretically maximum.
     		19950402 Alan Cox <Alan.Cox@linux.org>
-    		
+
     Some notes on this thing if you have to hack it.  [Alan]
-    
+
     1]	Some documentation is available from 3Com. Due to the boards age
     	standard responses when you ask for this will range from 'be serious'
     	to 'give it to a museum'. The documentation is incomplete and mostly
     	of historical interest anyway.
-    	
+
     2]  The basic system is a single buffer which can be used to receive or
     	transmit a packet. A third command mode exists when you are setting
     	things up.
-    	
-    3]	If it's transmitting it's not receiving and vice versa. In fact the 
+
+    3]	If it's transmitting it's not receiving and vice versa. In fact the
     	time to get the board back into useful state after an operation is
     	quite large.
-    	
+
     4]	The driver works by keeping the board in receive mode waiting for a
     	packet to arrive. When one arrives it is copied out of the buffer
     	and delivered to the kernel. The card is reloaded and off we go.
-    	
+
     5]	When transmitting dev->tbusy is set and the card is reset (from
     	receive mode) [possibly losing a packet just received] to command
     	mode. A packet is loaded and transmit mode triggered. The interrupt
     	handler runs different code for transmit interrupts and can handle
     	returning to receive mode or retransmissions (yes you have to help
     	out with those too).
-    	
+
     Problems:
     	There are a wide variety of undocumented error returns from the card
-    and you basically have to kick the board and pray if they turn up. Most 
+    and you basically have to kick the board and pray if they turn up. Most
     only occur under extreme load or if you do something the board doesn't
     like (eg touching a register at the wrong time).
-    
+
     	The driver is less efficient than it could be. It switches through
     receive mode even if more transmits are queued. If this worries you buy
     a real ethernet card.
-    
+
     	The combination of slow receive restart and no real multicast
     filter makes the board unusable with a kernel compiled for IP
-    multicasting in a real multicast environment. That's down to the board, 
+    multicasting in a real multicast environment. That's down to the board,
     but even with no multicast programs running a multicast IP kernel is
     in group 224.0.0.1 and you will therefore be listening to all multicasts.
     One nv conference running over that ethernet and you can give up.
-    
+
 */
 
 static const char *version =
@@ -112,9 +112,9 @@
 
 
 /*
- *	Index to functions. 
+ *	Index to functions.
  */
- 
+
 int el1_probe(struct device *dev);
 static int  el1_probe1(struct device *dev, int ioaddr);
 static int  el_open(struct device *dev);
@@ -132,12 +132,12 @@
 #define EL_DEBUG  0	/* use 0 for production, 1 for devel., >2 for debug */
 #endif			/* Anything above 5 is wordy death! */
 static int el_debug = EL_DEBUG;
- 
-/* 
- *	Board-specific info in dev->priv. 
+
+/*
+ *	Board-specific info in dev->priv.
  */
- 
-struct net_local 
+
+struct net_local
 {
     struct enet_statistics stats;
     int tx_pkt_start;		/* The length of the current Tx packet. */
@@ -169,7 +169,7 @@
 /*
  *	Writes to the ax command register.
  */
- 
+
 #define AX_OFF	0x00			/* Irq off, buffer access on */
 #define AX_SYS  0x40			/* Load the buffer */
 #define AX_XMIT 0x44			/* Transmit a packet */
@@ -181,16 +181,16 @@
  *	Normal receive mode written to RX_STATUS.  We must intr on short packets
  *	to avoid bogus rx lockups.
  */
- 
+
 #define RX_NORM 0xA8		/* 0x68 == all addrs, 0xA8 only to me. */
 #define RX_PROM 0x68		/* Senior Prom, uhmm promiscuous mode. */
 #define RX_MULT 0xE8		/* Accept multicast packets. */
 #define TX_NORM 0x0A		/* Interrupt on everything that might hang the chip */
 
 /*
- *	TX_STATUS register. 
+ *	TX_STATUS register.
  */
- 
+
 #define TX_COLLISION 0x02
 #define TX_16COLLISIONS 0x04
 #define TX_READY 0x08
@@ -203,7 +203,7 @@
 /*
  *	The boilerplate probe code.
  */
- 
+
 #ifdef HAVE_DEVLIST
 struct netdev_entry el1_drv = {"3c501", el1_probe1, EL1_IO_EXTENT, netcard_portlist};
 #else
@@ -218,7 +218,7 @@
 	else if (base_addr != 0)	/* Don't probe at all. */
 		return ENXIO;
 
-	for (i = 0; netcard_portlist[i]; i++) 
+	for (i = 0; netcard_portlist[i]; i++)
 	{
 		int ioaddr = netcard_portlist[i];
 		if (check_region(ioaddr, EL1_IO_EXTENT))
@@ -232,8 +232,8 @@
 #endif
 
 /*
- *	The actual probe. 
- */ 
+ *	The actual probe.
+ */
 
 static int el1_probe1(struct device *dev, int ioaddr)
 {
@@ -243,25 +243,25 @@
 	int i;
 
 	/*
-	 *	Read the station address PROM data from the special port.  
+	 *	Read the station address PROM data from the special port.
 	 */
-	 
-	for (i = 0; i < 6; i++) 
+
+	for (i = 0; i < 6; i++)
 	{
 		outw(i, ioaddr + EL1_DATAPTR);
 		station_addr[i] = inb(ioaddr + EL1_SAPROM);
 	}
 	/*
 	 *	Check the first three octets of the S.A. for 3Com's prefix, or
-	 *	for the Sager NP943 prefix. 
-	 */ 
-	 
+	 *	for the Sager NP943 prefix.
+	 */
+
 	if (station_addr[0] == 0x02  &&  station_addr[1] == 0x60
-		&& station_addr[2] == 0x8c) 
+		&& station_addr[2] == 0x8c)
 	{
 		mname = "3c501";
 	} else if (station_addr[0] == 0x00  &&  station_addr[1] == 0x80
-	&& station_addr[2] == 0xC8) 
+	&& station_addr[2] == 0xC8)
 	{
 		mname = "NP943";
     	}
@@ -269,17 +269,17 @@
 		return ENODEV;
 
 	/*
-	 *	Grab the region so we can find the another board if autoIRQ fails. 
+	 *	Grab the region so we can find the another board if autoIRQ fails.
 	 */
 
 	request_region(ioaddr, EL1_IO_EXTENT,"3c501");
 
-	/*	
+	/*
 	 *	We auto-IRQ by shutting off the interrupt line and letting it float
 	 *	high.
 	 */
 
-	if (dev->irq < 2) 
+	if (dev->irq < 2)
 	{
 		autoirq_setup(2);
 		inb(RX_STATUS);		/* Clear pending interrupts. */
@@ -287,10 +287,10 @@
 		outb(AX_LOOP + 1, AX_CMD);
 
 		outb(0x00, AX_CMD);
-	
+
 		autoirq = autoirq_report(1);
 
-		if (autoirq == 0) 
+		if (autoirq == 0)
 		{
 			printk("%s probe at %#x failed to detect IRQ line.\n",
 				mname, ioaddr);
@@ -309,27 +309,27 @@
 
 	printk("%s: %s EtherLink at %#lx, using %sIRQ %d.\n", dev->name, mname, dev->base_addr,
 			autoirq ? "auto":"assigned ", dev->irq);
-	   
+
 #ifdef CONFIG_IP_MULTICAST
 	printk("WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
-#endif    
+#endif
 
 	if (el_debug)
 		printk("%s", version);
 
 	/*
-	 *	Initialize the device structure. 
+	 *	Initialize the device structure.
 	 */
-	 
+
 	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
 	if (dev->priv == NULL)
 		return -ENOMEM;
 	memset(dev->priv, 0, sizeof(struct net_local));
 
 	/*
-	 *	The EL1-specific entries in the device structure. 
+	 *	The EL1-specific entries in the device structure.
 	 */
-	 
+
 	dev->open = &el_open;
 	dev->hard_start_xmit = &el_start_xmit;
 	dev->stop = &el1_close;
@@ -337,7 +337,7 @@
 	dev->set_multicast_list = &set_multicast_list;
 
 	/*
-	 *	Setup the generic properties 
+	 *	Setup the generic properties
 	 */
 
 	ether_setup(dev);
@@ -346,9 +346,9 @@
 }
 
 /*
- *	Open/initialize the board. 
+ *	Open/initialize the board.
  */
- 
+
 static int el_open(struct device *dev)
 {
 	int ioaddr = dev->base_addr;
@@ -356,7 +356,7 @@
 	if (el_debug > 2)
 		printk("%s: Doing el_open()...", dev->name);
 
-	if (request_irq(dev->irq, &el_interrupt, 0, "3c501", NULL)) 
+	if (request_irq(dev->irq, &el_interrupt, 0, "3c501", NULL))
 		return -EAGAIN;
 
 	irq2dev_map[dev->irq] = dev;
@@ -374,13 +374,13 @@
 	struct net_local *lp = (struct net_local *)dev->priv;
 	int ioaddr = dev->base_addr;
 	unsigned long flags;
-	
+
 	if(dev->interrupt)		/* May be unloading, don't stamp on */
 		return 1;		/* the packet buffer this time      */
 
-	if (dev->tbusy) 
+	if (dev->tbusy)
 	{
-		if (jiffies - dev->trans_start < 20) 
+		if (jiffies - dev->trans_start < 20)
 		{
 			if (el_debug > 2)
 				printk(" transmitter busy, deferred.\n");
@@ -398,7 +398,7 @@
 		dev->trans_start = jiffies;
 	}
 
-	if (skb == NULL) 
+	if (skb == NULL)
 	{
 		dev_tint(dev);
 		return 0;
@@ -411,13 +411,13 @@
 	 *	mode as the driver assumes tbusy is a faithful indicator of card
 	 *	state
 	 */
-	 
+
 	cli();
-	
+
 	/*
-	 *	Avoid timer-based retransmission conflicts. 
+	 *	Avoid timer-based retransmission conflicts.
 	 */
-	 
+
 	if (set_bit(0, (void*)&dev->tbusy) != 0)
 	{
 		restore_flags(flags);
@@ -436,19 +436,19 @@
 		 *	Command mode with status cleared should [in theory]
 		 *	mean no more interrupts can be pending on the card.
 		 */
-		 
+
 #ifdef BLOCKOUT_1
-		disable_irq(dev->irq);		 
-#endif	
+		disable_irq(dev->irq);
+#endif
 		outb_p(AX_SYS, AX_CMD);
 		inb_p(RX_STATUS);
 		inb_p(TX_STATUS);
-	
+
 		lp->loading=1;
-	
-		/* 
+
+		/*
 		 *	Turn interrupts back on while we spend a pleasant afternoon
-		 *	loading bytes into the board 
+		 *	loading bytes into the board
 		 */
 
 		restore_flags(flags);
@@ -456,7 +456,7 @@
 		outw(gp_start, GP_LOW);		/* aim - packet will be loaded into buffer start */
 		outsb(DATAPORT,buf,skb->len);	/* load buffer (usual thing each byte increments the pointer) */
 		outw(gp_start, GP_LOW);		/* the board reuses the same register */
-#ifndef BLOCKOUT_1		
+#ifndef BLOCKOUT_1
 		if(lp->loading==2)		/* A receive upset our load, despite our best efforts */
 		{
 			if(el_debug>2)
@@ -466,9 +466,9 @@
 #endif
 		outb(AX_XMIT, AX_CMD);		/* fire ... Trigger xmit.  */
 		lp->loading=0;
-#ifdef BLOCKOUT_1		
+#ifdef BLOCKOUT_1
 		enable_irq(dev->irq);
-#endif		
+#endif
 		dev->trans_start = jiffies;
 	}
 
@@ -481,7 +481,7 @@
 
 /*
  *	The typical workload of the driver:
- *	Handle the ether interface interrupts. 
+ *	Handle the ether interface interrupts.
  */
 
 static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -491,7 +491,7 @@
 	int ioaddr;
 	int axsr;			/* Aux. status reg. */
 
-	if (dev == NULL  ||  dev->irq != irq) 
+	if (dev == NULL  ||  dev->irq != irq)
 	{
 		printk ("3c501 driver: irq %d for unknown device.\n", irq);
 		return;
@@ -503,7 +503,7 @@
 	/*
 	 *	What happened ?
 	 */
-	 
+
 	axsr = inb(AX_STATUS);
 
 	/*
@@ -515,25 +515,25 @@
 	if (dev->interrupt)
 		printk("%s: Reentering the interrupt driver!\n", dev->name);
 	dev->interrupt = 1;
-#ifndef BLOCKOUT_1    
+#ifndef BLOCKOUT_1
         if(lp->loading==1 && !dev->tbusy)
         	printk("%s: Inconsistent state loading while not in tx\n",
         		dev->name);
-#endif        		
+#endif
 #ifdef BLOCKOUT_3
 	lp->loading=2;		/* So we can spot loading interruptions */
 #endif
 
-	if (dev->tbusy) 
+	if (dev->tbusy)
 	{
-    
+
     		/*
     		 *	Board in transmit mode. May be loading. If we are
     		 *	loading we shouldn't have got this.
     		 */
-    	 
+
 		int txsr = inb(TX_STATUS);
-#ifdef BLOCKOUT_2		
+#ifdef BLOCKOUT_2
 		if(lp->loading==1)
 		{
 			if(el_debug > 2)
@@ -549,7 +549,7 @@
 		if (el_debug > 6)
 			printk(" txsr=%02x gp=%04x rp=%04x", txsr, inw(GP_LOW),inw(RX_LOW));
 
-		if ((axsr & 0x80) && (txsr & TX_READY) == 0) 
+		if ((axsr & 0x80) && (txsr & TX_READY) == 0)
 		{
 			/*
 			 *	FIXME: is there a logic to whether to keep on trying or
@@ -561,8 +561,8 @@
 			inw(ioaddr + EL1_DATAPTR), inw(ioaddr + EL1_RXPTR));
 			dev->tbusy = 0;
 			mark_bh(NET_BH);
-		} 
-		else if (txsr & TX_16COLLISIONS) 
+		}
+		else if (txsr & TX_16COLLISIONS)
 		{
 			/*
 			 *	Timed out
@@ -572,18 +572,18 @@
 			outb(AX_SYS, AX_CMD);
 			lp->stats.tx_aborted_errors++;
 		}
-		else if (txsr & TX_COLLISION) 
-		{	
+		else if (txsr & TX_COLLISION)
+		{
 			/*
-			 *	Retrigger xmit. 
+			 *	Retrigger xmit.
 			 */
-			 
+
 			if (el_debug > 6)
 				printk(" retransmitting after a collision.\n");
 			/*
 			 *	Poor little chip can't reset its own start pointer
 			 */
-			
+
 			outb(AX_SYS, AX_CMD);
 			outw(lp->tx_pkt_start, GP_LOW);
 			outb(AX_XMIT, AX_CMD);
@@ -613,22 +613,22 @@
     		/*
     		 *	In receive mode.
     		 */
-    	 
+
 		int rxsr = inb(RX_STATUS);
 		if (el_debug > 5)
 			printk(" rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS),inw(RX_LOW));
 		/*
-		 *	Just reading rx_status fixes most errors. 
+		 *	Just reading rx_status fixes most errors.
 		 */
 		if (rxsr & RX_MISSED)
 			lp->stats.rx_missed_errors++;
-		else if (rxsr & RX_RUNT) 
+		else if (rxsr & RX_RUNT)
 		{	/* Handled to avoid board lock-up. */
 			lp->stats.rx_length_errors++;
-			if (el_debug > 5) 
+			if (el_debug > 5)
 				printk(" runt.\n");
-		} 
-		else if (rxsr & RX_GOOD) 
+		}
+		else if (rxsr & RX_GOOD)
 		{
 			/*
 			 *	Receive worked.
@@ -650,7 +650,7 @@
 	}
 
 	/*
-	 *	Move into receive mode 
+	 *	Move into receive mode
 	 */
 
 	outb(AX_RX, AX_CMD);
@@ -664,7 +664,7 @@
 
 /*
  *	We have a good packet. Well, not really "good", just mostly not broken.
- *	We must check everything to see if it is good. 
+ *	We must check everything to see if it is good.
  */
 
 static void el_receive(struct device *dev)
@@ -679,18 +679,18 @@
 	if (el_debug > 4)
 		printk(" el_receive %d.\n", pkt_len);
 
-	if ((pkt_len < 60)  ||  (pkt_len > 1536)) 
+	if ((pkt_len < 60)  ||  (pkt_len > 1536))
 	{
 		if (el_debug)
 			printk("%s: bogus packet, length=%d\n", dev->name, pkt_len);
 		lp->stats.rx_over_errors++;
 		return;
 	}
-    
+
 	/*
 	 *	Command mode so we can empty the buffer
 	 */
-     
+
 	outb(AX_SYS, AX_CMD);
 	skb = dev_alloc_skb(pkt_len+2);
 
@@ -699,7 +699,7 @@
 	 */
 
 	outw(0x00, GP_LOW);
-	if (skb == NULL) 
+	if (skb == NULL)
 	{
 		printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 		lp->stats.rx_dropped++;
@@ -711,7 +711,7 @@
 		skb->dev = dev;
 		/*
 		 *	The read increments through the bytes. The interrupt
-		 *	handler will fix the pointer when it returns to 
+		 *	handler will fix the pointer when it returns to
 		 *	receive mode.
 		 */
 		insb(DATAPORT, skb_put(skb,pkt_len), pkt_len);
@@ -735,7 +735,7 @@
 		for (i = 0; i < 6; i++)	/* Set the station address. */
 			outb(dev->dev_addr[i], ioaddr + i);
 	}
-    
+
 	outw(0, RX_BUF_CLR);		/* Set rx packet area to 0. */
 	cli();				/* Avoid glitch on writes to CMD regs */
 	outb(TX_NORM, TX_CMD);		/* tx irq on done, collision */
@@ -758,7 +758,7 @@
 	dev->start = 0;
 
 	/*
-	 *	Free and disable the IRQ. 
+	 *	Free and disable the IRQ.
 	 */
 
 	free_irq(dev->irq, NULL);
@@ -785,7 +785,7 @@
 	int ioaddr = dev->base_addr;
 
 	if(dev->flags&IFF_PROMISC)
-	{    
+	{
 		outb(RX_PROM, RX_CMD);
 		inb(RX_STATUS);
 	}
@@ -794,7 +794,7 @@
 		outb(RX_MULT, RX_CMD);	/* Multicast or all multicast is the same */
 		inb(RX_STATUS);		/* Clear status. */
 	}
-	else 
+	else
 	{
 		outb(RX_NORM, RX_CMD);
 		inb(RX_STATUS);
@@ -805,17 +805,19 @@
 
 static char devicename[9] = { 0, };
 
-static struct device dev_3c501 = 
+static struct device dev_3c501 =
 {
 	devicename, /* device name is inserted by linux/drivers/net/net_init.c */
 	0, 0, 0, 0,
 	0x280, 5,
-	0, 0, 0, NULL, el1_probe 
+	0, 0, 0, NULL, el1_probe
 };
 
 static int io=0x280;
 static int irq=5;
-	
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+
 int init_module(void)
 {
 	dev_3c501.irq=irq;
@@ -830,18 +832,18 @@
 	/*
 	 *	No need to check MOD_IN_USE, as sys_delete_module() checks.
 	 */
-	 
+
 	unregister_netdev(&dev_3c501);
 
 	/*
-	 *	Free up the private structure, or leak memory :-) 
+	 *	Free up the private structure, or leak memory :-)
 	 */
-	 
+
 	kfree(dev_3c501.priv);
 	dev_3c501.priv = NULL;	/* gets re-allocated by el1_probe1 */
 
 	/*
-	 *	If we don't do this, we can't re-insmod it later. 
+	 *	If we don't do this, we can't re-insmod it later.
 	 */
 	release_region(dev_3c501.base_addr, EL1_IO_EXTENT);
 }
diff -u --recursive --new-file v2.1.18/linux/drivers/net/3c503.c linux/drivers/net/3c503.c
--- v2.1.18/linux/drivers/net/3c503.c	Fri Apr 12 09:49:36 1996
+++ linux/drivers/net/3c503.c	Tue Dec 31 10:29:59 1996
@@ -19,7 +19,7 @@
     EtherLink II Technical Reference Manual,
     EtherLink II/16 Technical Reference Manual Supplement,
     3Com Corporation, 5400 Bayfront Plaza, Santa Clara CA 95052-8145
-    
+
     The Crynwr 3c503 packet driver.
 
     Changelog:
@@ -49,7 +49,7 @@
 
 #include "8390.h"
 #include "3c503.h"
-#define WRD_COUNT 4 
+#define WRD_COUNT 4
 
 int el2_probe(struct device *dev);
 int el2_pio_probe(struct device *dev);
@@ -277,9 +277,9 @@
     /*
 	Divide up the memory on the card. This is the same regardless of
 	whether shared-mem or PIO is used. For 16 bit cards (16kB RAM),
-	we use the entire 8k of bank1 for an Rx ring. We only use 3k 
+	we use the entire 8k of bank1 for an Rx ring. We only use 3k
 	of the bank0 for 2 full size Tx packet slots. For 8 bit cards,
-	(8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining 
+	(8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining
 	5kB for an Rx ring.  */
 
     if (wordlength) {
@@ -440,7 +440,7 @@
 
     if (ei_status.word16)      /* Tx packets go into bank 0 on EL2/16 card */
 	outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
-    else 
+    else
 	outb(EGACFR_NORM, E33G_GACFR);
 
     if (dev->mem_start) {	/* Shared memory transfer */
@@ -473,7 +473,7 @@
  */
     wrd = (unsigned short int *) buf;
     count  = (count + 1) >> 1;
-    for(;;) 
+    for(;;)
     {
         boguscount = 0x1000;
         while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
@@ -582,14 +582,14 @@
  *  can read one extra byte without clobbering anything in the kernel because
  *  this would only occur on an odd byte-count and allocation of skb->data
  *  is word-aligned. Variable 'count' is NOT checked. Caller must check
- *  for a valid count. 
+ *  for a valid count.
  *  [This is currently quite safe.... but if one day the 3c503 explodes
  *   you know where to come looking ;)]
  */
 
     buf =  (unsigned short int *) skb->data;
     count =  (count + 1) >> 1;
-    for(;;) 
+    for(;;)
     {
         boguscount = 0x1000;
         while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
@@ -602,7 +602,7 @@
             }
         }
         if(count > WRD_COUNT)
-        { 
+        {
             insw(E33G_FIFOH, buf, WRD_COUNT);
             buf   += WRD_COUNT;
             count -= WRD_COUNT;
@@ -634,6 +634,9 @@
 static int io[MAX_EL2_CARDS] = { 0, };
 static int irq[MAX_EL2_CARDS]  = { 0, };
 static int xcvr[MAX_EL2_CARDS] = { 0, };	/* choose int. or ext. xcvr */
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
+MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.1.18/linux/drivers/net/3c505.c linux/drivers/net/3c505.c
--- v2.1.18/linux/drivers/net/3c505.c	Tue Nov 19 15:53:54 1996
+++ linux/drivers/net/3c505.c	Tue Dec 31 10:29:59 1996
@@ -3,7 +3,7 @@
  *      By Craig Southeren, Juha Laiho and Philip Blundell
  *
  * 3c505.c      This module implements an interface to the 3Com
- *              Etherlink Plus (3c505) ethernet card. Linux device 
+ *              Etherlink Plus (3c505) ethernet card. Linux device
  *              driver interface reverse engineered from the Linux 3C509
  *              device drivers. Some 3C505 information gleaned from
  *              the Crynwr packet driver. Still this driver would not
@@ -78,11 +78,11 @@
 
 /* This driver may now work with revision 2.x hardware, since all the read
  * operations on the HCR have been removed (we now keep our own softcopy).
- * But I don't have an old card to test it on.  
- * 
+ * But I don't have an old card to test it on.
+ *
  * This has had the bad effect that the autoprobe routine is now a bit
  * less friendly to other devices.  However, it was never very good.
- * before, so I doubt it will hurt anybody.  
+ * before, so I doubt it will hurt anybody.
  */
 
 /* The driver is a mess.  I took Craig's and Juha's code, and hacked it firstly
@@ -378,7 +378,7 @@
 /*****************************************************************
  *
  * send_pcb
- *   Send a PCB to the adapter. 
+ *   Send a PCB to the adapter.
  *
  *	output byte to command reg  --<--+
  *	wait until HCRE is non zero      |
@@ -907,7 +907,7 @@
 	dev->interrupt = 0;
 
 	/*
-	 *  transmitter not busy 
+	 *  transmitter not busy
 	 */
 	dev->tbusy = 0;
 
@@ -1362,7 +1362,7 @@
 	if (orig_HSR == 0xff) {
 		if (elp_debug > 0)
 			printk(notfound_msg, 1);
-		return -1;	
+		return -1;
 	}
 	/* Enable interrupts - we need timers! */
 	save_flags(flags);
@@ -1594,7 +1594,7 @@
 			dev->dma = dev->mem_start & 7;
 		}
 		else {
-			printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name); 
+			printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name);
 			dev->dma = ELP_DMA;
 		}
 	}
@@ -1669,6 +1669,9 @@
 static int io[ELP_MAX_CARDS] = { 0, };
 static int irq[ELP_MAX_CARDS] = { 0, };
 static int dma[ELP_MAX_CARDS] = { 0, };
+MODULE_PARM(io, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
+MODULE_PARM(dma, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
 
 int init_module(void)
 {
@@ -1702,7 +1705,7 @@
 void cleanup_module(void)
 {
 	int this_dev;
-        
+
 	for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
 		struct device *dev = &dev_3c505[this_dev];
 		if (dev->priv != NULL) {
diff -u --recursive --new-file v2.1.18/linux/drivers/net/3c507.c linux/drivers/net/3c507.c
--- v2.1.18/linux/drivers/net/3c507.c	Fri Mar  1 07:50:42 1996
+++ linux/drivers/net/3c507.c	Tue Dec 31 10:29:59 1996
@@ -152,15 +152,15 @@
 
 /*  Since the 3c507 maps the shared memory window so that the last byte is
 	at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
-	48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively. 
+	48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively.
 	We can account for this be setting the 'SBC Base' entry in the ISCP table
 	below for all the 16 bit offset addresses, and also adding the 'SCB Base'
 	value to all 24 bit physical addresses (in the SCP table and the TX and RX
 	Buffer Descriptors).
-					-Mark	
+					-Mark
 	*/
 #define SCB_BASE		((unsigned)64*1024 - (dev->mem_end - dev->mem_start))
- 
+
 /*
   What follows in 'init_words[]' is the "program" that is downloaded to the
   82586 memory.	 It's mostly tables and command blocks, and starts at the
@@ -200,7 +200,7 @@
   That's it: only 86 bytes to set up the beast, including every extra
   command available.  The 170 byte buffer at DUMP_DATA is shared between the
   Dump command (called only by the diagnostic program) and the SetMulticastList
-  command. 
+  command.
 
   To complete the memory setup you only have to write the station address at
   SA_OFFSET and create the Tx & Rx buffer lists.
@@ -357,7 +357,7 @@
 	printk("%s: 3c507 at %#x,", dev->name, ioaddr);
 
 	/* We should make a few more checks here, like the first three octets of
-	   the S.A. for the manufacturer's code. */ 
+	   the S.A. for the manufacturer's code. */
 
 	irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
 
@@ -366,7 +366,7 @@
 		printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval);
 		return EAGAIN;
 	}
-	
+
 	/* We've committed to using the board, and can start filling in *dev. */
 	request_region(ioaddr, EL16_IO_EXTENT, "3c507");
 	dev->base_addr = ioaddr;
@@ -422,7 +422,7 @@
 	dev->get_stats	= el16_get_stats;
 
 	ether_setup(dev);	/* Generic ethernet behaviour */
-	
+
 	dev->flags&=~IFF_MULTICAST;	/* Multicast doesn't work */
 
 	return 0;
@@ -520,19 +520,19 @@
 	int ioaddr, status, boguscount = 0;
 	ushort ack_cmd = 0;
 	ushort *shmem;
-	
+
 	if (dev == NULL) {
 		printk ("net_interrupt(): irq %d for unknown device.\n", irq);
 		return;
 	}
 	dev->interrupt = 1;
-	
+
 	ioaddr = dev->base_addr;
 	lp = (struct net_local *)dev->priv;
 	shmem = ((ushort*)dev->mem_start);
-	
+
 	status = shmem[iSCB_STATUS>>1];
-	
+
 	if (net_debug > 4) {
 		printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
 	}
@@ -661,7 +661,7 @@
 	unsigned short SCB_base = SCB_BASE;
 
 	int cur_rxbuf = lp->rx_head = RX_BUF_START;
-	
+
 	/* Initialize each Rx frame + data buffer. */
 	do {	/* While there is room for one more. */
 
@@ -678,18 +678,18 @@
 		*write_ptr++ = 0x0000;
 		*write_ptr++ = 0x0000;
 		*write_ptr++ = 0x0000;				/* Pad for protocol. */
-		
+
 		*write_ptr++ = 0x0000;				/* Buffer: Actual count */
 		*write_ptr++ = -1;					/* Buffer: Next (none). */
 		*write_ptr++ = cur_rxbuf + 0x20 + SCB_base;	/* Buffer: Address low */
 		*write_ptr++ = 0x0000;
 		/* Finally, the number of bytes in the buffer. */
 		*write_ptr++ = 0x8000 + RX_BUF_SIZE-0x20;
-		
+
 		lp->rx_tail = cur_rxbuf;
 		cur_rxbuf += RX_BUF_SIZE;
 	} while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE);
-	
+
 	/* Terminate the list by setting the EOL bit, and wrap the pointer to make
 	   the list a ring. */
 	write_ptr = (unsigned short *)
@@ -847,13 +847,13 @@
 				lp->stats.rx_dropped++;
 				break;
 			}
-			
+
 			skb_reserve(skb,2);
 			skb->dev = dev;
 
 			/* 'skb->data' points to the start of sk_buff data area. */
 			memcpy(skb_put(skb,pkt_len), data_frame + 5, pkt_len);
-		
+
 			skb->protocol=eth_type_trans(skb,dev);
 			netif_rx(skb);
 			lp->stats.rx_packets++;
@@ -885,6 +885,8 @@
 
 static int io = 0x300;
 static int irq = 0;
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.1.18/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v2.1.18/linux/drivers/net/3c509.c	Thu Dec 12 19:37:03 1996
+++ linux/drivers/net/3c509.c	Tue Dec 31 10:29:59 1996
@@ -331,7 +331,7 @@
 
 	/* Pause for at least 162 us. for the read to take place. */
 	udelay (300);
-	
+
 	for (bit = 15; bit >= 0; bit--)
 		word = (word << 1) + (inb(id_port) & 0x01);
 
@@ -772,6 +772,8 @@
 
 static int io[MAX_3C_CARDS] = { 0, };
 static int irq[MAX_3C_CARDS]  = { 0, };
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_3C_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C_CARDS) "i");
 
 int
 init_module(void)
diff -u --recursive --new-file v2.1.18/linux/drivers/net/3c523.c linux/drivers/net/3c523.c
--- v2.1.18/linux/drivers/net/3c523.c	Thu Dec 12 19:37:04 1996
+++ linux/drivers/net/3c523.c	Tue Dec 31 10:29:59 1996
@@ -1,4 +1,4 @@
-/* 
+/*
 net-3-driver for the 3c523 Etherlink/MC card (i82586 Ethernet chip)
 
 
@@ -80,6 +80,10 @@
   $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
 */
 
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
@@ -93,11 +97,6 @@
 #include <asm/bitops.h>
 #include <asm/io.h>
 
-#ifdef MODULE
-#include <linux/module.h>
-#include <linux/version.h>
-#endif
-
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
@@ -129,9 +128,9 @@
 
 sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
 sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
-sizeof(rfd) = 24; sizeof(rbd) = 12; 
+sizeof(rfd) = 24; sizeof(rbd) = 12;
 sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
-sizeof(nop_cmd) = 8; 
+sizeof(nop_cmd) = 8;
 
   * if you don't know the driver, better do not change this values: */
 
@@ -251,7 +250,7 @@
 }
 
 /**********************************************
- * close device 
+ * close device
  */
 
 static
@@ -272,7 +271,7 @@
 }
 
 /**********************************************
- * open device 
+ * open device
  */
 
 static
@@ -283,14 +282,14 @@
 
   if(request_irq( dev->irq, &elmc_interrupt, SA_SHIRQ|SA_SAMPLE_RANDOM,
   	"3c523", dev )
-  ) {    
+  ) {
     printk( "%s: couldn't get irq %d\n", dev->name, dev->irq );
     elmc_id_reset586();
     return -EAGAIN;
-  }  
+  }
 
   alloc586(dev);
-  init586(dev);  
+  init586(dev);
   startrecv586(dev);
 
   dev->interrupt = 0;
@@ -305,7 +304,7 @@
 }
 
 /**********************************************
- * Check to see if there's an 82586 out there. 
+ * Check to see if there's an 82586 out there.
  */
 
 static
@@ -320,7 +319,7 @@
   p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
   memset((char *)p->scp,0, sizeof(struct scp_struct));
   p->scp->sysbus = SYSBUSVAL;        /* 1 = 8Bit-Bus, 0 = 16 Bit */
-  
+
   iscp_addrs[0] = where;
   iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct);
 
@@ -347,12 +346,12 @@
 }
 
 /******************************************************************
- * set iscp at the right place, called by elmc_probe and open586. 
+ * set iscp at the right place, called by elmc_probe and open586.
  */
 
 void
 alloc586( struct device *dev ) {
-  struct priv *p =  (struct priv *) dev->priv; 
+  struct priv *p =  (struct priv *) dev->priv;
 
   elmc_id_reset586();
   DELAY(2);
@@ -372,7 +371,7 @@
   elmc_id_reset586();
   elmc_id_attn586();
 
-  DELAY(2); 
+  DELAY(2);
 
   if(p->iscp->busy) {
     printk("%s: Init-Problems (alloc).\n",dev->name);
@@ -424,7 +423,7 @@
     if( MCA_bus == 0 ) {
     	return ENODEV;
     }
-   
+
 	/* search through the slots for the 3c523. */
 	slot = mca_find_adapter( ELMC_MCA_ID, 0 );
 	while( slot != -1 ) {
@@ -468,13 +467,13 @@
     printk("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
 
     /* Now we extract configuration info from the card.
-	The 3c523 provides information in two of the POS registers, but 
+	The 3c523 provides information in two of the POS registers, but
 	the second one is only needed if we want to tell the card what IRQ
 	to use.  I suspect that whoever sets the thing up initially would
 	prefer we don't screw with those things.
 
 	Note we we read the status info when we found the card...
-	
+
 	See 3c523.h for more details.
 	*/
 
@@ -501,13 +500,13 @@
     		mca_write_pos( slot, 3, 0x01 );
     		break;
     }
-    
+
     /* Our IO address? */
     dev->base_addr = csr_table[ (status & ELMC_STATUS_CSR_SELECT) >> 1];
 
     request_region( dev->base_addr, ELMC_IO_EXTENT,"3c523");
 
-    dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); 
+    dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
     if (dev->priv == NULL) {
 	return -ENOMEM;
     }
@@ -543,7 +542,7 @@
 	return ENODEV;
   }
   dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
-  
+
   ((struct priv *) (dev->priv))->base =  dev->mem_start + size - 0x01000000;
   alloc586(dev);
 
@@ -584,7 +583,7 @@
   return 0;
 }
 
-/********************************************** 
+/**********************************************
  * init the chip (elmc-interrupt should be disabled?!)
  * needs a correct 'allocated' memory
  */
@@ -625,12 +624,12 @@
 	dev->flags|=IFF_PROMISC;
   }
   cfg_cmd->carr_coll  = 0x00;
- 
+
   p->scb->cbl_offset = make16(cfg_cmd);
 
   p->scb->cmd = CUC_START; /* cmd.-unit start */
   elmc_id_attn586();
- 
+
   s = jiffies; /* warning: only active with interrupts on !! */
   while(!(cfg_cmd->cmd_status & STAT_COMPL)) {
     if(jiffies-s > 30) break;
@@ -638,7 +637,7 @@
 
   if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK)) {
     printk("%s (elmc): configure command failed: %x\n",dev->name,cfg_cmd->cmd_status);
-    return 1; 
+    return 1;
   }
 
     /*
@@ -664,11 +663,11 @@
 
   if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
     printk("%s (elmc): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status);
-    return 1; 
+    return 1;
   }
 
-   /* 
-    * TDR, wire check .. e.g. no resistor e.t.c 
+   /*
+    * TDR, wire check .. e.g. no resistor e.t.c
     */
   tdr_cmd = (struct tdr_cmd_struct *)ptr;
 
@@ -682,7 +681,7 @@
   p->scb->cmd = CUC_START; /* cmd.-unit start */
   elmc_attn586();
 
-  s = jiffies; 
+  s = jiffies;
   while(!(tdr_cmd->cmd_status & STAT_COMPL)) {
     if(jiffies - s > 30) {
       printk("%s: %d Problems while running the TDR.\n",dev->name,__LINE__);
@@ -711,9 +710,9 @@
       printk("%s: TDR: Unknown status %04x\n",dev->name,result);
     }
   }
- 
-   /* 
-    * ack interrupts 
+
+   /*
+    * ack interrupts
     */
   p->scb->cmd = p->scb->status & STAT_MASK;
   elmc_id_attn586();
@@ -743,12 +742,12 @@
   }
 #endif
 
-  ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */ 
+  ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */
 
-  /* 
+  /*
    * Multicast setup
    */
-  
+
   if(dev->mc_count) {
     /* I don't understand this: do we really need memory after the init? */
     int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
@@ -794,7 +793,7 @@
     if((void *)ptr > (void *)p->iscp) {
       printk("%s: not enough shared-mem for your configuration!\n",dev->name);
       return 1;
-    }   
+    }
     memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
     memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
     p->xmit_cmds[i]->cmd_status = STAT_COMPL;
@@ -804,7 +803,7 @@
     p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
   }
 
-  p->xmit_count = 0; 
+  p->xmit_count = 0;
   p->xmit_last  = 0;
 #ifndef NO_NOPCOMMANDS
   p->nop_point  = 0;
@@ -827,7 +826,7 @@
 }
 
 /******************************************************
- * This is a helper routine for elmc_rnr_int() and init586(). 
+ * This is a helper routine for elmc_rnr_int() and init586().
  * It sets up the Receive Frame Area (RFA).
  */
 
@@ -940,7 +939,7 @@
         elmc_attn586();
       } else {
         printk("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status);
-        elmc_rnr_int(dev); 
+        elmc_rnr_int(dev);
       }
     }
     WAIT_4_SCB_CMD(); /* wait for ack. (elmc_xmt_int can be faster than ack!!) */
@@ -1002,7 +1001,7 @@
 }
 
 /**********************************************************
- * handle 'Receiver went not ready'. 
+ * handle 'Receiver went not ready'.
  */
 
 static
@@ -1014,7 +1013,7 @@
 
   WAIT_4_SCB_CMD();    /* wait for the last cmd */
   p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
-  elmc_attn586(); 
+  elmc_attn586();
   WAIT_4_SCB_CMD();    /* wait for accept cmd. */
 
   alloc_rfa(dev,(char *)p->rfd_first);
@@ -1058,7 +1057,7 @@
     } else if(status & TCMD_MAXCOLL) {
       printk("%s: Max. collisions exceeded.\n",dev->name);
       p->stats.collisions += 16;
-    } 
+    }
   }
 
 #if (NUM_XMIT_BUFFS != 1)
@@ -1073,7 +1072,7 @@
 
 /***********************************************************
  * (re)start the receiver
- */ 
+ */
 
 static
 void
@@ -1088,7 +1087,7 @@
 }
 
 /******************************************************
- * send frame 
+ * send frame
  */
 
 static
@@ -1183,7 +1182,7 @@
     next_nop = (p->nop_point + 1) & 0x1;
     p->xmit_buffs[0]->size = TBD_LAST | len;
 
-    p->xmit_cmds[0]->cmd_link   = p->nop_cmds[next_nop]->cmd_link 
+    p->xmit_cmds[0]->cmd_link   = p->nop_cmds[next_nop]->cmd_link
                                 = make16((p->nop_cmds[next_nop]));
     p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
 
@@ -1199,14 +1198,14 @@
     }
 
     p->xmit_cmds[p->xmit_count]->cmd_status  = 0;
-    p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link 
+    p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link
                                           = make16((p->nop_cmds[next_nop]));
     p->nop_cmds[next_nop]->cmd_status = 0;
 
     p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
     dev->trans_start = jiffies;
     p->xmit_count = next_nop;
-  
+
     cli();
     if(p->xmit_count != p->xmit_last) {
       dev->tbusy = 0;
@@ -1219,7 +1218,7 @@
 }
 
 /*******************************************
- * Someone wanna have the statistics 
+ * Someone wanna have the statistics
  */
 
 static
@@ -1246,7 +1245,7 @@
 }
 
 /********************************************************
- * Set MC list ..  
+ * Set MC list ..
  */
 
 static
@@ -1259,7 +1258,7 @@
 
   dev->start = 0;
   alloc586(dev);
-  init586(dev);  
+  init586(dev);
   startrecv586(dev);
   dev->start = 1;
 }
@@ -1267,13 +1266,13 @@
 /*************************************************************************/
 
 #ifdef MODULE
-char kernel_version[] = UTS_RELEASE;
 static struct device dev_elmc = {
 	"        " /*"3c523"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, elmc_probe };
-	
 
-int irq=0;
-int io=0;
+static int irq=0;
+static int io=0;
+MODULE_PARM(irq, "i");
+MODULE_PARM(io, "i");
 
 int
 init_module(void) {
diff -u --recursive --new-file v2.1.18/linux/drivers/net/ac3200.c linux/drivers/net/ac3200.c
--- v2.1.18/linux/drivers/net/ac3200.c	Tue Sep  3 09:08:40 1996
+++ linux/drivers/net/ac3200.c	Tue Dec 31 10:29:59 1996
@@ -137,7 +137,7 @@
 	for (i = 0; i < 4; i++)
 		if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
 			printk("EISA ID mismatch, %8x vs %8x.\n",
-				   inl(ioaddr + AC_ID_PORT), AC_EISA_ID); 
+				   inl(ioaddr + AC_ID_PORT), AC_EISA_ID);
 			return ENODEV;
 		}
 
@@ -329,6 +329,9 @@
 static int io[MAX_AC32_CARDS] = { 0, };
 static int irq[MAX_AC32_CARDS]  = { 0, };
 static int mem[MAX_AC32_CARDS] = { 0, };
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
 
 int
 init_module(void)
diff -u --recursive --new-file v2.1.18/linux/drivers/net/apricot.c linux/drivers/net/apricot.c
--- v2.1.18/linux/drivers/net/apricot.c	Fri Mar  1 07:50:42 1996
+++ linux/drivers/net/apricot.c	Tue Dec 31 10:29:59 1996
@@ -5,8 +5,8 @@
 	This driver is for the Apricot 82596 bus-master interface
 
         Modularised 12/94 Mark Evans
-    
-    Driver skeleton 
+
+    Driver skeleton
 	Written 1993 by Donald Becker.
 	Copyright 1993 United States Government as represented by the Director,
 	National Security Agency.  This software may only be used and distributed
@@ -15,7 +15,7 @@
 
 	The author may be reached as becker@super.org or
 	C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
-    
+
 
 */
 
@@ -112,7 +112,7 @@
     unsigned short stat;
     unsigned short cmd;
     struct i596_rfd *next;
-    long rbd; 
+    long rbd;
     unsigned short count;
     unsigned short size;
     char data[1532];
@@ -177,7 +177,7 @@
 	0x00,	/* promiscuous mode */
 	0x00,	/* collision detect */
 	0x40,	/* minimum frame length */
-	0xff,	
+	0xff,
 	0x00,
 	0x7f	/*  *multi IA */ };
 
@@ -348,7 +348,7 @@
 		break;
 	    }
 
-  	    skb->dev = dev;		
+  	    skb->dev = dev;
 	    memcpy(skb_put(skb,pkt_len), lp->scb.rfd->data, pkt_len);
 
 	    skb->protocol=eth_type_trans(skb,dev);
@@ -496,7 +496,7 @@
     cli();
     if (lp->cmd_head != (struct i596_cmd *) I596_NULL)
 	lp->cmd_tail->next = cmd;
-    else 
+    else
     {
 	lp->cmd_head = cmd;
 	while (lp->scb.status, lp->scb.command)
@@ -517,7 +517,7 @@
     lp->cmd_head = lp->scb.cmd;
     restore_flags(flags);
 
-    if (lp->cmd_backlog > 16) 
+    if (lp->cmd_backlog > 16)
     {
 	int tickssofar = jiffies - lp->last_cmd;
 
@@ -682,7 +682,7 @@
     int checksum = 0;
     int ioaddr = 0x300;
     char eth_addr[6];
-    
+
     /* this is easy the ethernet interface can only be at 0x300 */
     /* first check nothing is already registered here */
 
@@ -703,7 +703,7 @@
 
     /* Some other boards trip the checksum.. but then appear as ether
        address 0. Trap these - AC */
-       
+
     if(memcmp(eth_addr,"\x00\x00\x49",3)!= 0)
     	return ENODEV;
 
@@ -953,7 +953,7 @@
 /*
  *	Set or clear the multicast filter for this adaptor.
  */
- 
+
 static void set_multicast_list(struct device *dev)
 {
 	struct i596_private *lp = (struct i596_private *)dev->priv;
@@ -962,7 +962,7 @@
 	if (i596_debug > 1)
 		printk ("%s: set multicast list %d\n", dev->name, dev->mc_count);
 
-	if (dev->mc_count > 0) 
+	if (dev->mc_count > 0)
 	{
 		struct dev_mc_list *dmi;
 		char *cp;
@@ -985,7 +985,7 @@
 	}
 	else
 	{
-		if (lp->set_conf.next != (struct i596_cmd * ) I596_NULL) 
+		if (lp->set_conf.next != (struct i596_cmd * ) I596_NULL)
 			return;
 		if (dev->mc_count == 0 && !(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
 		{
@@ -1002,7 +1002,7 @@
 
 #ifdef HAVE_DEVLIST
 static unsigned int apricot_portlist[] = {0x300, 0};
-struct netdev_entry apricot_drv = 
+struct netdev_entry apricot_drv =
 {"apricot", apricot_probe, APRICOT_TOTAL_SIZE, apricot_portlist};
 #endif
 
@@ -1016,6 +1016,7 @@
 
 static int io = 0x300;
 static int irq = 10;
+MODULE_PARM(irq, "i");
 
 int
 init_module(void)
diff -u --recursive --new-file v2.1.18/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c
--- v2.1.18/linux/drivers/net/arcnet.c	Thu Dec 12 19:37:05 1996
+++ linux/drivers/net/arcnet.c	Tue Dec 31 10:29:59 1996
@@ -4,9 +4,9 @@
 
 	Contact Avery at: apenwarr@foxnet.net or
 	RR #5 Pole Line Road, Thunder Bay, ON, Canada P7C 5M9
-	
+
 	**********************
-	
+
 	The original copyright was as follows:
 
 	skeleton.c Written 1993 by Donald Becker.
@@ -14,9 +14,9 @@
         Director, National Security Agency.  This software may only be used
         and distributed according to the terms of the GNU Public License as
         modified by SRC, incorporated herein by reference.
-         
+
 	**********************
-	
+
 	v2.60 ALPHA (96/11/23)
 	  - Added patch from Vojtech Pavlik <vojtech@atrey.karlin.mff.cuni.cz>
 	    and Martin Mares <mj@k332.feld.cvut.cz> to make the driver work
@@ -43,13 +43,13 @@
 	The following has been SUMMARIZED.  The complete ChangeLog is
 	available in the full Linux-ARCnet package at
 		http://www.foxnet.net/~apenwarr/arcnet
-		
+
 	v2.50 (96/02/24)
 	  - Massively improved autoprobe routines; they now work even as a
 	    module.  Thanks to Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz>
 	    for his ideas and help in this area.
 	  - Changed printk's around quite a lot.
-	
+
 	v2.22 (95/12/08)
 	  - Major cleanups, speedups, and better code-sharing.
 	  - Eliminated/changed many useless/meaningless/scary debug messages
@@ -73,7 +73,7 @@
 	    send "Ethernet-Encapsulation" packets, which are compatible with
 	    Windows for Workgroups and LAN Manager, and possibly other
 	    software.  See the README for more information.
-	  
+
 	v1.02 (95/06/21)
           - A fix to make "exception" packets sent from Linux receivable
 	    on other systems.  (The protocol_id byte was sometimes being set
@@ -84,13 +84,13 @@
 	  - Fixed some IPX-related bugs. (Thanks to Tomasz Motylewski
             <motyl@tichy.ch.uj.edu.pl> for the patches to make arcnet work
             with dosemu!)
-            
+
 	v1.00 (95/02/15)
 	  - Initial non-alpha release.
-	
-	
+
+
 	TO DO: (semi-prioritized)
-	
+
          - Use cleaner "architecture-independent" shared memory access.
            This is half-done in ARCnet 2.60, but still uses some
            undocumented i386 stuff.  (We shouldn't call phys_to_virt,
@@ -115,10 +115,10 @@
          - Try to implement promiscuous (receive-all-packets) mode available
            on some newer cards with COM20020 and similar chips.  I don't have
            one, but SMC sent me the specs.
-         - ATA protocol support?? 
+         - ATA protocol support??
          - VINES TCP/IP encapsulation?? (info needed)
 
-           
+
 	Sources:
 	 - Crynwr arcnet.com/arcether.com packet drivers.
 	 - arcnet.c v0.00 dated 1/1/94 and apparently by
@@ -139,7 +139,7 @@
 static const char *version =
  "arcnet.c: v2.60 96/11/23 Avery Pennarun <apenwarr@foxnet.net>\n";
 
- 
+
 
 #include <linux/module.h>
 #include <linux/config.h>
@@ -178,7 +178,7 @@
  */
 #undef RIM_I_MODE
 
-/* Normally, the ARCnet device needs to be assigned a name (default arc0). 
+/* Normally, the ARCnet device needs to be assigned a name (default arc0).
  * Ethernet devices have a function to automatically try eth0, eth1, etc
  * until a free name is found.  To name the ARCnet device using an "eth?"
  * device name, define this option.
@@ -206,9 +206,9 @@
  * usually happens when a new computer on the network is powered on or when
  * the cable is broken.
  *
- * Define DETECT_RECONFIGS if you want to detect network reconfigurations. 
+ * Define DETECT_RECONFIGS if you want to detect network reconfigurations.
  * Recons may be a real nuisance on a larger ARCnet network; if you are a
- * network administrator you probably would like to count them. 
+ * network administrator you probably would like to count them.
  * Reconfigurations will be recorded in stats.tx_carrier_errors (the last
  * field of the /proc/net/dev file).
  *
@@ -317,7 +317,7 @@
  * results in the cleanest mess possible.
  */
 #define ADEV lp->adev
- 
+
 #ifdef CONFIG_ARCNET_ETH
  #define EDEV lp->edev
 #else
@@ -481,7 +481,7 @@
 	 */
 	u_char  saddr,		/* Source address - needed for IPX */
 		daddr;		/* Destination address */
-	
+
 	/* data that IS part of real packet */
 	u_char	protocol_id,	/* ARC_P_IP, ARC_P_ARP, etc */
 		split_flag;	/* for use with split packets */
@@ -502,7 +502,7 @@
 	u_char  saddr,		/* Source address - needed for IPX */
 		daddr,		/* Destination address */
 		junk;		/* padding to make an even length */
-	
+
 	/* data that IS part of real packet */
 	u_char	protocol_id;	/* ARC_P_IP, ARC_P_ARP, etc */
 };
@@ -554,11 +554,11 @@
 	int num_recons,		/* number of RECONs between first and last. */
 	    network_down;	/* do we think the network is down? */
 #endif
-	
+
 	struct timer_list timer; /* the timer interrupt struct */
 	struct Incoming incoming[256];	/* one from each address */
 	struct Outgoing outgoing; /* packet currently being sent */
-	
+
 	struct device *adev;	/* RFC1201 protocol device */
 
 #ifdef CONFIG_ARCNET_ETH
@@ -655,13 +655,13 @@
  ****************************************************************************/
 
 /* Dump the contents of an sk_buff
- */ 
+ */
 #if ARCNET_DEBUG_MAX & D_SKB
 void arcnet_dump_skb(struct device *dev,struct sk_buff *skb,char *desc)
 {
 	int i;
 	long flags;
-	
+
 	save_flags(flags);
 	cli();
 	printk(KERN_DEBUG "%6s: skb dump (%s) follows:",dev->name,desc);
@@ -683,7 +683,7 @@
 {
 	int i;
 	long flags;
-	
+
 	save_flags(flags);
 	cli();
 	printk(KERN_DEBUG "%6s: packet dump (%s) follows:",dev->name,desc);
@@ -696,7 +696,7 @@
 	printk("\n");
 	restore_flags(flags);
 }
-#endif 
+#endif
 
 /****************************************************************************
  *                                                                          *
@@ -717,21 +717,21 @@
 	BUGMSG(D_NORMAL,"Compiled for ARCnet RIM I (autoprobe disabled)\n");
 	BUGMSG(D_NORMAL,"Given: node %02lXh, shmem %lXh, irq %d\n",
 		dev->base_addr,dev->mem_start,dev->irq);
-	
+
 	if (dev->mem_start<=0 || dev->irq<=0)
 	{
 		BUGMSG(D_NORMAL,"No autoprobe for RIM I; you "
 			"must specify the shmem and irq!\n");
 		return -ENODEV;
 	}
-	
+
 	if (dev->base_addr<=0 || dev->base_addr>255)
 	{
 		BUGMSG(D_NORMAL,"You need to specify your card's station "
 			"ID!\n");
 		return -ENODEV;
 	}
-	
+
 	return arcnet_found(dev,dev->base_addr,dev->irq,dev->mem_start);
 }
 
@@ -762,7 +762,7 @@
 	unsigned long airqmask;
 	int *port;
 	u_long *shmem;
-	
+
 	if (!init_once)
 	{
 		for (count=0x200; count<=0x3f0; count+=16)
@@ -778,7 +778,7 @@
 		sizeof(ports),sizeof(shmems),
 		sizeof(ports)+sizeof(shmems));
 
-	
+
 #if 1
 	BUGLVL(D_EXTRA)
 	{
@@ -801,13 +801,13 @@
 	}
 	else if (dev->base_addr > 0)	/* Don't probe at all. */
 		return -ENXIO;
-		
+
 	if (dev->mem_start)
 	{
 		shmems[0]=dev->mem_start;
 		numshmems=1;
 	}
-	
+
 
 	/* Stage 1: abandon any reserved ports, or ones with status==0xFF
 	 * (empty), and reset any others by reading the reset port.
@@ -824,9 +824,9 @@
 			numprint=1;
 		}
 		BUGMSG2(D_INIT,"%Xh ",*port);
-		
+
 		ioaddr=*port;
-		
+
 		if (check_region(*port, ARCNET_TOTAL_SIZE))
 		{
 			BUGMSG2(D_INIT_REASONS,"(check_region)\n");
@@ -837,7 +837,7 @@
 			port--;
 			continue;
 		}
-		
+
 		if (ARCSTATUS == 0xFF)
 		{
 			BUGMSG2(D_INIT_REASONS,"(empty)\n");
@@ -848,7 +848,7 @@
 			port--;
 			continue;
 		}
-		
+
 		ARCRESET;	/* begin resetting card */
 
 		BUGMSG2(D_INIT_REASONS,"\n");
@@ -856,13 +856,13 @@
 		BUGLVL(D_INIT_REASONS) numprint=0;
 	}
 	BUGMSG2(D_INIT,"\n");
-	
+
 	if (!numports)
 	{
 		BUGMSG(D_NORMAL,"Stage 1: No ARCnet cards found.\n");
 		return -ENODEV;
 	}
-	
+
 
 	/* Stage 2: we have now reset any possible ARCnet cards, so we can't
 	 * do anything until they finish.  If D_INIT, print the list of
@@ -883,7 +883,7 @@
 	}
 	BUGMSG2(D_INIT,"\n");
 	JIFFER(RESETtime);
-	
+
 
 	/* Stage 3: abandon any shmem addresses that don't have the signature
 	 * 0xD1 byte in the right place, or are read-only.
@@ -902,9 +902,9 @@
 			numprint=1;
 		}
 		BUGMSG2(D_INIT,"%lXh ",*shmem);
-		
+
 		ptr=(u_long)(*shmem);
-		
+
 		if (readb(ptr) != TESTvalue)
 		{
 			BUGMSG2(D_INIT_REASONS,"(mem=%02Xh, not %02Xh)\n",
@@ -916,7 +916,7 @@
 			shmem--;
 			continue;
 		}
-		
+
 		/* By writing 0x42 to the TESTvalue location, we also make
 		 * sure no "mirror" shmem areas show up - if they occur
 		 * in another pass through this loop, they will be discarded
@@ -932,7 +932,7 @@
 			shmem--;
 			continue;
 		}
-		
+
 		BUGMSG2(D_INIT_REASONS,"\n");
 		BUGMSG(D_INIT_REASONS,"Stage 3: ");
 		BUGLVL(D_INIT_REASONS) numprint=0;
@@ -962,7 +962,7 @@
 		BUGMSG2(D_INIT,"%lXh ",*shmem);
 	}
 	BUGMSG2(D_INIT,"\n");
-	
+
 
 	/* Stage 5: for any ports that have the correct status, can disable
 	 * the RESET flag, and (if no irq is given) generate an autoirq,
@@ -983,10 +983,10 @@
 			numprint=1;
 		}
 		BUGMSG2(D_INIT,"%Xh ",*port);
-		
+
 		ioaddr=*port;
 		status=ARCSTATUS;
-		
+
 		if ((status & 0x9D)
 			!= (NORXflag|RECONflag|TXFREEflag|RESETflag))
 		{
@@ -1027,7 +1027,7 @@
 			udelay(1);
 			AINTMASK(0);
 			airq = probe_irq_off(airqmask);
-	
+
 			if (airq<=0)
 			{
 				BUGMSG2(D_INIT_REASONS,"(airq=%d)\n",airq);
@@ -1043,10 +1043,10 @@
 		{
 			airq=dev->irq;
 		}
-		
+
 		BUGMSG2(D_INIT,"(%d,", airq);
 		openparen=1;
-		
+
 		/* Everything seems okay.  But which shmem, if any, puts
 		 * back its signature byte when the card is reset?
 		 *
@@ -1074,7 +1074,7 @@
 		{
 			u_long ptr;
 			ptr=(u_long)(*shmem);
-			
+
 			if (readb(ptr) == TESTvalue)	/* found one */
 			{
 				BUGMSG2(D_INIT,"%lXh)\n", *shmem);
@@ -1087,7 +1087,7 @@
 				/* remove shmem from the list */
 				*shmem=shmems[numshmems-1];
 				numshmems--;
-				
+
 				break;
 			}
 			else
@@ -1115,7 +1115,7 @@
 	 */
 	for (shmem = &shmems[0]; shmem-shmems<numshmems; shmem++)
 		writeb(TESTvalue,*shmem);
-		
+
 	if (retval) BUGMSG(D_NORMAL,"Stage 5: No ARCnet cards found.\n");
 	return retval;
 }
@@ -1131,7 +1131,7 @@
 	u_long first_mirror,last_mirror;
 	struct arcnet_local *lp;
 	int mirror_size;
-	
+
 	/* reserve the irq */
 	if (request_irq(airq,&arcnet_interrupt,0,"arcnet",NULL))
 	{
@@ -1150,9 +1150,9 @@
 	request_region(port,ARCNET_TOTAL_SIZE,"arcnet");
 	dev->base_addr=port;
 #endif
-	
+
 	/* find the real shared memory start/end points, including mirrors */
-	
+
 	#define BUFFER_SIZE (512)
 	#define MIRROR_SIZE (BUFFER_SIZE*4)
 
@@ -1165,7 +1165,7 @@
 	    && readb(shmem-mirror_size)!=TESTvalue
 	    && readb(shmem-2*mirror_size)==TESTvalue)
 		mirror_size*=2;
-	
+
 	first_mirror=last_mirror=shmem;
 	while (readb(first_mirror)==TESTvalue) first_mirror-=mirror_size;
 	first_mirror+=mirror_size;
@@ -1177,9 +1177,9 @@
 	dev->mem_end=last_mirror+MIRROR_SIZE-1;
 	dev->rmem_start=dev->mem_start+BUFFER_SIZE*0;
 	dev->rmem_end=dev->mem_start+BUFFER_SIZE*2-1;
-	 
+
 	/* Initialize the rest of the device structure. */
-	
+
 	dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
 	if (dev->priv == NULL)
 	{
@@ -1190,7 +1190,7 @@
 	}
 	memset(dev->priv,0,sizeof(struct arcnet_local));
 	lp=(struct arcnet_local *)(dev->priv);
-	
+
 	dev->open=arcnet_open;
 	dev->stop=arcnet_close;
 	dev->hard_start_xmit=arcnetA_send_packet;
@@ -1201,7 +1201,7 @@
 	 * values.
 	 */
 	arcnet_setup(dev);
-	
+
 	/* And now fill particular fields with arcnet values */
 	dev->mtu=1500; /* completely arbitrary - agrees with ether, though */
 	dev->hard_header_len=sizeof(struct ClientData);
@@ -1230,7 +1230,7 @@
 		lp->stationid,
 		dev->base_addr,dev->irq,dev->mem_start,
 		(dev->mem_end-dev->mem_start+1)/mirror_size,mirror_size);
-		
+
 	return 0;
 }
 
@@ -1247,11 +1247,11 @@
 	struct arcnet_local *lp=(struct arcnet_local *)dev->priv;
 	short ioaddr=IOADDR;
 	int delayval,recbuf=lp->recbuf;
-	
+
 	/* no IRQ's, please! */
 	lp->intmask=0;
 	SETMASK;
-	
+
 	BUGMSG(D_INIT,"Resetting %s (status=%Xh)\n",
 			dev->name,ARCSTATUS);
 
@@ -1271,7 +1271,7 @@
 		BUGMSG(D_NORMAL,"reset failed: TESTvalue not present.\n");
 		return 1;
 	}
-	
+
 	/* clear out status variables */
 	recbuf=lp->recbuf=0;
 	lp->txbuf=2;
@@ -1284,7 +1284,7 @@
 	BUGLVL(D_DURING)
 		memset_io(dev->mem_start,0x42,2048);
 #endif
-	
+
 	/* and enable receive of our first packet to the first buffer */
 	EnableReceiver();
 
@@ -1294,7 +1294,7 @@
 	lp->intmask|=RECONflag;
 #endif
 	SETMASK;
-	
+
 	/* done!  return success. */
 	return 0;
 }
@@ -1336,7 +1336,7 @@
  * Open and close the driver                                                *
  *                                                                          *
  ****************************************************************************/
- 
+
 
 /* Open/initialize the board.  This is called sometime after booting when
  * the 'ifconfig' program is run.
@@ -1350,7 +1350,7 @@
 {
 	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
 	int ioaddr=IOADDR;
-	
+
 	if (dev->metric>=1000)
 	{
 		arcnet_debug=dev->metric-1000;
@@ -1359,7 +1359,7 @@
 	}
 
 	BUGMSG(D_INIT,"arcnet_open: resetting card.\n");
-	
+
 #ifdef FAST_IFCONFIG
 	/* try to put the card in a defined state - if it fails the first
 	 * time, actually reset it.
@@ -1372,17 +1372,17 @@
 	if (arcnet_reset(dev,1) && arcnet_reset(dev,1))
 		return -ENODEV;
 #endif
-	
+
 	dev->tbusy=0;
 	dev->interrupt=0;
 	lp->intx=0;
 	lp->in_txhandler=0;
-	
+
 	/* The RFC1201 driver is the default - just store */
 	lp->adev=dev;
 	BUGMSG(D_NORMAL,"ARCnet RFC1201 protocol initialized.\n");
 
-#ifdef CONFIG_ARCNET_ETH	
+#ifdef CONFIG_ARCNET_ETH
 	/* Initialize the ethernet-encap protocol driver */
 	lp->edev=(struct device *)kmalloc(sizeof(struct device),GFP_KERNEL);
 	if (lp->edev == NULL)
@@ -1415,7 +1415,7 @@
 
 	/* we're started */
 	START=1;
-	
+
 	/* make sure we're ready to receive IRQ's.
 	 * arcnet_reset sets this for us, but if we receive one before
 	 * START is set to 1, it could be ignored.  So, we turn IRQ's
@@ -1427,7 +1427,7 @@
 			 * necessary)
 			 */
 	SETMASK;
-	
+
 	MOD_INC_USE_COUNT;
 	return 0;
 }
@@ -1440,7 +1440,7 @@
 {
 	int ioaddr=IOADDR;
 	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
-	
+
 	TBUSY=1;
 	START=0;
 
@@ -1456,10 +1456,10 @@
 
 	/* reset more flags */
 	INTERRUPT=0;
-	
+
 	/* do NOT free lp->adev!!  It's static! */
 	lp->adev=NULL;
-	
+
 #ifdef CONFIG_ARCNET_ETH
 	/* free the ethernet-encap protocol device */
 	lp->edev->priv=NULL;
@@ -1501,10 +1501,10 @@
 {
 	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
 	int ioaddr=IOADDR;
-	
+
 	BUGMSG(D_DURING,"transmit requested (status=%Xh, inTX=%d)\n",
 			ARCSTATUS,lp->intx);
-			
+
 	if (lp->in_txhandler)
 	{
 		BUGMSG(D_NORMAL,"send_packet called while in txhandler!\n");
@@ -1526,8 +1526,8 @@
 		int tickssofar = jiffies - dev->trans_start;
 		/*int recbuf=lp->recbuf;*/
 		int status=ARCSTATUS;
-		
-		if (tickssofar < TX_TIMEOUT) 
+
+		if (tickssofar < TX_TIMEOUT)
 		{
 			BUGMSG(D_DURING,"premature kickme! (status=%Xh ticks=%d o.skb=%ph numsegs=%d segnum=%d\n",
 					status,tickssofar,lp->outgoing.skb,
@@ -1538,7 +1538,7 @@
 
 		lp->intmask &= ~TXFREEflag;
 		SETMASK;
-		
+
 		if (status&TXFREEflag)	/* transmit _DID_ finish */
 		{
 			BUGMSG(D_NORMAL,"tx timeout - missed IRQ? (status=%Xh, ticks=%d, mask=%Xh, dest=%02Xh)\n",
@@ -1561,7 +1561,7 @@
 			lp->stats.tx_dropped++;
 		}
 		lp->outgoing.skb=NULL;
-		
+
 		TBUSY=0;
 		lp->txready=0;
 		lp->sending=0;
@@ -1579,7 +1579,7 @@
 		dev_tint(dev);
 		return 0;
 	}
-	
+
 	if (lp->txready)	/* transmit already in progress! */
 	{
 		BUGMSG(D_NORMAL,"trying to start new packet while busy! (status=%Xh)\n",
@@ -1591,7 +1591,7 @@
 		lp->stats.tx_errors++;
 		lp->stats.tx_fifo_errors++;
 		lp->txready=0;	/* we definitely need this line! */
-		
+
 		return 1;
 	}
 
@@ -1620,24 +1620,24 @@
 	struct Outgoing *out=&(lp->outgoing);
 
 	lp->intx++;
-	
+
 	bad=arcnet_send_packet_bad(skb,dev);
 	if (bad)
 	{
 		lp->intx--;
 		return bad;
 	}
-	
+
 	TBUSY=1;
-	
+
 	out->length = 1 < skb->len ? skb->len : 1;
 	out->hdr=(struct ClientData*)skb->data;
 	out->skb=skb;
-		
+
 	BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"tx");
 
 	out->hdr->sequence=(lp->sequence++);
-	
+
 	/* fits in one packet? */
 	if (out->length-EXTRA_CLIENTDATA<=XMTU)
 	{
@@ -1658,7 +1658,7 @@
 		/* done right away */
 		dev_kfree_skb(out->skb,FREE_WRITE);
 		out->skb=NULL;
-					
+
 		if (arcnet_go_tx(dev,1))
 		{
 			/* inform upper layers */
@@ -1675,7 +1675,7 @@
 		out->dataleft=out->length-sizeof(struct ClientData);
 		out->numsegs=(out->dataleft+maxsegsize-1)/maxsegsize;
 		out->segnum=0;
-		
+
 		BUGMSG(D_TX,"packet (%d bytes) split into %d fragments:\n",
 			out->length,out->numsegs);
 
@@ -1694,7 +1694,7 @@
 				arcnet_go_tx(dev,1);
 			}
 		}
-		
+
 		/* if segnum==numsegs, the transmission is finished;
 		 * free the skb right away.
 		 */
@@ -1710,7 +1710,7 @@
 
 	dev->trans_start=jiffies;
 	lp->intx--;
-	
+
 	/* make sure we didn't ignore a TX IRQ while we were in here */
 	lp->intmask |= TXFREEflag;
 	SETMASK;
@@ -1728,16 +1728,16 @@
 	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
 	int ioaddr=IOADDR,maxsegsize=XMTU-4;
 	struct Outgoing *out=&(lp->outgoing);
-	
+
 	BUGMSG(D_DURING,"continue_tx called (status=%Xh, intx=%d, intxh=%d, intmask=%Xh\n",
 		ARCSTATUS,lp->intx,lp->in_txhandler,lp->intmask);
-	
+
 	if (lp->txready)
 	{
 		BUGMSG(D_NORMAL,"continue_tx: called with packet in buffer!\n");
 		return;
 	}
-	
+
 	if (out->segnum>=out->numsegs)
 	{
 		BUGMSG(D_NORMAL,"continue_tx: building segment %d of %d!\n",
@@ -1751,7 +1751,7 @@
 
 	out->seglen=maxsegsize;
 	if (out->seglen>out->dataleft) out->seglen=out->dataleft;
-			
+
 	BUGMSG(D_TX,"building packet #%d (%d bytes) of %d (%d total), splitflag=%d\n",
 		out->segnum+1,out->seglen,out->numsegs,
 		out->length,out->hdr->split_flag);
@@ -1759,7 +1759,7 @@
 	arcnetAS_prepare_tx(dev,((char *)out->hdr)+EXTRA_CLIENTDATA,
 		sizeof(struct ClientData)-EXTRA_CLIENTDATA,
 		out->data,out->seglen,out->hdr->daddr,1);
-		
+
 	out->dataleft-=out->seglen;
 	out->data+=out->seglen;
 	out->segnum++;
@@ -1775,16 +1775,16 @@
 {
 	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
 	struct ClientData *arcsoft;
-	union ArcPacket *arcpacket = 
+	union ArcPacket *arcpacket =
 		(union ArcPacket *)phys_to_virt(dev->mem_start+512*(lp->txbuf^1));
 	int offset;
-	
+
 #ifdef SLOW_XMIT_COPY
 	char *iptr,*iend,*optr;
 #endif
-	
+
 	lp->txbuf=lp->txbuf^1;	/* XOR with 1 to alternate between 2 and 3 */
-	
+
 	length+=hdrlen;
 
 	BUGMSG(D_TX,"arcnetAS_prep_tx: hdr:%ph, length:%d, data:%ph\n",
@@ -1809,7 +1809,7 @@
 	{
 		arcpacket->hardheader.offset1=0;
 		arcpacket->hardheader.offset2=offset=512-length;
-		
+
 		arcsoft=(struct ClientData *)
 			(&arcpacket->raw[offset]);
 	}
@@ -1819,7 +1819,7 @@
 		arcpacket->hardheader.offset2=offset=512-length-4;
 		arcsoft=(struct ClientData *)
 			(&arcpacket->raw[offset+4]);
-		
+
 		/* exception-specific stuff - these four bytes
 		 * make the packet long enough to fit in a 512-byte
 		 * frame.
@@ -1857,10 +1857,10 @@
 	memcpy((u_char*)arcsoft+hdrlen,
 		data,length-hdrlen);
 #endif
-		
+
 	BUGMSG(D_DURING,"transmitting packet to station %02Xh (%d bytes)\n",
 			daddr,length);
-			
+
 	BUGLVL(D_TX) arcnet_dump_packet(dev,arcpacket->raw,length>MTU,"tx");
 	lp->lastload_dest=daddr;
 	lp->txready=lp->txbuf;	/* packet is ready for sending */
@@ -1894,7 +1894,7 @@
 		}
 		return 0;
 	}
-	
+
 	/* start sending */
 	ACOMMAND(TXcmd|(lp->txready<<3));
 
@@ -1930,14 +1930,14 @@
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	int ioaddr;
-	
+
 	if (dev==NULL)
 	{
 		BUGLVL(D_DURING)
 			printk(KERN_DEBUG "arcnet: irq %d for unknown device.\n", irq);
 		return;
 	}
-	
+
 	BUGMSG(D_DURING,"in arcnet_interrupt\n");
 
 	/* RESET flag was enabled - if !dev->start, we must clear it right
@@ -1961,7 +1961,7 @@
  */
 static void
 arcnet_inthandler(struct device *dev)
-{	
+{
 	struct arcnet_local *lp=(struct arcnet_local *)dev->priv;
 	int ioaddr=IOADDR, status, boguscount = 3, didsomething;
 
@@ -1970,7 +1970,7 @@
 		BUGMSG(D_NORMAL,"DRIVER PROBLEM!  Nested arcnet interrupts!\n");
 		return;	/* don't even try. */
 	}
-	
+
 	AINTMASK(0);
 	INTERRUPT = 1;
 
@@ -1981,7 +1981,7 @@
 	{
 		status = ARCSTATUS;
 		didsomething=0;
-	
+
 
 		/* RESET flag was enabled - card is resetting and if RX
 		 * is disabled, it's NOT because we just got a packet.
@@ -1991,12 +1991,12 @@
 			BUGMSG(D_NORMAL,"spurious reset (status=%Xh)\n",
 					status);
 			arcnet_reset(dev,0);
-			
+
 			/* all other flag values are just garbage */
 			break;
 		}
-		
-		
+
+
 		/* RX is inhibited - we must have received something. */
 		if (status & lp->intmask & NORXflag)
 		{
@@ -2012,14 +2012,14 @@
 			arcnet_rx(dev,!recbuf);
 			didsomething++;
 		}
-		
+
 		/* it can only be an xmit-done irq if we're xmitting :) */
 		/*if (status&TXFREEflag && !lp->in_txhandler && lp->sending)*/
 		if (status & lp->intmask & TXFREEflag)
 		{
 			struct Outgoing *out=&(lp->outgoing);
 			int was_sending=lp->sending;
-			
+
 			lp->intmask &= ~TXFREEflag;
 
 			lp->in_txhandler++;
@@ -2027,7 +2027,7 @@
 
 			BUGMSG(D_DURING,"TX IRQ (stat=%Xh, numsegs=%d, segnum=%d, skb=%ph)\n",
 					status,out->numsegs,out->segnum,out->skb);
-					
+
 			if (was_sending && !(status&TXACKflag))
 			{
 				if (lp->lasttrans_dest != 0)
@@ -2048,7 +2048,7 @@
 			/* send packet if there is one */
 			arcnet_go_tx(dev,0);
 			didsomething++;
-			
+
 			if (lp->intx)
 			{
 				BUGMSG(D_DURING,"TXDONE while intx! (status=%Xh, intx=%d)\n",
@@ -2060,7 +2060,7 @@
 			if (!lp->outgoing.skb)
 			{
 				BUGMSG(D_DURING,"TX IRQ done: no split to continue.\n");
-				
+
 				/* inform upper layers */
 				if (!lp->txready && IF_TBUSY)
 				{
@@ -2070,7 +2070,7 @@
 				lp->in_txhandler--;
 				continue;
 			}
-			
+
 			/* if more than one segment, and not all segments
 			 * are done, then continue xmit.
 			 */
@@ -2113,29 +2113,29 @@
 		{
 			ACOMMAND(CFLAGScmd|CONFIGclear);
 			lp->stats.tx_carrier_errors++;
-			
+
 			#ifdef SHOW_RECONFIGS
 			BUGMSG(D_NORMAL,"Network reconfiguration detected (status=%Xh)\n",
 					status);
 			#endif /* SHOW_RECONFIGS */
-			
+
 			#ifdef RECON_THRESHOLD
 			/* is the RECON info empty or old? */
-			if (!lp->first_recon || !lp->last_recon || 
+			if (!lp->first_recon || !lp->last_recon ||
 				jiffies-lp->last_recon > HZ*10)
 			{
 				if (lp->network_down)
 					BUGMSG(D_NORMAL,"reconfiguration detected: cabling restored?\n");
 				lp->first_recon=lp->last_recon=jiffies;
 				lp->num_recons=lp->network_down=0;
-				
+
 				BUGMSG(D_DURING,"recon: clearing counters.\n");
 			}
 			else /* add to current RECON counter */
 			{
 				lp->last_recon=jiffies;
 				lp->num_recons++;
-				
+
 				BUGMSG(D_DURING,"recon: counter=%d, time=%lds, net=%d\n",
 					lp->num_recons,
 					(lp->last_recon-lp->first_recon)/HZ,
@@ -2174,7 +2174,7 @@
 				BUGMSG(D_NORMAL,"cabling restored?\n");
 			lp->first_recon=lp->last_recon=0;
 			lp->num_recons=lp->network_down=0;
-			
+
 			BUGMSG(D_DURING,"not recon: clearing counters anyway.\n");
 		}
 		#endif
@@ -2212,12 +2212,12 @@
 	u_char *arcsoft;
 	short length,offset;
 	u_char daddr,saddr;
-	
+
 	lp->stats.rx_packets++;
 
 	saddr=arcpacket->hardheader.source;
 	daddr=arcpacket->hardheader.destination;
-	
+
 	/* if source is 0, it's a "used" packet! */
 	if (saddr==0)
 	{
@@ -2227,7 +2227,7 @@
 		return;
 	}
 	arcpacket->hardheader.source=0;
-	
+
 	if (arcpacket->hardheader.offset1) /* Normal Packet */
 	{
 		offset=arcpacket->hardheader.offset1;
@@ -2241,7 +2241,7 @@
 
 		length=512-offset;
 	}
-	
+
        	BUGMSG(D_DURING,"received packet from %02Xh to %02Xh (%d bytes)\n",
        			saddr,daddr,length);
 
@@ -2307,10 +2307,10 @@
 	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
 	struct sk_buff *skb;
 	struct ClientData *arcsoft,*soft;
-	
+
 	BUGMSG(D_DURING,"it's an RFC1201 packet (length=%d)\n",
 			length);
-			
+
 	/* compensate for EXTRA_CLIENTDATA (which isn't actually in the
 	 * packet)
 	 */
@@ -2326,14 +2326,14 @@
 			((u_char *)arcsoft + 4);
 		length-=4;
 	}
-	
+
 	if (!arcsoft->split_flag)		/* not split */
 	{
 		struct Incoming *in=&lp->incoming[saddr];
 
 		BUGMSG(D_RX,"incoming is not split (splitflag=%d)\n",
 			arcsoft->split_flag);
-			
+
 		if (in->skb)	/* already assembling one! */
         	{
         		BUGMSG(D_EXTRA,"aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
@@ -2344,7 +2344,7 @@
         		lp->stats.rx_missed_errors++;
         		in->skb=NULL;
         	}
-        	
+
         	in->sequence=arcsoft->sequence;
 
          	skb = alloc_skb(length, GFP_ATOMIC);
@@ -2354,16 +2354,16 @@
          		return;
          	}
          	soft=(struct ClientData *)skb->data;
-         	
+
          	skb->len = length;
          	skb->dev = dev;
-         	
+
          	memcpy((u_char *)soft+EXTRA_CLIENTDATA,
          		(u_char *)arcsoft+EXTRA_CLIENTDATA,
          		length-EXTRA_CLIENTDATA);
          	soft->daddr=daddr;
          	soft->saddr=saddr;
-         	
+
          	/* ARP packets have problems when sent from DOS.
          	 * source address is always 0 on some systems!  So we take
          	 * the hardware source addr (which is impossible to fumble)
@@ -2378,7 +2378,7 @@
          		if (arp->ar_hln==1 && arp->ar_pln==4)
          		{
          			char *cptr=(char *)(arp)+sizeof(struct arphdr);
-         			
+
          			if (!*cptr)	/* is saddr = 00? */
          			{
          				BUGMSG(D_EXTRA,"ARP source address was 00h, set to %02Xh.\n",
@@ -2400,7 +2400,7 @@
          			lp->stats.rx_crc_errors++;
          		}
          	}
-         	
+
 		BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
 
 		skb->protocol=arcnetA_type_trans(skb,dev);
@@ -2425,9 +2425,9 @@
 	          * ARCnet card possible on the network.  Seems rather like
 	          * a waste of memory.  Necessary?
 	          */
-	          
+
 	        struct Incoming *in=&lp->incoming[saddr];
-	        
+
 	        BUGMSG(D_RX,"packet is split (splitflag=%d, seq=%d)\n",
 	        	arcsoft->split_flag,in->sequence);
 
@@ -2442,7 +2442,7 @@
 	        	lp->stats.rx_missed_errors++;
 	        	in->lastpacket=in->numpackets=0;
 	        }
-	          
+
 	        if (arcsoft->split_flag & 1)	/* first packet in split */
 	        {
 	        	BUGMSG(D_RX,"brand new splitpacket (splitflag=%d)\n",
@@ -2460,7 +2460,7 @@
 			in->sequence=arcsoft->sequence;
 	        	in->numpackets=((unsigned)arcsoft->split_flag>>1)+2;
 	        	in->lastpacket=1;
-	        	
+
 	        	if (in->numpackets>16)
 	        	{
 	        		BUGMSG(D_EXTRA,"incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
@@ -2469,7 +2469,7 @@
 	        		lp->stats.rx_length_errors++;
 	        		return;
 	        	}
-	        
+
                 	in->skb=skb=alloc_skb(508*in->numpackets
                 			+ sizeof(struct ClientData),
 	                		GFP_ATOMIC);
@@ -2478,9 +2478,9 @@
                 		lp->stats.rx_dropped++;
                 		return;
                 	}
-	                		
+
                 	soft=(struct ClientData *)skb->data;
-                	
+
                 	skb->len=sizeof(struct ClientData);
                 	skb->dev=dev;
 
@@ -2495,7 +2495,7 @@
 
 			/* if we're not assembling, there's no point
 			 * trying to continue.
-			 */			
+			 */
 			if (!in->skb)
 			{
 				BUGMSG(D_EXTRA,"can't continue split without starting first! (splitflag=%d, seq=%d)\n",
@@ -2517,7 +2517,7 @@
 					lp->stats.rx_frame_errors++;
 					return;
 				}
-				
+
 				/* "bad" duplicate, kill reassembly */
 				BUGMSG(D_EXTRA,"out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n",
 					in->sequence,arcsoft->split_flag,
@@ -2532,18 +2532,18 @@
 
 	               	soft=(struct ClientData *)in->skb->data;
 	        }
-	        
+
 	        skb=in->skb;
-	        
+
 	        memcpy(skb->data+skb->len,
 	               (u_char *)arcsoft+sizeof(struct ClientData),
 	               length-sizeof(struct ClientData));
 
          	skb->len+=length-sizeof(struct ClientData);
-         	
+
          	soft->daddr=daddr;
          	soft->saddr=saddr;
-         	
+
          	/* are we done? */
          	if (in->lastpacket == in->numpackets)
          	{
@@ -2556,11 +2556,11 @@
          		{
 	         		in->skb=NULL;
         	 		in->lastpacket=in->numpackets=0;
-			
+
 				BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
-			
+
 				skb->protocol=arcnetA_type_trans(skb,dev);
-				
+
 	         		netif_rx(skb);
 	         	}
         	}
@@ -2649,7 +2649,7 @@
 		lp->stats.tx_errors++;
 		lp->stats.tx_aborted_errors++;
 		return 0;
-	}	
+	}
 
 	/*
 	 * Set the source hardware address.
@@ -2675,7 +2675,7 @@
 	}
 	else
 		head->daddr=0;	/* better fill one in anyway */
-		
+
 	return -dev->hard_header_len;
 }
 
@@ -2697,8 +2697,8 @@
 	 *
 	 * FIXME: Anyone want to spec IPv6 over ARCnet ?
 	 */
-	 
-	if(head->protocol_id != ARC_P_IP) 
+
+	if(head->protocol_id != ARC_P_IP)
 	{
 		BUGMSG(D_NORMAL,"I don't understand protocol type %d (%Xh) addresses!\n",
 			head->protocol_id,head->protocol_id);
@@ -2712,7 +2712,7 @@
 	/*
 	 * Try to get ARP to resolve the header.
 	 */
-#ifdef CONFIG_INET	 
+#ifdef CONFIG_INET
 	BUGMSG(D_DURING,"rebuild header from %d to %d; protocol %Xh\n",
 			head->saddr,head->daddr,head->protocol_id);
 	status=arp_find(&(head->daddr),skb)? 1 : 0;
@@ -2720,8 +2720,8 @@
 			head->saddr,head->daddr,head->protocol_id);
 	return status;
 #else
-	return 0;	
-#endif	
+	return 0;
+#endif
 }
 
 
@@ -2738,7 +2738,7 @@
 	skb->mac.raw=skb->data;
 	skb_pull(skb,dev->hard_header_len);
 	head=(struct ClientData *)skb->mac.raw;
-	
+
 	if (head->daddr==0)
 		skb->pkt_type=PACKET_BROADCAST;
 	else if (dev->flags&IFF_PROMISC)
@@ -2747,7 +2747,7 @@
 		if (head->daddr != dev->dev_addr[0])
 			skb->pkt_type=PACKET_OTHERHOST;
 	}
-	
+
 	/* now return the protocol number */
 	switch (head->protocol_id)
 	{
@@ -2790,7 +2790,7 @@
 	dev->hard_start_xmit=arcnetE_send_packet;
 
 	BUGMSG(D_NORMAL,"ARCnet Ethernet-Encap protocol initialized.\n");
-			
+
 	return 0;
 }
 
@@ -2811,13 +2811,13 @@
 {
 	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
 	int ioaddr=IOADDR,bad;
-	union ArcPacket *arcpacket = 
+	union ArcPacket *arcpacket =
 		(union ArcPacket *)phys_to_virt(dev->mem_start+512*(lp->txbuf^1));
 	u_char *arcsoft,daddr;
 	short offset,length=skb->len+1;
 
 	lp->intx++;
-	
+
 	bad=arcnet_send_packet_bad(skb,dev);
 	if (bad)
 	{
@@ -2826,7 +2826,7 @@
 	}
 
 	TBUSY=1;
-		
+
 	if (length>XMTU)
 	{
 		BUGMSG(D_NORMAL,"MTU must be <= 493 for ethernet encap (length=%d).\n",
@@ -2837,7 +2837,7 @@
 		lp->intx--;
 		return 0;
 	}
-		
+
 	BUGMSG(D_DURING,"starting tx sequence...\n");
 
 	lp->txbuf=lp->txbuf^1; /* XOR with 1 to alternate btw 2 & 3 */
@@ -2867,25 +2867,25 @@
 	{
 		arcpacket->hardheader.offset1=(offset-=256);
 	}
-	
+
 	BUGMSG(D_DURING," length=%Xh, offset=%Xh, offset1=%Xh, offset2=%Xh\n",
 			length,offset,arcpacket->hardheader.offset1,
 			arcpacket->hardheader.offset2);
-	
+
 	arcsoft=&arcpacket->raw[offset];
 	arcsoft[0]=ARC_P_ETHER;
 	arcsoft++;
-		
+
 	/* copy the packet into ARCnet shmem
 	 *  - the first bytes of ClientData header are skipped
 	 */
 	BUGMSG(D_DURING,"ready to memcpy\n");
-	
+
 	memcpy(arcsoft,skb->data,skb->len);
-		
+
 	BUGMSG(D_DURING,"transmitting packet to station %02Xh (%d bytes)\n",
 			daddr,length);
-				
+
 	BUGLVL(D_TX) arcnet_dump_packet(dev,arcpacket->raw,length>=240,"tx");
 
 	lp->lastload_dest=daddr;
@@ -2902,7 +2902,7 @@
 
 	dev->trans_start=jiffies;
 	lp->intx--;
-	
+
 	/* make sure we didn't ignore a TX IRQ while we were in here */
 	lp->intmask |= TXFREEflag;
 	SETMASK;
@@ -2919,7 +2919,7 @@
 {
 	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
 	struct sk_buff *skb;
-	
+
 	BUGMSG(D_DURING,"it's an ethernet-encap packet (length=%d)\n",
 			length);
 
@@ -2929,16 +2929,16 @@
        		lp->stats.rx_dropped++;
        		return;
        	}
-       	
+
        	skb->len = length;
        	skb->dev = dev;
-       	
+
        	memcpy(skb->data,(u_char *)arcsoft+1,length-1);
 
         BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
 
 	skb->protocol=eth_type_trans(skb,dev);
-        
+
         netif_rx(skb);
 }
 
@@ -2958,7 +2958,7 @@
 	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
 
 	arcnet_setup(dev);
-       
+
 	/* And now fill particular fields with arcnet values */
 	dev->dev_addr[0]=lp->stationid;
 	dev->hard_header_len=sizeof(struct S_ClientData);
@@ -2994,14 +2994,14 @@
 	struct S_ClientData *hdr=(struct S_ClientData *)skb->data;
 
 	lp->intx++;
-	
+
 	bad=arcnet_send_packet_bad(skb,dev);
 	if (bad)
 	{
 		lp->intx--;
 		return bad;
 	}
-	
+
 	TBUSY=1;
 
 	length = 1 < skb->len ? skb->len : 1;
@@ -3020,7 +3020,7 @@
 
 		/* done right away */
 		dev_kfree_skb(skb,FREE_WRITE);
-				
+
 		if (arcnet_go_tx(dev,1))
 		{
 			/* inform upper layers */
@@ -3035,7 +3035,7 @@
 		dev_kfree_skb(skb,FREE_WRITE);
 		lp->stats.tx_dropped++;
 		TBUSY=0;
-		mark_bh(NET_BH);	
+		mark_bh(NET_BH);
 	}
 
 	dev->trans_start=jiffies;
@@ -3049,7 +3049,7 @@
 }
 
 
-/* Packet receiver for RFC1051 packets; 
+/* Packet receiver for RFC1051 packets;
  */
 static void
 arcnetS_rx(struct device *dev,u_char *buf,
@@ -3058,16 +3058,16 @@
 	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
 	struct sk_buff *skb;
 	struct S_ClientData *arcsoft,*soft;
-	
+
 	arcsoft=(struct S_ClientData *)(buf-S_EXTRA_CLIENTDATA);
 	length+=S_EXTRA_CLIENTDATA;
-	
+
 	BUGMSG(D_DURING,"it's an RFC1051 packet (length=%d)\n",
 			length);
-			
-	
-			
-	{    /* was "if not split" in A protocol, S is never split */	
+
+
+
+	{    /* was "if not split" in A protocol, S is never split */
 
          	skb = alloc_skb(length, GFP_ATOMIC);
          	if (skb == NULL) {
@@ -3080,14 +3080,14 @@
 		memcpy((u_char *)soft + sizeof(struct S_ClientData)
 				- S_EXTRA_CLIENTDATA,
 			(u_char *)arcsoft + sizeof(struct S_ClientData)
-				- S_EXTRA_CLIENTDATA, 
+				- S_EXTRA_CLIENTDATA,
 			length - sizeof(struct S_ClientData)
 				+ S_EXTRA_CLIENTDATA);
 		soft->protocol_id=arcsoft->protocol_id;
          	soft->daddr=daddr;
          	soft->saddr=saddr;
          	skb->dev = dev;  /* is already lp->sdev */
-         	
+
 		BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
 
 		skb->protocol=arcnetS_type_trans(skb,dev);
@@ -3126,7 +3126,7 @@
 		lp->stats.tx_errors++;
 		lp->stats.tx_aborted_errors++;
 		return 0;
-	}	
+	}
 
 	/*
 	 * Set the source hardware address.
@@ -3149,7 +3149,7 @@
 	}
 	else
 		head->daddr=0;	/* better fill one in anyway */
-		
+
 	return -dev->hard_header_len;
 }
 
@@ -3167,8 +3167,8 @@
 	/*
 	 * Only ARP and IP are currently supported
 	 */
-	 
-	if(head->protocol_id != ARC_P_IP_RFC1051) 
+
+	if(head->protocol_id != ARC_P_IP_RFC1051)
 	{
 		BUGMSG(D_NORMAL,"I don't understand protocol type %d (%Xh) addresses!\n",
 			head->protocol_id,head->protocol_id);
@@ -3182,14 +3182,14 @@
 	/*
 	 * Try to get ARP to resolve the header.
 	 */
-#ifdef CONFIG_INET	 
+#ifdef CONFIG_INET
 	return arp_find(&(head->daddr),skb)? 1 : 0;
 #else
-	return 0;	
-#endif	
+	return 0;
+#endif
 }
 
-		
+
 /* Determine a packet's protocol ID.
  *
  * With ARCnet we have to convert everything to Ethernet-style stuff.
@@ -3203,7 +3203,7 @@
 	skb->mac.raw=skb->data;
 	skb_pull(skb,dev->hard_header_len);
 	head=(struct S_ClientData *)skb->mac.raw;
-	
+
 	if (head->daddr==0)
 		skb->pkt_type=PACKET_BROADCAST;
 	else if (dev->flags&IFF_PROMISC)
@@ -3212,7 +3212,7 @@
 		if (head->daddr != dev->dev_addr[0])
 			skb->pkt_type=PACKET_OTHERHOST;
 	}
-	
+
 	/* now return the protocol number */
 	switch (head->protocol_id)
 	{
@@ -3246,14 +3246,18 @@
   0, 0,  /* I/O address, IRQ */
   0, 0, 0, NULL, arcnet_probe
 };
-	
-	
+
+
 static int io=0x0;	/* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
 static int irqnum=0;	/* or use the insmod io= irq= shmem= options */
 static int irq=0;
 static int shmem=0;
 static char *device = NULL;	/* use eg. device="arc1" to change name */
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irqnum, "i");
+MODULE_PARM(shmem, "i");
+
 #ifdef RIM_I_MODE
   static int node=0;	/* you must specify the node ID for RIM I cards */
 #endif
@@ -3272,7 +3276,7 @@
 	#endif
 
 	dev->base_addr=io;
-	
+
 	if (irq) irqnum=irq;
 	dev->irq=irqnum;
 	if (dev->irq==2) dev->irq=9;
@@ -3310,7 +3314,7 @@
 		irq2dev_map[dev->irq] = NULL;
 		free_irq(dev->irq,NULL);
 	}
-	
+
 	if (dev->base_addr) RELEASE_REGION(dev->base_addr,ARCNET_TOTAL_SIZE);
 	unregister_netdev(dev);
 	kfree(dev->priv);
diff -u --recursive --new-file v2.1.18/linux/drivers/net/at1700.c linux/drivers/net/at1700.c
--- v2.1.18/linux/drivers/net/at1700.c	Wed Oct  9 08:55:19 1996
+++ linux/drivers/net/at1700.c	Tue Dec 31 10:29:59 1996
@@ -270,7 +270,7 @@
 	dev->set_multicast_list = &set_multicast_list;
 
 	/* Fill in the fields of 'dev' with ethernet-generic values. */
-	   
+
 	ether_setup(dev);
 	return 0;
 }
@@ -283,9 +283,9 @@
 	short ee_daddr = ioaddr + EEPROM_Data;
 	int read_cmd = location | EE_READ_CMD;
 	short ctrl_val = EE_CS;
-	
+
 	outb(ctrl_val, ee_addr);
-	
+
 	/* Shift the read command bits out. */
 	for (i = 9; i >= 0; i--) {
 		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
@@ -296,7 +296,7 @@
 		eeprom_delay();
 	}
 	outb(EE_CS, ee_addr);
-	
+
 	for (i = 16; i > 0; i--) {
 		outb(EE_CS | EE_SHIFT_CLK, ee_addr);
 		eeprom_delay();
@@ -410,7 +410,7 @@
 
 		/* Turn off the possible Tx interrupts. */
 		outb(0x00, ioaddr + TX_INTR);
-		
+
 		outw(length, ioaddr + DATAPORT);
 		outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
 
@@ -563,7 +563,7 @@
 		}
 
 		if (net_debug > 5)
-			printk("%s: Exint Rx packet with mode %02x after %d ticks.\n", 
+			printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
 				   dev->name, inb(ioaddr + RX_MODE), i);
 	}
 	return;
@@ -614,17 +614,17 @@
 set_multicast_list(struct device *dev)
 {
 	short ioaddr = dev->base_addr;
-	if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI)) 
+	if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI))
 	{
 		/*
 		 *	We must make the kernel realise we had to move
 		 *	into promisc mode or we start all out war on
 		 *	the cable. - AC
 		 */
-		dev->flags|=IFF_PROMISC;		
-	
+		dev->flags|=IFF_PROMISC;
+
 		outb(3, ioaddr + RX_MODE);	/* Enable promiscuous mode */
-	} 
+	}
 	else
 		outb(2, ioaddr + RX_MODE);	/* Disable promiscuous, use normal mode */
 }
@@ -638,6 +638,8 @@
 
 static int io = 0x260;
 static int irq = 0;
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.1.18/linux/drivers/net/atari_bionet.c linux/drivers/net/atari_bionet.c
--- v2.1.18/linux/drivers/net/atari_bionet.c	Sun Dec 22 16:37:31 1996
+++ linux/drivers/net/atari_bionet.c	Tue Dec 31 10:30:00 1996
@@ -2,7 +2,7 @@
  *
  * Version:	@(#)bionet.c	1.0	02/06/96
  *
- * Author:	Hartmut Laue <laue@ifk-mp.uni-kiel.de> 
+ * Author:	Hartmut Laue <laue@ifk-mp.uni-kiel.de>
  * and		Torsten Narjes <narjes@ifk-mp.uni-kiel.de>
  *
  * Little adaptions for integration into pl7 by Roman Hodek
@@ -116,7 +116,7 @@
 #include <asm/atari_acsi.h>
 #include <asm/atari_stdma.h>
 
-  
+
 extern struct device *init_etherdev(struct device *dev, int sizeof_private);
 
 /* use 0 for production, 1 for verification, >2 for debug
@@ -128,6 +128,8 @@
  * Global variable 'bionet_debug'. Can be set at load time by 'insmod'
  */
 unsigned int bionet_debug = NET_DEBUG;
+MODULE_PARM(bionet_debug, "i");
+
 static unsigned int bionet_min_poll_time = 2;
 
 
@@ -177,7 +179,7 @@
 	unsigned int c;
 
 	dma_wd.dma_mode_status = (mod | ((a0) ? 2 : 0) | 0x88);
-	dma_wd.fdc_acces_seccount = cmd; 
+	dma_wd.fdc_acces_seccount = cmd;
 	dma_wd.dma_mode_status = (mod | 0x8a);
 
 	if( !acsi_wait_for_IRQ(HZ/2) )	/* wait for cmd ack */
@@ -268,7 +270,7 @@
 	dma_wd.dma_mode_status	= 0x88;
 	c = dma_wd.fdc_acces_seccount;
 	c = 1;
-  
+
 rend:
 	dma_wd.dma_mode_status	= 0x80;
 	udelay(40);
@@ -333,7 +335,7 @@
 
 	if (!MACH_IS_ATARI || no_more_found)
 		return ENODEV;
-	
+
 	printk("Probing for BioNet 100 Adapter...\n");
 
 	stdma_lock(bionet_intr, NULL);
@@ -342,7 +344,7 @@
 	stdma_release();
 
 	/* Check the first three octets of the S.A. for the manufactor's code.
-	 */ 
+	 */
 
 	if( i < 0
 	||  station_addr[0] != 'B'
@@ -508,7 +510,7 @@
 
 	while(boguscount--) {
 		status = get_frame((unsigned long)phys_nic_packet, 0);
-	  
+
 		if( status != 1 ) break;
 
 		/* Good packet... */
@@ -610,7 +612,7 @@
 #undef	NEXT_DEV
 #define NEXT_DEV	(&bio_dev)
 
-static struct device bio_dev =  
+static struct device bio_dev =
 	{
 		"        ",	/* filled in by register_netdev() */
 		0, 0, 0, 0,	/* memory */
@@ -621,7 +623,7 @@
 int
 init_module(void) {
 	int err;
-	
+
 	if ((err = register_netdev(&bio_dev))) {
 		if (err == -EEXIST)  {
 			printk("BIONET: devices already present. Module not loaded.\n");
@@ -629,13 +631,13 @@
 		return err;
 	}
 	return 0;
-}  
+}
 
 void
 cleanup_module(void) {
 	unregister_netdev(&bio_dev);
 }
-                      
+
 #endif /* MODULE */
 
 /* Local variables:
diff -u --recursive --new-file v2.1.18/linux/drivers/net/atari_pamsnet.c linux/drivers/net/atari_pamsnet.c
--- v2.1.18/linux/drivers/net/atari_pamsnet.c	Sun Dec 22 16:37:31 1996
+++ linux/drivers/net/atari_pamsnet.c	Tue Dec 31 10:30:00 1996
@@ -2,12 +2,12 @@
  *
  * Version:	@(#)PAMsNet.c	0.2ß	03/31/96
  *
- * Author:  Torsten Lang <Torsten.Lang@ap.physik.uni-giessen.de> 
+ * Author:  Torsten Lang <Torsten.Lang@ap.physik.uni-giessen.de>
  *                       <Torsten.Lang@jung.de>
  *
  * This driver is based on my driver PAMSDMA.c for MiNT-Net and
  * on the driver bionet.c written by
- *          Hartmut Laue <laue@ifk-mp.uni-kiel.de> 
+ *          Hartmut Laue <laue@ifk-mp.uni-kiel.de>
  * and      Torsten Narjes <narjes@ifk-mp.uni-kiel.de>
  *
  * Little adaptions for integration into pl7 by Roman Hodek
@@ -114,7 +114,7 @@
 
 #undef READ
 #undef WRITE
-  
+
 extern struct device *init_etherdev(struct device *dev, int sizeof_private);
 
 /* use 0 for production, 1 for verification, >2 for debug
@@ -126,6 +126,8 @@
  * Global variable 'pamsnet_debug'. Can be set at load time by 'insmod'
  */
 unsigned int pamsnet_debug = NET_DEBUG;
+MODULE_PARM(pamsnet_debug, "i");
+
 static unsigned int pamsnet_min_poll_time = 2;
 
 
@@ -195,7 +197,7 @@
  * LUN 7 lets you send and receive packets.
  *
  * Some commands like the INQUIRY command work identical on all used LUNs.
- * 
+ *
  * UNKNOWN1 seems to read some data.
  *          Command length is 6 bytes.
  * UNKNOWN2 seems to read some data (command byte 1 must be !=0). The
@@ -229,7 +231,7 @@
  *          Command length is 6 byte.
  */
 
-enum {UNKNOWN1=3, READPKT=8, UNKNOWN2, WRITEPKT=10, INQUIRY=18, START, 
+enum {UNKNOWN1=3, READPKT=8, UNKNOWN2, WRITEPKT=10, INQUIRY=18, START,
       NUMPKTS=22, UNKNOWN3, UNKNOWN4, UNKNOWN5, DESELECT, STOP};
 
 #define READSECTOR  READPKT
@@ -292,14 +294,14 @@
  */
 
 /* The following lowlevel routines work on physical addresses only and assume
- * that eventually needed buffers are 
+ * that eventually needed buffers are
  * - completely located in ST RAM
  * - are contigous in the physical address space
  */
 
 /* Setup the DMA counter */
 
-static void 
+static void
 setup_dma (address, rw_flag, num_blocks)
 	void *address;
 	unsigned rw_flag;
@@ -321,7 +323,7 @@
 
 /* Send the first byte of an command block */
 
-static int 
+static int
 send_first (target, byte)
 	int target;
 	unsigned char byte;
@@ -342,14 +344,14 @@
 
 /* Send the rest of an command block */
 
-static int 
+static int
 send_1_5 (lun, command, dma)
 	int lun;
 	unsigned char *command;
 	int dma;
 {
 	int i, j;
-	
+
 	for (i=0; i<5; i++) {
 		WRITEBOTH((!i ? (((lun & 0x7) << 5) | (command[i] & 0x1F))
 			      : command[i]),
@@ -365,7 +367,7 @@
 
 /* Read a status byte */
 
-static int 
+static int
 get_status (void)
 {
 	WRITEMODE(DMA_FDC | DMA_WINDOW | REG_ACSI | A1);
@@ -375,7 +377,7 @@
 
 /* Calculate the number of received bytes */
 
-static int 
+static int
 calc_received (start_address)
 	void *start_address;
 {
@@ -435,7 +437,7 @@
 /* inquiry() returns 0 when PAM's DMA found, -1 when timeout, -2 otherwise */
 /* Please note: The buffer is for internal use only but must be defined!   */
 
-static int 
+static int
 inquiry (target, buffer)
 	int target;
 	unsigned char *buffer;
@@ -443,7 +445,7 @@
 	int ret = -1;
 	unsigned char *vbuffer = (unsigned char *)PTOV(buffer);
 	unsigned char cmd_buffer[5];
-	
+
 	if (send_first(target, INQUIRY))
 		goto bad;
 	setup_dma(buffer, READ, 1);
@@ -467,12 +469,12 @@
 	return (ret);
 }
 
-/* 
+/*
  * read_hw_addr() reads the sector containing the hwaddr and returns
  * a pointer to it (virtual address!) or 0 in case of an error
  */
 
-static HADDR 
+static HADDR
 *read_hw_addr(target, buffer)
 	int target;
 	unsigned char *buffer;
@@ -569,7 +571,7 @@
 {
 	int i;
 	HADDR *hwaddr;
-	
+
 	unsigned char station_addr[6];
 	static unsigned version_printed = 0;
 	/* avoid "Probing for..." printed 4 times - the driver is supporting only one adapter now! */
@@ -579,7 +581,7 @@
 		return ENODEV;
 
 	no_more_found = 1;
-	
+
 	printk("Probing for PAM's Net/GK Adapter...\n");
 
 	/* Allocate the DMA buffer here since we need it for probing! */
@@ -613,7 +615,7 @@
 		else
 			memcpy (station_addr, hwaddr, ETH_ALEN);
 	}
-	
+
 	ENABLE_IRQ();
 	stdma_release();
 
@@ -775,7 +777,7 @@
 
 	while(boguscount--) {
 		pkt_len = receivepkt(lance_target, phys_nic_packet);
-	  
+
 		if( pkt_len < 60 ) break;
 
 		/* Good packet... */
@@ -882,7 +884,7 @@
 #undef	NEXT_DEV
 #define NEXT_DEV	(&pam_dev)
 
-static struct device pam_dev =  
+static struct device pam_dev =
 	{
 		"        ",	/* filled in by register_netdev() */
 		0, 0, 0, 0,	/* memory */
@@ -893,7 +895,7 @@
 int
 init_module(void) {
 	int err;
-	
+
 	if ((err = register_netdev(&pam_dev))) {
 		if (err == -EEXIST)  {
 			printk("PAM's Net/GK: devices already present. Module not loaded.\n");
@@ -901,13 +903,13 @@
 		return err;
 	}
 	return 0;
-}  
+}
 
 void
 cleanup_module(void) {
 	unregister_netdev(&pam_dev);
 }
-                      
+
 #endif /* MODULE */
 
 /* Local variables:
diff -u --recursive --new-file v2.1.18/linux/drivers/net/atarilance.c linux/drivers/net/atarilance.c
--- v2.1.18/linux/drivers/net/atarilance.c	Sun Dec 22 16:37:32 1996
+++ linux/drivers/net/atarilance.c	Tue Dec 31 10:30:00 1996
@@ -81,6 +81,7 @@
 #else
 static int lance_debug = 1;
 #endif
+MODULE_PARM(lance_debug, "i");
 
 /* Print debug messages on probing? */
 #undef LANCE_DEBUG_PROBE
@@ -94,7 +95,7 @@
 #ifdef LANCE_DEBUG_PROBE
 # define PROBE_PRINT(a)	printk a
 #else
-# define PROBE_PRINT(a)	
+# define PROBE_PRINT(a)
 #endif
 
 /* These define the number of Rx and Tx buffers as log2. (Only powers
@@ -372,12 +373,12 @@
 
 {	int i;
 	static int found = 0;
-	
+
 	if (!MACH_IS_ATARI || found)
 		/* Assume there's only one board possible... That seems true, since
 		 * the Riebl/PAM board's address cannot be changed. */
 		return( ENODEV );
-	
+
 	for( i = 0; i < N_LANCE_ADDR; ++i ) {
 		if (lance_probe1( dev, &lance_addr_list[i] )) {
 			found = 1;
@@ -402,7 +403,7 @@
 
 	__asm__ __volatile__ ( "movec	%/vbr,%0" : "=r" (vbr) : );
 	save_berr = vbr[2];
-	
+
 	__asm__ __volatile__
 	(	"movel	%/sp,%/d1\n\t"
 		"movel	#Lberr,%2@\n\t"
@@ -436,7 +437,7 @@
 
 	vbr[2] = save_berr;
 	restore_flags(flags);
-	
+
 	return( ret );
 }
 
@@ -453,7 +454,7 @@
 	int 					i;
 	static int 				did_version = 0;
 	unsigned short			save1, save2;
-	
+
 	PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n",
 				  (long)memaddr, (long)ioaddr ));
 
@@ -470,7 +471,7 @@
 	*memaddr = 0x0000;
 	if (*memaddr != 0x0000) goto probe_fail;
 	*memaddr = save1;
-	
+
 	/* First port should be readable and writable */
 	PROBE_PRINT(( "lance_probe1: testing ioport to be accessible\n" ));
 	if (!addr_accessible( ioaddr, 1, 1 )) goto probe_fail;
@@ -505,7 +506,7 @@
 
   probe_fail:
 	return( 0 );
-	
+
   probe_ok:
 	init_etherdev( dev, sizeof(struct lance_private) );
 	if (!dev->priv)
@@ -515,7 +516,7 @@
 	IO = lp->iobase = (struct lance_ioreg *)ioaddr;
 	dev->base_addr = (unsigned long)ioaddr; /* informational only */
 	lp->memcpy_f = init_rec->slow_flag ? slow_memcpy : memcpy;
-	
+
 	REGA( CSR0 ) = CSR0_STOP;
 
 	/* Now test for type: If the eeprom I/O port is readable, it is a
@@ -530,7 +531,7 @@
 	}
 	else
 		lp->cardtype = OLD_RIEBL;
-		
+
 	if (lp->cardtype == PAM_CARD ||
 		memaddr == (unsigned short *)0xffe00000) {
 		/* PAMs card and Riebl on ST use level 5 autovector */
@@ -572,7 +573,7 @@
 	  case PAM_CARD:
 		i = IO->eeprom;
 		for( i = 0; i < 6; ++i )
-			dev->dev_addr[i] = 
+			dev->dev_addr[i] =
 				((((unsigned short *)MEM)[i*2] & 0x0f) << 4) |
 				((((unsigned short *)MEM)[i*2+1] & 0x0f));
 		i = IO->mem;
@@ -585,7 +586,7 @@
 				dev->name );
 		printk( "      Use \"ifconfig hw ether ...\" to set the address.\n" );
 	}
-	
+
 	MEM->init.mode = 0x0000;		/* Disable Rx and Tx. */
 	for( i = 0; i < 6; i++ )
 		MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
@@ -602,7 +603,7 @@
 		IO->ivec = IRQ_SOURCE_TO_VECTOR(dev->irq);
 	else
 		*RIEBL_IVEC_ADDR = IRQ_SOURCE_TO_VECTOR(dev->irq);
-	
+
 	if (did_version++ == 0)
 		DPRINTK( 1, ( version ));
 
@@ -616,7 +617,7 @@
 	dev->start = 0;
 
 	memset( &lp->stats, 0, sizeof(lp->stats) );
-	
+
 	return( 1 );
 }
 
@@ -632,12 +633,12 @@
 	lance_init_ring(dev);
 	/* Re-initialize the LANCE, and start it when done. */
 
-	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); 
+	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
 	REGA( CSR2 ) = 0;
 	REGA( CSR1 ) = 0;
 	REGA( CSR0 ) = CSR0_INIT;
 	/* From now on, AREG is kept to point to CSR0 */
-	
+
 	i = 1000000;
 	while (--i > 0)
 		if (DREG & CSR0_IDON)
@@ -670,7 +671,7 @@
 {	struct lance_private *lp = (struct lance_private *)dev->priv;
 	int i;
 	unsigned offset;
-	
+
 	lp->lock = 0;
 	lp->tx_full = 0;
 	lp->cur_rx = lp->cur_tx = 0;
@@ -718,7 +719,7 @@
 	int entry, len;
 	struct lance_tx_head *head;
 	unsigned long flags;
-	
+
 	/* Transmitter timeout, serious problems. */
 	if (dev->tbusy) {
 		int tickssofar = jiffies - dev->trans_start;
@@ -732,7 +733,7 @@
 		 * Always set BSWP after a STOP as STOP puts it back into
 		 * little endian mode.
 		 */
-		REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); 
+		REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
 		lp->stats.tx_errors++;
 #ifndef final_version
 		{	int i;
@@ -808,7 +809,7 @@
 	/* Mask to ring buffer boundary. */
 	entry = lp->cur_tx & TX_RING_MOD_MASK;
 	head  = &(MEM->tx_head[entry]);
-	
+
 	/* Caution: the write order is important here, set the "ownership" bits
 	 * last.
 	 */
@@ -885,7 +886,7 @@
 			while( dirty_tx < lp->cur_tx) {
 				int entry = dirty_tx & TX_RING_MOD_MASK;
 				int status = MEM->tx_head[entry].flag;
-			
+
 				if (status & TMD1_OWN_CHIP)
 					break;			/* It still hasn't been Txed */
 
@@ -965,12 +966,12 @@
 
 	DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name,
 				  MEM->rx_head[entry].flag ));
-	
+
 	/* If we own the next entry, it's a new packet. Send it up. */
 	while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) {
 		struct lance_rx_head *head = &(MEM->rx_head[entry]);
 		int status = head->flag;
-		
+
 		if (status != (RMD1_ENP|RMD1_STP)) {		/* There was an error. */
 			/* There is a tricky error noted by John Murphy,
 			   <murf@perftech.com> to Russ Nelson: Even with full-sized
@@ -1001,7 +1002,7 @@
 						if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag &
 							RMD1_OWN_CHIP)
 							break;
-					
+
 					if (i > RX_RING_SIZE - 2) {
 						lp->stats.rx_dropped++;
 						head->flag |= RMD1_OWN_CHIP;
@@ -1025,7 +1026,7 @@
 						   data[19], data[20], data[21], data[22],
 						   pkt_len );
 				}
-				
+
 				skb->dev = dev;
 				skb_reserve( skb, 2 );	/* 16 byte align */
 				skb_put( skb, pkt_len );	/* Make room */
@@ -1094,7 +1095,7 @@
 	if (!dev->start)
 		/* Only possible if board is already started */
 		return;
-	
+
 	/* We take the simple way out and always enable promiscuous mode. */
 	DREG = CSR0_STOP; /* Temporarily stop the lance. */
 
@@ -1119,7 +1120,7 @@
 	 * Always set BSWP after a STOP as STOP puts it back into
 	 * little endian mode.
 	 */
-	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); 
+	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
 
 	/* Resume normal operation and reset AREG to CSR0 */
 	REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT;
@@ -1133,7 +1134,7 @@
 {	struct lance_private *lp = (struct lance_private *)dev->priv;
 	struct sockaddr *saddr = addr;
 	int i;
-	
+
 	if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL)
 		return( -EOPNOTSUPP );
 
@@ -1150,7 +1151,7 @@
 	lp->memcpy_f( RIEBL_HWADDR_ADDR, dev->dev_addr, 6 );
 	/* set also the magic for future sessions */
 	*RIEBL_MAGIC_ADDR = RIEBL_MAGIC;
-	
+
 	return( 0 );
 }
 
@@ -1158,7 +1159,7 @@
 #ifdef MODULE
 static char devicename[9] = { 0, };
 
-static struct device atarilance_dev =  
+static struct device atarilance_dev =
 {
 	devicename,	/* filled in by register_netdev() */
 	0, 0, 0, 0,	/* memory */
@@ -1169,7 +1170,7 @@
 int init_module(void)
 
 {	int err;
-	
+
 	if ((err = register_netdev( &atarilance_dev ))) {
 		if (err == -EIO)  {
 			printk( "No Atari Lance board found. Module not loaded.\n");
@@ -1177,14 +1178,14 @@
 		return( err );
 	}
 	return( 0 );
-}  
+}
 
 void cleanup_module(void)
 
 {
 	unregister_netdev( &atarilance_dev );
 }
-                      
+
 #endif /* MODULE */
 
 
diff -u --recursive --new-file v2.1.18/linux/drivers/net/baycom.c linux/drivers/net/baycom.c
--- v2.1.18/linux/drivers/net/baycom.c	Wed Dec 18 15:58:47 1996
+++ linux/drivers/net/baycom.c	Tue Dec 31 10:30:00 1996
@@ -33,7 +33,7 @@
  *          hence the name. Since the serial port is not used as an async serial
  *          port, the kernel driver for serial ports cannot be used, and this
  *          driver only supports standard serial hardware (8250, 16450, 16550)
- *  
+ *
  *  par96:  This is a modem for 9600 baud FSK compatible to the G3RUH standard.
  *          The modem does all the filtering and regenerates the receiver clock.
  *          Data is transferred from and to the PC via a shift register.
@@ -45,7 +45,7 @@
  *          from Baycom) and has been replaced by the PICPAR modem (see below).
  *          You may however still build one from the schematics published in
  *          cq-DL :-).
- *  
+ *
  *  picpar: This is a redesign of the par96 modem by Henning Rech, DF9IC. The
  *          modem is protocol compatible to par96, but uses only three low
  *          power ICs and can therefore be fed from the parallel port and
@@ -55,7 +55,7 @@
  *
  *
  *  Command line options (insmod command line)
- * 
+ *
  *  mode     driver mode string. Valid choices are ser12 and par96. An
  *           optional * enables software DCD.
  *           2=par96/par97, any other value invalid
@@ -63,7 +63,7 @@
  *           0x2f8, 0x3e8, 0x2e8 and for par96/par97 0x378, 0x278, 0x3bc
  *  irq      interrupt line of the port; common values are for ser12 3,4
  *           and for par96/par97 7
- * 
+ *
  *
  *  History:
  *   0.1  26.06.96  Adapted from baycom.c and made network driver interface
@@ -153,7 +153,7 @@
 
 /* ---------------------------------------------------------------------- */
 /*
- * Information that need to be kept for each board. 
+ * Information that need to be kept for each board.
  */
 
 struct baycom_state {
@@ -182,7 +182,7 @@
 			unsigned long scram;
 		} par96;
 	} modem;
-	
+
 #ifdef BAYCOM_DEBUG
 	struct debug_vals {
 		unsigned long last_jiffies;
@@ -205,7 +205,7 @@
 {
 #ifdef BAYCOM_DEBUG
 	unsigned long cur_jiffies = jiffies;
-	/* 
+	/*
 	 * measure the interrupt frequency
 	 */
 	bc->debug_vals.cur_intcnt++;
@@ -224,7 +224,7 @@
  * ===================== SER12 specific routines =========================
  */
 
-static void inline ser12_set_divisor(struct device *dev, 
+static void inline ser12_set_divisor(struct device *dev,
 				     unsigned char divisor)
 {
 	outb(0x81, LCR(dev->base_addr));	/* DLAB = 1 */
@@ -235,7 +235,7 @@
 	 * make sure the next interrupt is generated;
 	 * 0 must be used to power the modem; the modem draws its
 	 * power from the TxD line
-	 */	
+	 */
 	outb(0x00, THR(dev->base_addr));
 	/*
 	 * it is important not to set the divider while transmitting;
@@ -258,7 +258,7 @@
 static inline void ser12_tx(struct device *dev, struct baycom_state *bc)
 {
 	/* one interrupt per channel bit */
-	ser12_set_divisor(dev, 12); 
+	ser12_set_divisor(dev, 12);
 	/*
 	 * first output the last bit (!) then call HDLC transmitter,
 	 * since this may take quite long
@@ -266,7 +266,7 @@
 	outb(0x0e | (!!bc->modem.ser12.tx_bit), MCR(dev->base_addr));
 	if (bc->modem.shreg <= 1)
 		bc->modem.shreg = 0x10000 | hdlcdrv_getbits(&bc->hdrv);
-	bc->modem.ser12.tx_bit = !(bc->modem.ser12.tx_bit ^ 
+	bc->modem.ser12.tx_bit = !(bc->modem.ser12.tx_bit ^
 				   (bc->modem.shreg & 1));
 	bc->modem.shreg >>= 1;
 }
@@ -280,7 +280,7 @@
 	 * do demodulator
 	 */
 	cur_s = inb(MSR(dev->base_addr)) & 0x10;	/* the CTS line */
-	hdlcdrv_channelbit(&bc->hdrv, cur_s); 
+	hdlcdrv_channelbit(&bc->hdrv, cur_s);
 	bc->modem.ser12.dcd_shreg = (bc->modem.ser12.dcd_shreg << 1) |
 		(cur_s != bc->modem.ser12.last_sample);
 	bc->modem.ser12.last_sample = cur_s;
@@ -301,7 +301,7 @@
 			bc->modem.ser12.dcd_sum0--;
 	}
 	if(!bc->modem.ser12.dcd_time) {
-		hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 + 
+		hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
 					   bc->modem.ser12.dcd_sum1 +
 					   bc->modem.ser12.dcd_sum2) < 0);
 		bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
@@ -342,14 +342,14 @@
 				break;
 			}
 			bc->modem.shreg >>= 1;
-			if (bc->modem.ser12.last_sample == 
+			if (bc->modem.ser12.last_sample ==
 			    bc->modem.ser12.last_rxbit)
 				bc->modem.shreg |= 0x10000;
-			bc->modem.ser12.last_rxbit = 
+			bc->modem.ser12.last_rxbit =
 				bc->modem.ser12.last_sample;
 		}
 		if (++bc->modem.ser12.interm_sample >= 3)
-			bc->modem.ser12.interm_sample = 0;	
+			bc->modem.ser12.interm_sample = 0;
 		/*
 		 * DCD stuff
 		 */
@@ -365,7 +365,7 @@
 			dcdsneg += ((bc->modem.ser12.dcd_shreg >> 4) & 1);
 
 			bc->modem.ser12.dcd_sum0 += 16*dcdspos - dcdsneg;
-		} 
+		}
 	} else {
 		/*
 		 * PLL algorithm for the hardware squelch DCD algorithm
@@ -397,10 +397,10 @@
 				break;
 			}
 			bc->modem.shreg >>= 1;
-			if (bc->modem.ser12.last_sample == 
+			if (bc->modem.ser12.last_sample ==
 			    bc->modem.ser12.last_rxbit)
 				bc->modem.shreg |= 0x10000;
-			bc->modem.ser12.last_rxbit = 
+			bc->modem.ser12.last_rxbit =
 				bc->modem.ser12.last_sample;
 		}
 		bc->modem.ser12.interm_sample = !bc->modem.ser12.interm_sample;
@@ -415,7 +415,7 @@
 		bc->modem.shreg = 0x10000;
 	}
 	if(!bc->modem.ser12.dcd_time) {
-		hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 + 
+		hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
 					   bc->modem.ser12.dcd_sum1 +
 					   bc->modem.ser12.dcd_sum2) < 0);
 		bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
@@ -433,7 +433,7 @@
 {
 	struct device *dev = (struct device *)dev_id;
 	struct baycom_state *bc = (struct baycom_state *)dev->priv;
-	
+
 	if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC)
 		return;
 
@@ -477,7 +477,7 @@
 	b3 = inb(MSR(iobase)) & 0xf0;
 	outb(b1, MCR(iobase));			/* restore old values */
 	outb(b2, MSR(iobase));
-	if (b3 != 0x90) 
+	if (b3 != 0x90)
 		return c_uart_unknown;
 	inb(RBR(iobase));
 	inb(RBR(iobase));
@@ -488,7 +488,7 @@
 		b1 = inb(SCR(iobase));
 		outb(0xa5, SCR(iobase));
 		b2 = inb(SCR(iobase));
-		if ((b1 != 0x5a) || (b2 != 0xa5)) 
+		if ((b1 != 0x5a) || (b2 != 0xa5))
 			u = c_uart_8250;
 	}
 	return u;
@@ -496,14 +496,14 @@
 
 /* --------------------------------------------------------------------- */
 
-static int ser12_open(struct device *dev) 
+static int ser12_open(struct device *dev)
 {
 	struct baycom_state *bc = (struct baycom_state *)dev->priv;
 	enum uart u;
 
 	if (!dev || !bc)
 		return -ENXIO;
-	if (!dev->base_addr || dev->base_addr > 0x1000-SER12_EXTENT || 
+	if (!dev->base_addr || dev->base_addr > 0x1000-SER12_EXTENT ||
 	    dev->irq < 2 || dev->irq > 15)
 		return -ENXIO;
 	if (check_region(dev->base_addr, SER12_EXTENT))
@@ -516,14 +516,14 @@
 	outb(0x0d, MCR(dev->base_addr));
 	outb(0x0d, MCR(dev->base_addr));
 	outb(0, IER(dev->base_addr));
-	if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT, 
+	if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT,
 			"baycom_ser12", dev))
 		return -EBUSY;
 	request_region(dev->base_addr, SER12_EXTENT, "baycom_ser12");
 	/*
 	 * enable transmitter empty interrupt
 	 */
-	outb(2, IER(dev->base_addr));  
+	outb(2, IER(dev->base_addr));
 	/*
 	 * set the SIO to 6 Bits/character and 19200 or 28800 baud, so that
 	 * we get exactly (hopefully) 2 or 3 interrupts per radio symbol,
@@ -531,7 +531,7 @@
 	 */
 	ser12_set_divisor(dev, (bc->options & BAYCOM_OPTIONS_SOFTDCD) ? 4 : 6);
 	printk(KERN_INFO "%s: ser12 at iobase 0x%lx irq %u options "
-	       "0x%x uart %s\n", bc_drvname, dev->base_addr, dev->irq, 
+	       "0x%x uart %s\n", bc_drvname, dev->base_addr, dev->irq,
 	       bc->options, uart_str[u]);
 	MOD_INC_USE_COUNT;
 	return 0;
@@ -539,7 +539,7 @@
 
 /* --------------------------------------------------------------------- */
 
-static int ser12_close(struct device *dev) 
+static int ser12_close(struct device *dev)
 {
 	struct baycom_state *bc = (struct baycom_state *)dev->priv;
 
@@ -550,7 +550,7 @@
 	 */
 	outb(0, IER(dev->base_addr));
 	outb(1, MCR(dev->base_addr));
-	free_irq(dev->irq, dev);	
+	free_irq(dev->irq, dev);
 	release_region(dev->base_addr, SER12_EXTENT);
 	printk(KERN_INFO "%s: close ser12 at iobase 0x%lx irq %u\n",
 	       bc_drvname, dev->base_addr, dev->irq);
@@ -588,7 +588,7 @@
 		if (!(data & 1))
 			bc->modem.par96.scram ^= 1;
 		if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 1))
-			bc->modem.par96.scram ^= 
+			bc->modem.par96.scram ^=
 				(PAR96_SCRAM_TAPN << 1);
 		if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 2))
 			val |= PAR96_TXBIT;
@@ -611,7 +611,7 @@
 		bc->modem.par96.descram = (bc->modem.par96.descram << 1);
 		if (inb(LPT_STATUS(dev->base_addr)) & PAR96_RXBIT)
 			bc->modem.par96.descram |= 1;
-		descx = bc->modem.par96.descram ^ 
+		descx = bc->modem.par96.descram ^
 			(bc->modem.par96.descram >> 1);
 		/* now the diff decoded data is inverted in descram */
 		outb(PAR97_POWER | PAR96_PTT, LPT_DATA(dev->base_addr));
@@ -620,7 +620,7 @@
 		data >>= 1;
 		if (!(descx & 1))
 			data |= 0x8000;
-		outb(PAR97_POWER | PAR96_PTT | PAR96_BURST, 
+		outb(PAR97_POWER | PAR96_PTT | PAR96_BURST,
 		     LPT_DATA(dev->base_addr));
 	}
 	hdlcdrv_putbits(&bc->hdrv, data);
@@ -631,12 +631,12 @@
 		bc->modem.par96.dcd_shreg = (bc->modem.par96.dcd_shreg >> 16)
 			| (data << 16);
 		/* search for flags and set the dcd counter appropriately */
-		for(mask = 0x1fe00, mask2 = 0xfc00, i = 0; 
+		for(mask = 0x1fe00, mask2 = 0xfc00, i = 0;
 		    i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
 			if ((bc->modem.par96.dcd_shreg & mask) == mask2)
 				bc->modem.par96.dcd_count = HDLCDRV_MAXFLEN+4;
 		/* check for abort/noise sequences */
-		for(mask = 0x1fe00, mask2 = 0x1fe00, i = 0; 
+		for(mask = 0x1fe00, mask2 = 0x1fe00, i = 0;
 		    i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
 			if (((bc->modem.par96.dcd_shreg & mask) == mask2) &&
 			    (bc->modem.par96.dcd_count >= 0))
@@ -657,7 +657,7 @@
 {
 	struct device *dev = (struct device *)dev_id;
 	struct baycom_state *bc = (struct baycom_state *)dev->priv;
-	
+
 	if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC)
 		return;
 
@@ -704,13 +704,13 @@
 
 /* --------------------------------------------------------------------- */
 
-static int par96_open(struct device *dev) 
+static int par96_open(struct device *dev)
 {
 	struct baycom_state *bc = (struct baycom_state *)dev->priv;
 
 	if (!dev || !bc)
 		return -ENXIO;
-	if (!dev->base_addr || dev->base_addr > 0x1000-PAR96_EXTENT || 
+	if (!dev->base_addr || dev->base_addr > 0x1000-PAR96_EXTENT ||
 	    dev->irq < 2 || dev->irq > 15)
 		return -ENXIO;
 	if (check_region(dev->base_addr, PAR96_EXTENT))
@@ -720,34 +720,34 @@
 	if (par96_check_lpt(dev->base_addr))
 		return -EIO;
 	/* disable interrupt */
-	outb(0, LPT_CONTROL(dev->base_addr));          
+	outb(0, LPT_CONTROL(dev->base_addr));
 	 /* switch off PTT */
 	outb(PAR96_PTT | PAR97_POWER, LPT_DATA(dev->base_addr));
 	printk(KERN_INFO "%s: par96 at iobase 0x%lx irq %u options 0x%x\n",
 	       bc_drvname, dev->base_addr, dev->irq, bc->options);
-	if (request_irq(dev->irq, par96_interrupt, SA_INTERRUPT, 
+	if (request_irq(dev->irq, par96_interrupt, SA_INTERRUPT,
 			"baycom_par96", dev))
 		return -EBUSY;
 	request_region(dev->base_addr, PAR96_EXTENT, "baycom_par96");
 	/* enable interrupt */
-	outb(LPT_IRQ_ENABLE, LPT_CONTROL(dev->base_addr)); 
+	outb(LPT_IRQ_ENABLE, LPT_CONTROL(dev->base_addr));
 	MOD_INC_USE_COUNT;
 	return 0;
 }
 
 /* --------------------------------------------------------------------- */
 
-static int par96_close(struct device *dev) 
+static int par96_close(struct device *dev)
 {
 	struct baycom_state *bc = (struct baycom_state *)dev->priv;
 
 	if (!dev || !bc)
 		return -EINVAL;
 	/* disable interrupt */
-	outb(0, LPT_CONTROL(dev->base_addr));  
+	outb(0, LPT_CONTROL(dev->base_addr));
 	/* switch off PTT */
 	outb(PAR96_PTT | PAR97_POWER, LPT_DATA(dev->base_addr));
-	free_irq(dev->irq, dev);	
+	free_irq(dev->irq, dev);
 	release_region(dev->base_addr, PAR96_EXTENT);
 	printk(KERN_INFO "%s: close par96 at iobase 0x%lx irq %u\n",
 	       bc_drvname, dev->base_addr, dev->irq);
@@ -762,7 +762,7 @@
 
 /* --------------------------------------------------------------------- */
 
-static int baycom_ioctl(struct device *dev, struct ifreq *ifr, 
+static int baycom_ioctl(struct device *dev, struct ifreq *ifr,
 			struct hdlcdrv_ioctl *hi, int cmd);
 
 /* --------------------------------------------------------------------- */
@@ -801,7 +801,7 @@
 {
 	struct hdlcdrv_ops *newops = NULL;
 	unsigned long flags;
-	
+
 	if (!strncmp(modestr, "off", 3))
 		newops = &dummy_ops;
 	else if (!strncmp(modestr, "ser12", 5))
@@ -820,14 +820,14 @@
 
 /* --------------------------------------------------------------------- */
 
-static int baycom_ioctl(struct device *dev, struct ifreq *ifr, 
+static int baycom_ioctl(struct device *dev, struct ifreq *ifr,
 			struct hdlcdrv_ioctl *hi, int cmd)
 {
 	struct baycom_state *bc;
 	struct baycom_ioctl bi;
 	int cmd2;
-		
-	if (!dev || !dev->priv || 
+
+	if (!dev || !dev->priv ||
 	    ((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
 		printk(KERN_ERR "bc_ioctl: invalid device struct\n");
 		return -EINVAL;
@@ -841,7 +841,7 @@
 	switch (hi->cmd) {
 	default:
 		break;
-		
+
 	case HDLCDRVCTL_GETMODE:
 		if (bc->hdrv.ops == &ser12_ops)
 			strcpy(hi->data.modename, "ser12");
@@ -868,7 +868,7 @@
 		if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
 			return -EFAULT;
 		return 0;
-		
+
 	case HDLCDRVCTL_MODEMPARMASK:
 		return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ;
 
@@ -900,14 +900,14 @@
 #ifdef MODULE
 static
 #endif /* MODULE */
-int baycom_init(void) 
+int baycom_init(void)
 {
 	int i, j, found = 0;
 	char set_hw = 1;
 	struct baycom_state *bc;
 	char ifname[HDLCDRV_IFNAMELEN];
 
-	
+
 	printk(bc_drvinfo);
 	/*
 	 * register net devices
@@ -920,8 +920,8 @@
 			set_hw = 0;
 		if (!set_hw)
 			baycom_ports[i].iobase = baycom_ports[i].irq = 0;
-		j = hdlcdrv_register_hdlcdrv(dev, &dummy_ops, 
-					     sizeof(struct baycom_state), 
+		j = hdlcdrv_register_hdlcdrv(dev, &dummy_ops,
+					     sizeof(struct baycom_state),
 					     ifname, baycom_ports[i].iobase,
 					     baycom_ports[i].irq, 0);
 		if (!j) {
@@ -949,6 +949,9 @@
 char *mode = NULL;
 int iobase = 0x3f8;
 int irq = 4;
+MODULE_PARM(mode, "s");
+MODULE_PARM(iobase, "i");
+MODULE_PARM(irq, "i");
 
 int init_module(void)
 {
@@ -974,7 +977,7 @@
 			if (bc->hdrv.magic != HDLCDRV_MAGIC)
 				printk(KERN_ERR "baycom: invalid magic in "
 				       "cleanup_module\n");
-			else 
+			else
 				hdlcdrv_unregister_hdlcdrv(dev);
 		}
 	}
diff -u --recursive --new-file v2.1.18/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v2.1.18/linux/drivers/net/de4x5.c	Thu Dec 12 19:37:05 1996
+++ linux/drivers/net/de4x5.c	Tue Dec 31 10:30:00 1996
@@ -54,7 +54,7 @@
     no great  consequence except do make sure  you're not sharing interrupts
     with  anything that cannot  accommodate  interrupt sharing! The existing
     register_netdevice() code will only allow one device to be registered at
-    a time. 
+    a time.
 
     ************************************************************************
     For now, please only use the 'io=??' assignment (see  2. below, ?? != 0)
@@ -64,7 +64,7 @@
     Essentially, the I/O address and IRQ information  are ignored and filled
     in later by  the PCI BIOS   during the PCI  probe.  Note  that the board
     should be in the system at boot time so that its I/O address and IRQ are
-    allocated by the PCI BIOS automatically. 
+    allocated by the PCI BIOS automatically.
 
     To utilise this ability, you have to do 8 things:
 
@@ -76,18 +76,18 @@
     when loading by:
 
                    insmod de4x5.o io=0xghh         where g = bus number
-		                                        hh = device number   
+		                                        hh = device number
 
     3) compile  de4x5.c, but include -DMODULE in  the command line to ensure
     that the correct bits are compiled (see end of source code).
     4) if you are wanting to add a new  card, goto 5. Otherwise, recompile a
     kernel with the de4x5 configuration turned off and reboot.
     5) insmod de4x5.o [io=0xghh]
-    6) run the net startup bits for your new eth?? interface(s) manually 
-    (usually /etc/rc.inet[12] at boot time). 
+    6) run the net startup bits for your new eth?? interface(s) manually
+    (usually /etc/rc.inet[12] at boot time).
     7) enjoy!
 
-    To unload a module, turn off the associated interface(s) 
+    To unload a module, turn off the associated interface(s)
     'ifconfig eth?? down' then 'rmmod de4x5'.
 
     Automedia detection is included so that in  principal you can disconnect
@@ -133,7 +133,7 @@
     ----------------
 
     Version   Date        Description
-  
+
       0.1     17-Nov-94   Initial writing. ALPHA code release.
       0.2     13-Jan-95   Added PCI support for DE435's.
       0.21    19-Jan-95   Added auto media detection.
@@ -142,7 +142,7 @@
 			  Add request/release_region code.
 			  Add loadable modules support for PCI.
 			  Clean up loadable modules support.
-      0.23    28-Feb-95   Added DC21041 and DC21140 support. 
+      0.23    28-Feb-95   Added DC21041 and DC21140 support.
                           Fix missed frame counter value and initialisation.
 			  Fixed EISA probe.
       0.24    11-Apr-95   Change delay routine to use <linux/udelay>.
@@ -171,7 +171,7 @@
                           Add kernel timer code (h/w is too flaky).
 			  Add MII based PHY autosense.
 			  Add new multicasting code.
-			  Add new autosense algorithms for media/mode 
+			  Add new autosense algorithms for media/mode
 			  selection using kernel scheduling/timing.
 			  Re-formatted.
 			  Made changes suggested by <jeff@router.patch.net>:
@@ -198,10 +198,10 @@
                           Add Accton to the list of broken cards.
 			  Fix TX under-run bug for non DC21140 chips.
 			  Fix boot command probe bug in alloc_device() as
-			   reported by <koen.gadeyne@barco.com> and 
+			   reported by <koen.gadeyne@barco.com> and
 			   <orava@nether.tky.hut.fi>.
 			  Add cache locks to prevent a race condition as
-			   reported by <csd@microplex.com> and 
+			   reported by <csd@microplex.com> and
 			   <baba@beckman.uiuc.edu>.
 			  Upgraded alloc_device() code.
       0.431  28-Jun-96    Fix potential bug in queue_pkt() from discussion
@@ -213,7 +213,7 @@
                            with a loopback packet.
       0.442   9-Sep-96    Include AUI in dc21041 media printout. Bug reported
                            by <bhat@mundook.cs.mu.OZ.AU>
-      0.45    8-Dec-96    Include endian functions for PPC use, from work 
+      0.45    8-Dec-96    Include endian functions for PPC use, from work
                            by <cort@cs.nmt.edu>.
 
     =========================================================================
@@ -371,7 +371,7 @@
 ** Memory Alignment. Each descriptor is 4 longwords long. To force a
 ** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
 ** DESC_ALIGN. ALIGN aligns the start address of the private memory area
-** and hence the RX descriptor ring's first entry. 
+** and hence the RX descriptor ring's first entry.
 */
 #define ALIGN4      ((u_long)4 - 1)     /* 1 longword align */
 #define ALIGN8      ((u_long)8 - 1)     /* 2 longword align */
@@ -720,9 +720,9 @@
 
     eisa_probe(dev, iobase);
     pci_probe(dev, iobase);
-    
+
     if ((tmp == num_de4x5s) && (iobase != 0) && loading_module) {
-	printk("%s: de4x5_probe() cannot find device at 0x%04lx.\n", dev->name, 
+	printk("%s: de4x5_probe() cannot find device at 0x%04lx.\n", dev->name,
 	       iobase);
     }
 
@@ -731,10 +731,10 @@
     ** initialised OK
     */
     for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
-    
+
     if (dev->priv) status = 0;
     if (iobase == 0) autoprobed = 1;
-    
+
     return status;
 }
 
@@ -745,20 +745,20 @@
     int tmpbus, tmpchs, status=0;
     int i, media = *((char *)&(lp->srom) + *((char *)&(lp->srom) + 19) * 3);
     char *tmp;
-    
+
     /* Ensure we're not sleeping */
     if (lp->chipset == DC21041) {
 	outl(0, PCI_CFDA);
 	de4x5_ms_delay(10);
     }
-    
+
     RESET_DE4X5;
-    
+
     if ((inl(DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
 	return -ENXIO;                       /* Hardware could not reset */
     }
-    
-    /* 
+
+    /*
     ** Now find out what kind of DC21040/DC21041/DC21140 board we have.
     */
     if (lp->bus == PCI) {
@@ -766,46 +766,46 @@
     } else {
 	EISA_signature(name, EISA_ID0);
     }
-    
+
     if (*name == '\0') {                     /* Not found a board signature */
 	return -ENXIO;
     }
-    
+
     dev->base_addr = iobase;
     if (lp->bus == EISA) {
-	printk("%s: %s at 0x%04lx (EISA slot %ld)", 
+	printk("%s: %s at 0x%04lx (EISA slot %ld)",
 	       dev->name, name, iobase, ((iobase>>12)&0x0f));
     } else {                                 /* PCI port address */
 	printk("%s: %s at 0x%04lx (PCI bus %d, device %d)", dev->name, name,
 	       iobase, lp->bus_num, lp->device);
     }
-    
+
     printk(", h/w address ");
     status = get_hw_addr(dev);
     for (i = 0; i < ETH_ALEN - 1; i++) {     /* get the ethernet addr. */
 	printk("%2.2x:", dev->dev_addr[i]);
     }
     printk("%2.2x,\n", dev->dev_addr[i]);
-    
+
     tmpbus = lp->bus;
     tmpchs = lp->chipset;
-    
+
     if (status != 0) {
 	printk("      which has an Ethernet PROM CRC error.\n");
 	return -ENXIO;
     } else {
 	struct de4x5_private *lp;
-	
-	/* 
+
+	/*
 	** Reserve a section of kernel memory for the adapter
 	** private area and the TX/RX descriptor rings.
 	*/
-	dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + ALIGN, 
+	dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + ALIGN,
 				     GFP_KERNEL);
 	if (dev->priv == NULL) {
 	    return -ENOMEM;
 	}
-	
+
 	/*
 	** Align to a longword boundary
 	*/
@@ -828,7 +828,7 @@
 	} else {
 	    mii_get_phy(dev);                      /* Search the MII anyway! */
 	}
-	
+
 	/*
 	** Choose correct autosensing in case someone messed up
 	*/
@@ -847,12 +847,12 @@
 		lp->autosense = de4x5_autosense & 0x00c0;
 	    }
 	}
-	
+
 	sprintf(lp->adapter_name,"%s (%s)", name, dev->name);
-	
+
 	/*
 	** Set up the RX descriptor ring (Intels)
-	** Allocate contiguous receive buffers, long word aligned (Alphas) 
+	** Allocate contiguous receive buffers, long word aligned (Alphas)
 	*/
 #if !defined(__alpha__) && !defined(__powerpc__) && !defined(DE4X5_DO_MEMCPY)
 	for (i=0; i<NUM_RX_DESC; i++) {
@@ -864,7 +864,7 @@
 	}
 
 #else
-	if ((tmp = (void *)kmalloc(RX_BUFF_SZ * NUM_RX_DESC + ALIGN, 
+	if ((tmp = (void *)kmalloc(RX_BUFF_SZ * NUM_RX_DESC + ALIGN,
 				   GFP_KERNEL)) == NULL) {
 	    kfree(lp->cache.priv);
 	    return -ENOMEM;
@@ -882,22 +882,22 @@
 #endif
 
 	barrier();
-	    
+
 	request_region(iobase, (lp->bus == PCI ? DE4X5_PCI_TOTAL_SIZE :
-				DE4X5_EISA_TOTAL_SIZE), 
+				DE4X5_EISA_TOTAL_SIZE),
 		       lp->adapter_name);
-	    
+
 	lp->rxRingSize = NUM_RX_DESC;
 	lp->txRingSize = NUM_TX_DESC;
-	    
+
 	/* Write the end of list marker to the descriptor lists */
 	lp->rx_ring[lp->rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);
 	lp->tx_ring[lp->txRingSize - 1].des1 |= cpu_to_le32(TD_TER);
-	    
+
 	/* Tell the adapter where the TX/RX rings are located. */
 	outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA);
 	outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA);
-	    
+
 	/* Initialise the IRQ mask and Enable/Disable */
 	lp->irq_mask = IMR_RIM | IMR_TIM | IMR_TUM | IMR_UNM;
 	lp->irq_en   = IMR_NIM | IMR_AIM;
@@ -918,11 +918,11 @@
 	       ((lp->bus == PCI) ? "PCI BIOS" : "EISA CNFG"));
 
     }
-    
+
     if (de4x5_debug > 1) {
 	printk(version);
     }
-    
+
     /* The DE4X5-specific entries in the device structure. */
     dev->open = &de4x5_open;
     dev->hard_start_xmit = &de4x5_queue_pkt;
@@ -930,18 +930,18 @@
     dev->get_stats = &de4x5_get_stats;
     dev->set_multicast_list = &set_multicast_list;
     dev->do_ioctl = &de4x5_ioctl;
-    
+
     dev->mem_start = 0;
-    
+
     /* Fill in the generic field of the device structure. */
     ether_setup(dev);
-    
+
     /* Let the adapter sleep to save power */
     if (lp->chipset == DC21041) {
 	outl(0, DE4X5_SICR);
 	outl(CFDA_PSM, PCI_CFDA);
     }
-    
+
     return status;
 }
 
@@ -953,7 +953,7 @@
     u_long iobase = dev->base_addr;
     int i, status = 0;
     s32 omr;
-    
+
     /* Allocate the RX buffers */
     for (i=0; i<lp->rxRingSize; i++) {
 	if (de4x5_alloc_rx_buff(dev, i, 0) == NULL) {
@@ -970,29 +970,29 @@
 	de4x5_ms_delay(10);
     }
 
-    /* 
-    ** Re-initialize the DE4X5... 
+    /*
+    ** Re-initialize the DE4X5...
     */
     status = de4x5_init(dev);
-    
+
     lp->state = OPEN;
     de4x5_dbg_open(dev);
-    
-    if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ, 
+
+    if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ,
 		                                     lp->adapter_name, dev)) {
 	printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq);
 	status = -EAGAIN;
     } else {
-	dev->tbusy = 0;                         
+	dev->tbusy = 0;
 	dev->start = 1;
 	dev->interrupt = UNMASK_INTERRUPTS;
 	dev->trans_start = jiffies;
-	
+
 	START_DE4X5;
-	
+
 	de4x5_setup_intr(dev);
     }
-    
+
     if (de4x5_debug > 1) {
 	printk("\tsts:  0x%08x\n", inl(DE4X5_STS));
 	printk("\tbmr:  0x%08x\n", inl(DE4X5_BMR));
@@ -1003,9 +1003,9 @@
 	printk("\tstrr: 0x%08x\n", inl(DE4X5_STRR));
 	printk("\tsigr: 0x%08x\n", inl(DE4X5_SIGR));
     }
-    
+
     MOD_INC_USE_COUNT;
-    
+
     return status;
 }
 
@@ -1019,15 +1019,15 @@
 */
 static int
 de4x5_init(struct device *dev)
-{  
+{
     /* Lock out other processes whilst setting up the hardware */
     set_bit(0, (void *)&dev->tbusy);
-    
+
     de4x5_sw_reset(dev);
-    
+
     /* Autoconfigure the connected port */
     autoconf_media(dev);
-    
+
     return 0;
 }
 
@@ -1038,22 +1038,22 @@
     u_long iobase = dev->base_addr;
     int i, j, status = 0;
     s32 bmr, omr;
-    
+
     /* Select the MII or SRL port now and RESET the MAC */
     if (lp->phy[lp->active].id == 0) {
 	de4x5_switch_to_srl(dev);
     } else {
 	de4x5_switch_to_mii(dev);
     }
-    
-    /* 
+
+    /*
     ** Set the programmable burst length to 8 longwords for all the DC21140
     ** Fasternet chips and 4 longwords for all others: DMA errors result
     ** without these values. Cache align 16 long.
     */
     bmr = (lp->chipset==DC21140 ? PBL_8 : PBL_4) | DESC_SKIP_LEN | CACHE_ALIGN;
     outl(bmr, DE4X5_BMR);
-    
+
     omr = inl(DE4X5_OMR) & ~OMR_PR;             /* Turn off promiscuous mode */
     if (lp->chipset == DC21140) {
 	omr |= (OMR_SDP | OMR_SB);
@@ -1061,26 +1061,26 @@
     lp->setup_f = PERFECT;
     outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA);
     outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA);
-    
+
     lp->rx_new = lp->rx_old = 0;
     lp->tx_new = lp->tx_old = 0;
-    
+
     for (i = 0; i < lp->rxRingSize; i++) {
 	lp->rx_ring[i].status = cpu_to_le32(R_OWN);
     }
-    
+
     for (i = 0; i < lp->txRingSize; i++) {
 	lp->tx_ring[i].status = cpu_to_le32(0);
     }
-    
+
     barrier();
-    
+
     /* Build the setup frame depending on filtering mode */
     SetMulticastFilter(dev);
-    
+
     load_packet(dev, lp->setup_frame, PERFECT_F|TD_SET|SETUP_FRAME_LEN, NULL);
     outl(omr|OMR_ST, DE4X5_OMR);
-    
+
     /* Poll for setup frame completion (adapter interrupts are disabled now) */
     sti();                                       /* Ensure timer interrupts */
     for (j=0, i=0;(i<500) && (j==0);i++) {       /* Upto 500ms delay */
@@ -1088,20 +1088,20 @@
 	if ((s32)le32_to_cpu(lp->tx_ring[lp->tx_new].status) >= 0) j=1;
     }
     outl(omr, DE4X5_OMR);                        /* Stop everything! */
-    
+
     if (j == 0) {
-	printk("%s: Setup frame timed out, status %08x\n", dev->name, 
+	printk("%s: Setup frame timed out, status %08x\n", dev->name,
 	       inl(DE4X5_STS));
 	status = -EIO;
     }
-    
+
     lp->tx_new = (++lp->tx_new) % lp->txRingSize;
     lp->tx_old = lp->tx_new;
-    
+
     return status;
 }
 
-/* 
+/*
 ** Writes a socket buffer address to the next available transmit descriptor
 */
 static int
@@ -1118,9 +1118,9 @@
 
     set_bit(0, (void*)&dev->tbusy);              /* Stop send re-tries */
     if (lp->tx_enable == NO) {                   /* Cannot send for now */
-	return -1;                                
+	return -1;
     }
-    
+
     /*
     ** Clean out the TX ring asynchronously to interrupts - sometimes the
     ** interrupts are lost by delayed descriptor status updates relative to
@@ -1155,10 +1155,10 @@
 	    set_bit(0, (void*)&dev->tbusy);
 	    load_packet(dev, skb->data, TD_IC | TD_LS | TD_FS | skb->len, skb);
 	    outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */
-		
+
 	    lp->tx_new = (++lp->tx_new) % lp->txRingSize;
 	    dev->trans_start = jiffies;
-		    
+
 	    if (TX_BUFFS_AVAIL) {
 		dev->tbusy = 0;         /* Another pkt may be queued */
 	    }
@@ -1167,15 +1167,15 @@
 	}
 	if (skb) de4x5_putb_cache(dev, skb);
     }
-    
+
     lp->cache.lock = 0;
 
     return status;
 }
 
 /*
-** The DE4X5 interrupt handler. 
-** 
+** The DE4X5 interrupt handler.
+**
 ** I/O Read/Writes through intermediate PCI bridges are never 'posted',
 ** so that the asserted interrupt always has some real data to work with -
 ** if these I/O accesses are ever changed to memory accesses, ensure the
@@ -1191,41 +1191,41 @@
     struct de4x5_private *lp;
     s32 imr, omr, sts, limit;
     u_long iobase;
-    
+
     if (dev == NULL) {
 	printk ("de4x5_interrupt(): irq %d for unknown device.\n", irq);
 	return;
     }
     lp = (struct de4x5_private *)dev->priv;
     iobase = dev->base_addr;
-	
+
     if (dev->interrupt)
       printk("%s: Re-entering the interrupt handler.\n", dev->name);
-	
+
     DISABLE_IRQs;                        /* Ensure non re-entrancy */
     dev->interrupt = MASK_INTERRUPTS;
-	
+
     for (limit=0; limit<8; limit++) {
 	sts = inl(DE4X5_STS);            /* Read IRQ status */
 	outl(sts, DE4X5_STS);            /* Reset the board interrupts */
-	    
+
 	if (!(sts & lp->irq_mask)) break;/* All done */
-	    
+
 	if (sts & (STS_RI | STS_RU))     /* Rx interrupt (packet[s] arrived) */
 	  de4x5_rx(dev);
-	    
+
 	if (sts & (STS_TI | STS_TU))     /* Tx interrupt (packet sent) */
-	  de4x5_tx(dev); 
-	    
+	  de4x5_tx(dev);
+
 	if (sts & STS_LNF) {             /* TP Link has failed */
 	    lp->lostMedia = LOST_MEDIA_THRESHOLD + 1;
 	    lp->irq_mask &= ~IMR_LFM;
 	}
-	    
+
 	if (sts & STS_UNF) {             /* Transmit underrun */
 	    de4x5_txur(dev);
 	}
-	    
+
 	if (sts & STS_SE) {              /* Bus Error */
 	    STOP_DE4X5;
 	    printk("%s: Fatal bus error occurred, sts=%#8x, device stopped.\n",
@@ -1244,7 +1244,7 @@
 
     dev->interrupt = UNMASK_INTERRUPTS;
     ENABLE_IRQs;
-    
+
     return;
 }
 
@@ -1255,11 +1255,11 @@
     u_long iobase = dev->base_addr;
     int entry;
     s32 status;
-    
+
     for (entry=lp->rx_new; (s32)le32_to_cpu(lp->rx_ring[entry].status)>=0;
 	                                                    entry=lp->rx_new) {
 	status = (s32)le32_to_cpu(lp->rx_ring[entry].status);
-	
+
 	if (lp->rx_ovf) {
 	    if (inl(DE4X5_MFC) & MFC_FOCM) {
 		de4x5_rx_ovfc(dev);
@@ -1270,7 +1270,7 @@
 	if (status & RD_FS) {                 /* Remember the start of frame */
 	    lp->rx_old = entry;
 	}
-	
+
 	if (status & RD_LS) {                 /* Valid frame status */
 	    lp->linkOK++;
 	    if (status & RD_ES) {	      /* There was an error. */
@@ -1287,9 +1287,9 @@
 		struct sk_buff *skb;
 		short pkt_len = (short)(le32_to_cpu(lp->rx_ring[entry].status)
 					                            >> 16) - 4;
-		
+
 		if ((skb = de4x5_alloc_rx_buff(dev, entry, pkt_len)) == NULL) {
-		    printk("%s: Insufficient memory; nuking packet.\n", 
+		    printk("%s: Insufficient memory; nuking packet.\n",
 			                                            dev->name);
 		    lp->stats.rx_dropped++;   /* Really, deferred. */
 		    break;
@@ -1299,12 +1299,12 @@
 		/* Push up the protocol stack */
 		skb->protocol=eth_type_trans(skb,dev);
 		netif_rx(skb);
-		    
+
 		/* Update stats */
 		lp->stats.rx_packets++;
 		de4x5_local_stats(dev, skb->data, pkt_len);
 	    }
-	    
+
 	    /* Change buffer ownership for this frame, back to the adapter */
 	    for (;lp->rx_old!=entry;lp->rx_old=(++lp->rx_old)%lp->rxRingSize) {
 		lp->rx_ring[lp->rx_old].status = cpu_to_le32(R_OWN);
@@ -1313,13 +1313,13 @@
 	    lp->rx_ring[entry].status = cpu_to_le32(R_OWN);
 	    barrier();
 	}
-	
+
 	/*
 	** Update entry information
 	*/
 	lp->rx_new = (++lp->rx_new) % lp->rxRingSize;
     }
-    
+
     return 0;
 }
 
@@ -1333,20 +1333,20 @@
     u_long iobase = dev->base_addr;
     int entry;
     s32 status;
-    
+
     for (entry = lp->tx_old; entry != lp->tx_new; entry = lp->tx_old) {
 	status = (s32)le32_to_cpu(lp->tx_ring[entry].status);
 	if (status < 0) {                     /* Buffer not sent yet */
 	    break;
 	} else if (status != 0x7fffffff) {    /* Not setup frame */
 	    if (status & TD_ES) {             /* An error happened */
-		lp->stats.tx_errors++; 
+		lp->stats.tx_errors++;
 		if (status & TD_NC) lp->stats.tx_carrier_errors++;
 		if (status & TD_LC) lp->stats.tx_window_errors++;
 		if (status & TD_UF) lp->stats.tx_fifo_errors++;
 		if (status & TD_EC) lp->pktStats.excessive_collisions++;
 		if (status & TD_DE) lp->stats.tx_aborted_errors++;
-	    
+
 		if (status & (TD_LO | TD_NC | TD_EC | TD_LF)) {
 		    lp->lostMedia++;
 		}
@@ -1359,7 +1359,7 @@
 		lp->linkOK++;
 	    }
 	    /* Update the collision counter */
-	    lp->stats.collisions += ((status & TD_EC) ? 16 : 
+	    lp->stats.collisions += ((status & TD_EC) ? 16 :
 				                      ((status & TD_CC) >> 3));
 
 	    /* Free the buffer. */
@@ -1368,7 +1368,7 @@
 		lp->tx_skb[entry] = NULL;
 	    }
 	}
-	
+
 	/* Update all the pointers */
 	lp->tx_old = (++lp->tx_old) % lp->txRingSize;
     }
@@ -1377,7 +1377,7 @@
 	dev->tbusy = 0;                  /* Clear TX busy flag */
 	if (dev->interrupt) mark_bh(NET_BH);
     }
-	
+
     return 0;
 }
 
@@ -1386,9 +1386,9 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int next_tick = DE4X5_AUTOSENSE_MS;
-    
+
     disable_ast(dev);
-    
+
     if (lp->chipset == DC21140) {
 	next_tick = dc21140m_autoconf(dev);
     } else if (lp->chipset == DC21041) {
@@ -1398,7 +1398,7 @@
     }
     lp->linkOK = 0;
     enable_ast(dev, next_tick);
-    
+
     return 0;
 }
 
@@ -1421,11 +1421,11 @@
 	}
 	outl(omr | OMR_ST | OMR_SR, DE4X5_OMR);
     }
-    
+
     return 0;
 }
 
-static int 
+static int
 de4x5_rx_ovfc(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
@@ -1442,7 +1442,7 @@
     }
 
     outl(omr, DE4X5_OMR);
-    
+
     return 0;
 }
 
@@ -1452,22 +1452,22 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     s32 imr, omr;
-    
+
     disable_ast(dev);
     dev->start = 0;
     dev->tbusy = 1;
-    
+
     if (de4x5_debug > 1) {
 	printk("%s: Shutting down ethercard, status was %8.8x.\n",
 	       dev->name, inl(DE4X5_STS));
     }
-    
-    /* 
+
+    /*
     ** We stop the DE4X5 here... mask interrupts and stop TX & RX
     */
     DISABLE_IRQs;
     STOP_DE4X5;
-    
+
     /* Free the associated irq */
     free_irq(dev->irq, dev);
     lp->state = CLOSED;
@@ -1475,15 +1475,15 @@
     /* Free any socket buffers */
     de4x5_free_rx_buffs(dev);
     de4x5_free_tx_buffs(dev);
-    
+
     MOD_DEC_USE_COUNT;
-    
+
     /* Put the adapter to sleep to save power */
     if (lp->chipset == DC21041) {
 	outl(0, DE4X5_SICR);
 	outl(CFDA_PSM, PCI_CFDA);
     }
-    
+
     return 0;
 }
 
@@ -1492,9 +1492,9 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     lp->stats.rx_missed_errors = (int)(inl(DE4X5_MFC) & (MFC_OVFL | MFC_CNTR));
-    
+
     return &lp->stats;
 }
 
@@ -1520,7 +1520,7 @@
 	       (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) {
         lp->pktStats.unicast++;
     }
-		
+
     lp->pktStats.bins[0]++;       /* Duplicates stats.rx_packets */
     if (lp->pktStats.bins[0] == 0) { /* Reset counters */
         memset((char *)&lp->pktStats, 0, sizeof(lp->pktStats));
@@ -1533,7 +1533,7 @@
 load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
-    
+
     lp->tx_ring[lp->tx_new].buf = cpu_to_le32(virt_to_bus(buf));
     lp->tx_ring[lp->tx_new].des1 &= cpu_to_le32(TD_TER);
     lp->tx_ring[lp->tx_new].des1 |= cpu_to_le32(flags);
@@ -1541,7 +1541,7 @@
     barrier();
     lp->tx_ring[lp->tx_new].status = cpu_to_le32(T_OWN);
     barrier();
-    
+
     return;
 }
 
@@ -1553,7 +1553,7 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     /* First, double check that the adapter is open */
     if (lp->state == OPEN) {
 	if (dev->flags & IFF_PROMISC) {         /* set promiscuous mode */
@@ -1561,17 +1561,17 @@
 	    omr = inl(DE4X5_OMR);
 	    omr |= OMR_PR;
 	    outl(omr, DE4X5_OMR);
-	} else { 
+	} else {
 	    SetMulticastFilter(dev);
-	    load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | 
+	    load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
 			                                SETUP_FRAME_LEN, NULL);
-	    
+
 	    lp->tx_new = (++lp->tx_new) % lp->txRingSize;
 	    outl(POLL_DEMAND, DE4X5_TPD);       /* Start the TX */
 	    dev->trans_start = jiffies;
 	}
     }
-    
+
     return;
 }
 
@@ -1591,30 +1591,30 @@
     u32 omr, crc, poly = CRC_POLYNOMIAL_LE;
     char *pa;
     unsigned char *addrs;
-    
+
     omr = inl(DE4X5_OMR);
     omr &= ~(OMR_PR | OMR_PM);
     pa = build_setup_frame(dev, ALL);        /* Build the basic frame */
-    
+
     if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 14)) {
 	omr |= OMR_PM;                       /* Pass all multicasts */
     } else if (lp->setup_f == HASH_PERF) {   /* Hash Filtering */
 	for (i=0;i<dev->mc_count;i++) {      /* for each address in the list */
 	    addrs=dmi->dmi_addr;
 	    dmi=dmi->next;
-	    if ((*addrs & 0x01) == 1) {      /* multicast address? */ 
+	    if ((*addrs & 0x01) == 1) {      /* multicast address? */
 		crc = 0xffffffff;            /* init CRC for each address */
 		for (byte=0;byte<ETH_ALEN;byte++) {/* for each address byte */
-		                             /* process each address bit */ 
+		                             /* process each address bit */
 		    for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
 			crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0);
 		    }
 		}
 		hashcode = crc & HASH_BITS;  /* hashcode is 9 LSb of CRC */
-		
+
 		byte = hashcode >> 3;        /* bit[3-8] -> byte in filter */
 		bit = 1 << (hashcode & 0x07);/* bit[0-2] -> bit in byte */
-		
+
 		byte <<= 1;                  /* calc offset into setup frame */
 		if (byte & 0x02) {
 		    byte -= 1;
@@ -1626,14 +1626,14 @@
 	for (j=0; j<dev->mc_count; j++) {
 	    addrs=dmi->dmi_addr;
 	    dmi=dmi->next;
-	    for (i=0; i<ETH_ALEN; i++) { 
+	    for (i=0; i<ETH_ALEN; i++) {
 		*(pa + (i&1)) = *addrs++;
 		if (i & 0x01) pa += 4;
 	    }
 	}
     }
     outl(omr, DE4X5_OMR);
-    
+
     return;
 }
 
@@ -1651,11 +1651,11 @@
     struct bus_type *lp = &bus;
     char name[DE4X5_STRLEN];
     struct device *tmp;
-    
+
     if (!ioaddr && autoprobed) return;     /* Been here before ! */
-    
+
     lp->bus = EISA;
-    
+
     if (ioaddr == 0) {                     /* Autoprobing */
 	iobase = EISA_SLOT_INC;            /* Get the first slot address */
 	i = 1;
@@ -1665,14 +1665,14 @@
 	i = (ioaddr >> 12);
 	maxSlots = i + 1;
     }
-    
+
     for (status = -ENODEV; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
 	if (EISA_signature(name, EISA_ID)) {
 	    cfid = inl(PCI_CFID);
 	    cfrv = inl(PCI_CFRV);
 	    device = (u_short)(cfid >> 16);
 	    vendor = (u_short) cfid;
-	    
+
 	    /* Read the EISA Configuration Registers */
 	    dev->irq = inb(EISA_REG0);
 	    dev->irq = de4x5_irq[(dev->irq >> 1) & 0x03];
@@ -1683,7 +1683,7 @@
 	    outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS);
 	    outl(0x00006000, PCI_CFLT);
 	    outl(iobase, PCI_CBIO);
-	    
+
 	    if (check_region(iobase, DE4X5_EISA_TOTAL_SIZE) == 0) {
 		if ((tmp = alloc_device(dev, iobase)) != NULL) {
 		    if ((status = de4x5_hw_init(tmp, iobase)) == 0) {
@@ -1695,7 +1695,7 @@
 	    }
 	}
     }
-    
+
     return;
 }
 
@@ -1726,11 +1726,11 @@
     struct device *tmp;
 
     if ((!ioaddr || !loading_module) && autoprobed) return;
-    
+
     if (!pcibios_present()) return;          /* No PCI bus in this machine! */
-    
+
     lp->bus = PCI;
-    
+
     if ((ioaddr < 0x1000) && loading_module) {
 	pbus = (u_short)(ioaddr >> 8);
 	dnum = (u_short)(ioaddr & 0xff);
@@ -1739,11 +1739,11 @@
 	dnum = 0;
     }
 
-    for (index=0; 
+    for (index=0;
 	 (pcibios_find_class(class, index, &pb, &dev_fn)!= PCIBIOS_DEVICE_NOT_FOUND);
 	 index++) {
 	dev_num = PCI_SLOT(dev_fn);
-	
+
 	if ((!pbus && !dnum) || ((pbus == pb) && (dnum == dev_num))) {
 	    pcibios_read_config_word(pb, PCI_DEVICE, PCI_VENDOR_ID, &vendor);
 	    pcibios_read_config_word(pb, PCI_DEVICE, PCI_DEVICE_ID, &device);
@@ -1752,10 +1752,10 @@
 	    /* Set the device number information */
 	    lp->device = dev_num;
 	    lp->bus_num = pb;
-	    
+
 	    /* Set the chipset information */
 	    lp->chipset = device;
-	    
+
 	    /* Get the chip configuration revision register */
 	    pcibios_read_config_dword(pb, PCI_DEVICE, PCI_REVISION_ID, &cfrv);
 
@@ -1766,7 +1766,7 @@
 	    /* Fetch the IRQ to be used */
 	    pcibios_read_config_byte(pb, PCI_DEVICE, PCI_INTERRUPT_LINE, &irq);
 	    if ((irq == 0) || (irq == (u_char) 0xff)) continue;
-	    
+
 	    /* Check if I/O accesses and Bus Mastering are enabled */
 	    pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status);
 	    if (!(status & PCI_COMMAND_IO)) continue;
@@ -1786,12 +1786,12 @@
 		    }
 		}
 	    } else if (autoprobed) {
-		printk("%s: region already allocated at 0x%04x.\n", dev->name, 
+		printk("%s: region already allocated at 0x%04x.\n", dev->name,
 		       (u_short)iobase);
 	    }
 	}
     }
-    
+
     return;
 }
 
@@ -1809,7 +1809,7 @@
 
     num_eth = de4x5_dev_index(dev->name);
     if (loading_module) return dev;
-    
+
     while (1) {
 	if (((dev->base_addr == DE4X5_NDA) || (dev->base_addr==0)) && !adev) {
 	    adev=dev;
@@ -1832,13 +1832,13 @@
 	new_dev = 0;
     }
 
-    if (((dev->next == NULL) &&  
+    if (((dev->next == NULL) &&
 	((dev->base_addr != DE4X5_NDA) && (dev->base_addr != 0)) && !fixed) ||
 	new_dev) {
 	num_eth++;                         /* New device */
 	dev = insert_device(dev, iobase, de4x5_probe);
     }
-    
+
     return dev;
 }
 
@@ -1891,7 +1891,7 @@
 ** Auto configure the media here rather than setting the port at compile
 ** time. This routine is called by de4x5_init() and when a loss of media is
 ** detected (excessive collisions, loss of carrier, no carrier or link fail
-** [TP] or no recent receive activity) to check whether the user has been 
+** [TP] or no recent receive activity) to check whether the user has been
 ** sneaky and changed the port on us.
 */
 static int
@@ -1900,7 +1900,7 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     int next_tick = DE4X5_AUTOSENSE_MS;;
-    
+
     lp->linkOK = 0;
     lp->c_media = AUTO;                     /* Bogus last media */
     disable_ast(dev);
@@ -1914,7 +1914,7 @@
 	next_tick = dc21140m_autoconf(dev);
     }
     enable_ast(dev, next_tick);
-    
+
     return (lp->media);
 }
 
@@ -1937,7 +1937,7 @@
     u_long iobase = dev->base_addr;
     int next_tick = DE4X5_AUTOSENSE_MS;
     s32 imr;
-    
+
     switch (lp->media) {
       case INIT:
 	DISABLE_IRQs;
@@ -1956,36 +1956,36 @@
 	lp->local_state = 0;
 	next_tick = dc21040_autoconf(dev);
 	break;
-	
+
       case TP:
-	next_tick = dc21040_state(dev, 0x8f01, 0xffff, 0x0000, 3000, BNC_AUI, 
+	next_tick = dc21040_state(dev, 0x8f01, 0xffff, 0x0000, 3000, BNC_AUI,
 		                                         TP_SUSPECT, test_tp);
 	break;
-	
+
       case TP_SUSPECT:
 	next_tick = de4x5_suspect_state(dev, 1000, TP, test_tp, dc21040_autoconf);
 	break;
-	
+
       case BNC:
       case AUI:
       case BNC_AUI:
-	next_tick = dc21040_state(dev, 0x8f09, 0x0705, 0x0006, 3000, EXT_SIA, 
+	next_tick = dc21040_state(dev, 0x8f09, 0x0705, 0x0006, 3000, EXT_SIA,
 		                                  BNC_AUI_SUSPECT, ping_media);
 	break;
-	
+
       case BNC_AUI_SUSPECT:
 	next_tick = de4x5_suspect_state(dev, 1000, BNC_AUI, ping_media, dc21040_autoconf);
 	break;
-	
+
       case EXT_SIA:
-	next_tick = dc21040_state(dev, 0x3041, 0x0000, 0x0006, 3000, 
+	next_tick = dc21040_state(dev, 0x3041, 0x0000, 0x0006, 3000,
 		                              NC, EXT_SIA_SUSPECT, ping_media);
 	break;
-	
+
       case EXT_SIA_SUSPECT:
 	next_tick = de4x5_suspect_state(dev, 1000, EXT_SIA, ping_media, dc21040_autoconf);
 	break;
-	
+
       case NC:
 	/* default to TP for all */
 	reset_init_sia(dev, 0x8f01, 0xffff, 0x0000);
@@ -1997,13 +1997,13 @@
 	lp->tx_enable = NO;
 	break;
     }
-    
+
     return next_tick;
 }
 
 static int
 dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout,
-	      int next_state, int suspect_state, 
+	      int next_state, int suspect_state,
 	      int (*fn)(struct device *, int))
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
@@ -2016,7 +2016,7 @@
 	lp->local_state++;
 	next_tick = 500;
 	break;
-	    
+
       case 1:
 	if (!lp->tx_enable) {
 	    linkBad = fn(dev, timeout);
@@ -2036,7 +2036,7 @@
 	}
 	break;
     }
-    
+
     return next_tick;
 }
 
@@ -2090,7 +2090,7 @@
     u_long iobase = dev->base_addr;
     s32 sts, irqs, irq_mask, imr, omr;
     int next_tick = DE4X5_AUTOSENSE_MS;
-    
+
     switch (lp->media) {
       case INIT:
 	DISABLE_IRQs;
@@ -2111,7 +2111,7 @@
 	lp->local_state = 0;
 	next_tick = dc21041_autoconf(dev);
 	break;
-	
+
       case TP_NW:
 	if (lp->timeout < 0) {
 	    omr = inl(DE4X5_OMR);/* Set up full duplex for the autonegotiate */
@@ -2131,7 +2131,7 @@
 	    next_tick = dc21041_autoconf(dev);
 	}
 	break;
-	
+
       case ANS:
 	if (!lp->tx_enable) {
 	    irqs = STS_LNP;
@@ -2153,11 +2153,11 @@
 	    next_tick = 3000;
 	}
 	break;
-	
+
       case ANS_SUSPECT:
 	next_tick = de4x5_suspect_state(dev, 1000, ANS, test_tp, dc21041_autoconf);
 	break;
-	
+
       case TP:
 	if (!lp->tx_enable) {
 	    if (lp->timeout < 0) {
@@ -2187,11 +2187,11 @@
 	    next_tick = 3000;
 	}
 	break;
-	
+
       case TP_SUSPECT:
 	next_tick = de4x5_suspect_state(dev, 1000, TP, test_tp, dc21041_autoconf);
 	break;
-	
+
       case AUI:
 	if (!lp->tx_enable) {
 	    if (lp->timeout < 0) {
@@ -2217,11 +2217,11 @@
 	    next_tick = 3000;
 	}
 	break;
-	
+
       case AUI_SUSPECT:
 	next_tick = de4x5_suspect_state(dev, 1000, AUI, ping_media, dc21041_autoconf);
 	break;
-	
+
       case BNC:
 	switch (lp->local_state) {
 	  case 0:
@@ -2239,7 +2239,7 @@
 		next_tick = dc21041_autoconf(dev);
 	    }
 	    break;
-	    
+
 	  case 1:
 	    if (!lp->tx_enable) {
 		if ((sts = ping_media(dev, 3000)) < 0) {
@@ -2259,11 +2259,11 @@
 	    break;
 	}
 	break;
-	
+
       case BNC_SUSPECT:
 	next_tick = de4x5_suspect_state(dev, 1000, BNC, ping_media, dc21041_autoconf);
 	break;
-	
+
       case NC:
 	omr = inl(DE4X5_OMR);    /* Set up full duplex for the autonegotiate */
 	outl(omr | OMR_FD, DE4X5_OMR);
@@ -2276,7 +2276,7 @@
 	lp->tx_enable = NO;
 	break;
     }
-    
+
     return next_tick;
 }
 
@@ -2292,9 +2292,9 @@
     int ana, anlpa, cap, cr, slnk, sr, iobase = dev->base_addr;
     int next_tick = DE4X5_AUTOSENSE_MS;
     u_long imr, omr;
-    
+
     switch(lp->media) {
-      case INIT: 
+      case INIT:
 	DISABLE_IRQs;
 	lp->tx_enable = FALSE;
 	lp->timeout = -1;
@@ -2308,7 +2308,7 @@
 		lp->media = _100Mb;
 	    } else if (lp->autosense == _10Mb) {
 		lp->media = _10Mb;
-	    } else if ((lp->autosense == AUTO) && 
+	    } else if ((lp->autosense == AUTO) &&
 		                     ((sr=is_anc_capable(dev)) & MII_SR_ANC)) {
 		ana = (((sr >> 6) & MII_ANA_TAF) | MII_ANA_CSMA);
 		ana &= (de4x5_full_duplex ? ~0 : ~MII_ANA_FDAM);
@@ -2325,7 +2325,7 @@
 	    next_tick = dc21140m_autoconf(dev);
 	}
 	break;
-	
+
       case ANS:
 	switch (lp->local_state) {
 	  case 0:
@@ -2345,7 +2345,7 @@
 		next_tick = dc21140m_autoconf(dev);
 	    }
 	    break;
-	    
+
 	  case 1:
 	    if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) {
 		next_tick = sr & ~TIMER_CB;
@@ -2356,7 +2356,7 @@
 		    lp->tmp = MII_SR_ASSC;
 		    anlpa = mii_rd(MII_ANLPA, lp->phy[lp->active].addr, DE4X5_MII);
 		    ana = mii_rd(MII_ANA, lp->phy[lp->active].addr, DE4X5_MII);
-		    if (!(anlpa & MII_ANLPA_RF) && 
+		    if (!(anlpa & MII_ANLPA_RF) &&
 			 (cap = anlpa & MII_ANLPA_TAF & ana)) {
 			if (cap & MII_ANA_100M) {
 			    de4x5_full_duplex = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE);
@@ -2373,7 +2373,7 @@
 	    break;
 	}
 	break;
-	
+
       case SPD_DET:                              /* Choose 10Mb/s or 100Mb/s */
         if (lp->timeout < 0) {
 	    lp->tmp = (lp->phy[lp->active].id ? MII_SR_LKS :
@@ -2393,7 +2393,7 @@
 	    next_tick = dc21140m_autoconf(dev);
 	}
 	break;
-	
+
       case _100Mb:                               /* Set 100Mb/s */
 	next_tick = 3000;
 	if (!lp->tx_enable) {
@@ -2408,7 +2408,7 @@
 	    }
 	}
 	break;
-	
+
       case _10Mb:                                /* Set 10Mb/s */
 	next_tick = 3000;
 	if (!lp->tx_enable) {
@@ -2423,7 +2423,7 @@
 	    }
 	}
 	break;
-	
+
       case NC:
         if (lp->media != lp->c_media) {
 	    de4x5_dbg_media(dev);
@@ -2433,7 +2433,7 @@
 	lp->tx_enable = FALSE;
 	break;
     }
-    
+
     return next_tick;
 }
 
@@ -2478,7 +2478,7 @@
 	}
 	next_tick = test_mii_reg(dev, MII_CR, MII_CR_RST, FALSE, 500);
     }
-    
+
     return next_tick;
 }
 
@@ -2488,7 +2488,7 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     s32 sts, csr12;
-    
+
     if (lp->timeout < 0) {
 	lp->timeout = msec/100;
 	reset_init_sia(dev, csr13, csr14, csr15);
@@ -2499,22 +2499,22 @@
 	/* clear all pending interrupts */
 	sts = inl(DE4X5_STS);
 	outl(sts, DE4X5_STS);
-	
+
 	/* clear csr12 NRA and SRA bits */
 	if (lp->chipset == DC21041) {
 	    csr12 = inl(DE4X5_SISR);
 	    outl(csr12, DE4X5_SISR);
 	}
     }
-    
+
     sts = inl(DE4X5_STS) & ~TIMER_CB;
-    
+
     if (!(sts & irqs) && --lp->timeout) {
 	sts = 100 | TIMER_CB;
     } else {
 	lp->timeout = -1;
     }
-    
+
     return sts;
 }
 
@@ -2524,11 +2524,11 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     int sisr;
-    
+
     if (lp->timeout < 0) {
 	lp->timeout = msec/100;
     }
-    
+
     sisr = (inl(DE4X5_SISR) & ~TIMER_CB) & (SISR_LKF | SISR_NCR);
 
     if (sisr && --lp->timeout) {
@@ -2536,7 +2536,7 @@
     } else {
 	lp->timeout = -1;
     }
-    
+
     return sisr;
 }
 
@@ -2546,11 +2546,11 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int iobase = dev->base_addr;
     int gep = 0;
-    
+
     if (lp->timeout < 0) {
 	lp->timeout = msec/100;
     }
-    
+
     if (lp->phy[lp->active].id) {
 	gep = ((is_100_up(dev) && is_spd_100(dev)) ? GEP_SLNK : 0);
     } else {
@@ -2561,7 +2561,7 @@
     } else {
 	lp->timeout = -1;
     }
-    
+
     return gep;
 }
 
@@ -2574,21 +2574,21 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int test, iobase = dev->base_addr;
-    
+
     if (lp->timeout < 0) {
 	lp->timeout = msec/100;
     }
-    
+
     if (pol) pol = ~0;
     reg = mii_rd((u_char)reg, lp->phy[lp->active].addr, DE4X5_MII) & mask;
     test = (reg ^ pol) & mask;
-    
+
     if (test && --lp->timeout) {
 	reg = 100 | TIMER_CB;
     } else {
 	lp->timeout = -1;
     }
-    
+
     return reg;
 }
 
@@ -2598,7 +2598,7 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     int spd;
-    
+
     if (lp->phy[lp->active].id) {
 	spd = mii_rd(lp->phy[lp->active].spd.reg, lp->phy[lp->active].addr, DE4X5_MII);
 	spd = ~(spd ^ lp->phy[lp->active].spd.value);
@@ -2606,7 +2606,7 @@
     } else {
 	spd = ((~inl(DE4X5_GEP)) & GEP_SLNK);
     }
-    
+
     return spd;
 }
 
@@ -2615,7 +2615,7 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     if (lp->phy[lp->active].id) {
 	/* Double read for sticky bits & temporary drops */
 	mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII);
@@ -2630,7 +2630,7 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     if (lp->phy[lp->active].id) {
 	/* Double read for sticky bits & temporary drops */
 	mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII);
@@ -2645,7 +2645,7 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     if (lp->phy[lp->active].id) {
 	return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII));
     } else {
@@ -2663,24 +2663,24 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     int sisr;
-    
+
     if (lp->timeout < 0) {
 	lp->timeout = msec/100;
-	
+
 	lp->tmp = lp->tx_new;                /* Remember the ring position */
 	load_packet(dev, lp->frame, TD_LS | TD_FS | sizeof(lp->frame), NULL);
 	lp->tx_new = (++lp->tx_new) % lp->txRingSize;
 	outl(POLL_DEMAND, DE4X5_TPD);
     }
-    
+
     sisr = inl(DE4X5_SISR);
 
-    if ((!(sisr & SISR_NCR)) && 
-	((s32)le32_to_cpu(lp->tx_ring[lp->tmp].status) < 0) && 
+    if ((!(sisr & SISR_NCR)) &&
+	((s32)le32_to_cpu(lp->tx_ring[lp->tmp].status) < 0) &&
 	 (--lp->timeout)) {
 	sisr = 100 | TIMER_CB;
     } else {
-	if ((!(sisr & SISR_NCR)) && 
+	if ((!(sisr & SISR_NCR)) &&
 	    !(le32_to_cpu(lp->tx_ring[lp->tmp].status) & (T_OWN | TD_ES)) &&
 	    lp->timeout) {
 	    sisr = 0;
@@ -2689,7 +2689,7 @@
 	}
 	lp->timeout = -1;
     }
-    
+
     return sisr;
 }
 
@@ -2736,15 +2736,15 @@
     skb_reserve(p, 2);	                               /* Align */
     if (index < lp->rx_old) {                          /* Wrapped buffer */
 	short tlen = (lp->rxRingSize - lp->rx_old) * RX_BUFF_SZ;
-	memcpy(skb_put(p,tlen), 
+	memcpy(skb_put(p,tlen),
 	       bus_to_virt(le32_to_cpu(lp->rx_ring[lp->rx_old].buf)),tlen);
-	memcpy(skb_put(p,len-tlen), 
+	memcpy(skb_put(p,len-tlen),
 	       bus_to_virt(le32_to_cpu(lp->rx_ring[0].buf)), len-tlen);
     } else {                                           /* Linear buffer */
-	memcpy(skb_put(p,len), 
+	memcpy(skb_put(p,len),
 	       bus_to_virt(le32_to_cpu(lp->rx_ring[lp->rx_old].buf)),len);
     }
-		    
+
     return p;
 #endif
 }
@@ -2831,7 +2831,7 @@
 	lp->cache.save_cnt--;
 	START_DE4X5;
     }
-        
+
     return;
 }
 
@@ -2866,7 +2866,7 @@
 	    }
 	    outl(gep, DE4X5_GEP);
 	} else {
-	    reset_init_sia(dev, lp->cache.csr13, lp->cache.csr14, 
+	    reset_init_sia(dev, lp->cache.csr13, lp->cache.csr14,
 			                                      lp->cache.csr15);
 	}
 	break;
@@ -2928,25 +2928,25 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     s32 sts, ans;
-    
+
     if (lp->timeout < 0) {
 	lp->timeout = msec/100;
 	outl(irq_mask, DE4X5_IMR);
-	
+
 	/* clear all pending interrupts */
 	sts = inl(DE4X5_STS);
 	outl(sts, DE4X5_STS);
     }
-    
+
     ans = inl(DE4X5_SISR) & SISR_ANS;
     sts = inl(DE4X5_STS) & ~TIMER_CB;
-    
+
     if (!(sts & irqs) && (ans ^ ANS_NWOK) && --lp->timeout) {
 	sts = 100 | TIMER_CB;
     } else {
 	lp->timeout = -1;
     }
-    
+
     return sts;
 }
 
@@ -2956,7 +2956,7 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     s32 imr, sts;
-    
+
     if (inl(DE4X5_OMR) & OMR_SR) {   /* Only unmask if TX/RX is enabled */
 	imr = 0;
 	UNMASK_IRQs;
@@ -2964,7 +2964,7 @@
 	outl(sts, DE4X5_STS);
 	ENABLE_IRQs;
     }
-    
+
     return;
 }
 
@@ -2976,7 +2976,7 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     RESET_SIA;
     outl(sigr, DE4X5_SIGR);
     outl(strr, DE4X5_STRR);
@@ -2993,17 +2993,17 @@
 {
     int i;
     char *buf = frame;
-    
+
     for (i=0; i<ETH_ALEN; i++) {             /* Use this source address */
 	*buf++ = dev->dev_addr[i];
     }
     for (i=0; i<ETH_ALEN; i++) {             /* Use this destination address */
 	*buf++ = dev->dev_addr[i];
     }
-    
+
     *buf++ = 0;                              /* Packet length (2 bytes) */
     *buf++ = 1;
-    
+
     return;
 }
 
@@ -3014,7 +3014,7 @@
 de4x5_us_delay(u32 usec)
 {
     udelay(usec);
-    
+
     return;
 }
 
@@ -3025,11 +3025,11 @@
 de4x5_ms_delay(u32 msec)
 {
     u_int i;
-    
+
     for (i=0; i<msec; i++) {
 	de4x5_us_delay(1000);
     }
-    
+
     return;
 }
 
@@ -3047,17 +3047,17 @@
 	char Id[4];
     } Eisa;
     int i, status = 0, siglen = sizeof(signatures)/sizeof(c_char *);
-    
+
     *name = '\0';
     Eisa.ID = inl(eisa_id);
-    
+
     ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40);
     ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40);
     ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30);
     ManCode[3]=((Eisa.Id[2]&0x0f)+0x30);
     ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30);
     ManCode[5]='\0';
-    
+
     for (i=0;i<siglen;i++) {
 	if (strstr(ManCode, signatures[i]) != NULL) {
 	    strcpy(name,ManCode);
@@ -3065,7 +3065,7 @@
 	    break;
 	}
     }
-    
+
     return status;                         /* return the device name string */
 }
 
@@ -3077,7 +3077,7 @@
 {
     c_char *de4x5_signatures[] = DE4X5_SIGNATURE;
     int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *);
-    
+
     if (lp->chipset == DC21040) {
 	strcpy(name, "DE434/5");
     } else {
@@ -3102,7 +3102,7 @@
 			     )))));
 	}
     }
-    
+
     return status;
 }
 
@@ -3115,7 +3115,7 @@
 {
     int i;
     struct bus_type *lp = &bus;
-    
+
     if (lp->chipset == DC21040) {
 	outl(0, aprom_addr);           /* Reset Ethernet Address ROM Pointer */
     } else {                           /* Read new srom */
@@ -3125,7 +3125,7 @@
 	}
 	de4x5_dbg_srom((struct de4x5_srom *)&lp->srom);
     }
-    
+
     return;
 }
 
@@ -3141,7 +3141,7 @@
     for (i=0,k=0,j=0;j<3;j++) {
 	k <<= 1;
 	if (k > 0xffff) k-=0xffff;
-	
+
 	if (lp->bus == PCI) {
 	    if (lp->chipset == DC21040) {
 		while ((tmp = inl(DE4X5_APROM)) < 0);
@@ -3163,11 +3163,11 @@
 	    k += (u_short) ((tmp = inb(EISA_APROM)) << 8);
 	    dev->dev_addr[i++] = (u_char) tmp;
 	}
-	
+
 	if (k > 0xffff) k-=0xffff;
     }
     if (k == 0xffff) k=0;
-    
+
     if (lp->bus == PCI) {
 	if (lp->chipset == DC21040) {
 	    while ((tmp = inl(DE4X5_APROM)) < 0);
@@ -3228,11 +3228,11 @@
 srom_rd(u_long addr, u_char offset)
 {
     sendto_srom(SROM_RD | SROM_SR, addr);
-    
+
     srom_latch(SROM_RD | SROM_SR | DT_CS, addr);
     srom_command(SROM_RD | SROM_SR | DT_IN | DT_CS, addr);
     srom_address(SROM_RD | SROM_SR | DT_CS, addr, offset);
-    
+
     return srom_data(SROM_RD | SROM_SR | DT_CS, addr);
 }
 
@@ -3242,7 +3242,7 @@
     sendto_srom(command, addr);
     sendto_srom(command | DT_CLK, addr);
     sendto_srom(command, addr);
-    
+
     return;
 }
 
@@ -3252,7 +3252,7 @@
     srom_latch(command, addr);
     srom_latch(command, addr);
     srom_latch((command & 0x0000ff00) | DT_CS, addr);
-    
+
     return;
 }
 
@@ -3261,18 +3261,18 @@
 {
     int i;
     char a;
-    
+
     a = (char)(offset << 2);
     for (i=0; i<6; i++, a <<= 1) {
 	srom_latch(command | ((a < 0) ? DT_IN : 0), addr);
     }
     de4x5_us_delay(1);
-    
+
     i = (getfrom_srom(addr) >> 3) & 0x01;
     if (i != 0) {
 	printk("Bad SROM address phase.....\n");
     }
-    
+
     return;
 }
 
@@ -3282,17 +3282,17 @@
     int i;
     short word = 0;
     s32 tmp;
-    
+
     for (i=0; i<16; i++) {
 	sendto_srom(command  | DT_CLK, addr);
 	tmp = getfrom_srom(addr);
 	sendto_srom(command, addr);
-	
+
 	word = (word << 1) | ((tmp >> 3) & 0x01);
     }
-    
+
     sendto_srom(command & 0x0000ff00, addr);
-    
+
     return word;
 }
 
@@ -3301,13 +3301,13 @@
 srom_busy(u_int command, u_long addr)
 {
    sendto_srom((command & 0x0000ff00) | DT_CS, addr);
-   
+
    while (!((getfrom_srom(addr) >> 3) & 0x01)) {
        de4x5_ms_delay(1);
    }
-   
+
    sendto_srom(command & 0x0000ff00, addr);
-   
+
    return;
 }
 */
@@ -3317,7 +3317,7 @@
 {
     outl(command, addr);
     udelay(1);
-    
+
     return;
 }
 
@@ -3325,10 +3325,10 @@
 getfrom_srom(u_long addr)
 {
     s32 tmp;
-    
+
     tmp = inl(addr);
     udelay(1);
-    
+
     return tmp;
 }
 
@@ -3345,7 +3345,7 @@
     mii_address(phyaddr, ioaddr);          /* PHY address to be accessed     */
     mii_address(phyreg, ioaddr);           /* PHY Register to read           */
     mii_ta(MII_STRD, ioaddr);              /* Turn around time - 2 MDC       */
-    
+
     return mii_rdata(ioaddr);              /* Read data                      */
 }
 
@@ -3360,7 +3360,7 @@
     mii_ta(MII_STWR, ioaddr);              /* Turn around time - 2 MDC       */
     data = mii_swap(data, 16);             /* Swap data bit ordering         */
     mii_wdata(data, 16, ioaddr);           /* Write data                     */
-    
+
     return;
 }
 
@@ -3369,12 +3369,12 @@
 {
     int i;
     s32 tmp = 0;
-    
+
     for (i=0; i<16; i++) {
 	tmp <<= 1;
 	tmp |= getfrom_mii(MII_MRD | MII_RD, ioaddr);
     }
-    
+
     return tmp;
 }
 
@@ -3382,12 +3382,12 @@
 mii_wdata(int data, int len, u_long ioaddr)
 {
     int i;
-    
+
     for (i=0; i<len; i++) {
 	sendto_mii(MII_MWR | MII_WR, data, ioaddr);
 	data >>= 1;
     }
-    
+
     return;
 }
 
@@ -3395,13 +3395,13 @@
 mii_address(u_char addr, u_long ioaddr)
 {
     int i;
-    
+
     addr = mii_swap(addr, 5);
     for (i=0; i<5; i++) {
 	sendto_mii(MII_MWR | MII_WR, addr, ioaddr);
 	addr >>= 1;
     }
-    
+
     return;
 }
 
@@ -3409,12 +3409,12 @@
 mii_ta(u_long rw, u_long ioaddr)
 {
     if (rw == MII_STWR) {
-	sendto_mii(MII_MWR | MII_WR, 1, ioaddr);  
-	sendto_mii(MII_MWR | MII_WR, 0, ioaddr);  
+	sendto_mii(MII_MWR | MII_WR, 1, ioaddr);
+	sendto_mii(MII_MWR | MII_WR, 0, ioaddr);
     } else {
 	getfrom_mii(MII_MRD | MII_RD, ioaddr);        /* Tri-state MDIO */
     }
-    
+
     return;
 }
 
@@ -3422,13 +3422,13 @@
 mii_swap(int data, int len)
 {
     int i, tmp = 0;
-    
+
     for (i=0; i<len; i++) {
 	tmp <<= 1;
 	tmp |= (data & 1);
 	data >>= 1;
     }
-    
+
     return tmp;
 }
 
@@ -3436,13 +3436,13 @@
 sendto_mii(u32 command, int data, u_long ioaddr)
 {
     u32 j;
-    
+
     j = (data & 1) << 17;
     outl(command | j, ioaddr);
     udelay(1);
     outl(command | MII_MDC | j, ioaddr);
     udelay(1);
-    
+
     return;
 }
 
@@ -3453,7 +3453,7 @@
     udelay(1);
     outl(command | MII_MDC, ioaddr);
     udelay(1);
-    
+
     return ((inl(ioaddr) >> 19) & 1);
 }
 
@@ -3512,17 +3512,17 @@
     int iobase = dev->base_addr;
     int i, j, k, limit=sizeof(phy_info)/sizeof(struct phy_table);
     int id;
-    
+
     /* Issue a hard PHY reset - Broadcom is screwed up otherwise */
     outl(GEP_HRST, DE4X5_GEP);
     udelay(1000);                                  /* Assert for 1ms */
     outl(0x00, DE4X5_GEP);
     udelay(2000);                                  /* Wait for 2ms */
-    
+
     /* Search the MII address space for possible PHY devices */
     lp->active = 0;
     for (lp->mii_cnt=0, i=1; i<DE4X5_MAX_MII; i++) {
-	id = mii_get_oui(i, DE4X5_MII); 
+	id = mii_get_oui(i, DE4X5_MII);
 	if ((id == 0) || (id == -1)) continue;     /* Valid ID? */
 	for (j=0; j<limit; j++) {                  /* Search PHY table */
 	    if (id != phy_info[j].id) continue;    /* ID match? */
@@ -3542,11 +3542,11 @@
 	for (k=0; lp->phy[k].id && (k < DE4X5_MAX_PHY); k++) { /*For each PHY*/
 	    mii_wr(MII_CR_RST, MII_CR, lp->phy[k].addr, DE4X5_MII);
 	    while (mii_rd(MII_CR, lp->phy[k].addr, DE4X5_MII) & MII_CR_RST);
-	    
+
 	    de4x5_dbg_mii(dev, k);
 	}
     }
-    
+
     return lp->mii_cnt;
 }
 
@@ -3556,12 +3556,12 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int i;
     char *pa = lp->setup_frame;
-    
+
     /* Initialise the setup frame */
     if (mode == ALL) {
 	memset(lp->setup_frame, 0, SETUP_FRAME_LEN);
     }
-    
+
     if (lp->setup_f == HASH_PERF) {
 	for (pa=lp->setup_frame+IMPERF_PA_OFFSET, i=0; i<ETH_ALEN; i++) {
 	    *(pa + i) = dev->dev_addr[i];                 /* Host address */
@@ -3578,7 +3578,7 @@
 	    if (i & 0x01) pa += 4;
 	}
     }
-    
+
     return pa;                     /* Points to the next entry */
 }
 
@@ -3586,7 +3586,7 @@
 enable_ast(struct device *dev, u32 time_out)
 {
     timeout(dev, (void *)&de4x5_ast, (u_long)dev, time_out);
-    
+
     return;
 }
 
@@ -3594,9 +3594,9 @@
 disable_ast(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
-    
+
     del_timer(&lp->timer);
-    
+
     return;
 }
 
@@ -3606,21 +3606,21 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int iobase = dev->base_addr;
     long omr;
-    
+
     /* Assert the OMR_PS bit in CSR6 */
     omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR));
     omr |= (OMR_PS | OMR_HBD);
     outl(omr, DE4X5_OMR);
-    
+
     /* Soft Reset */
     RESET_DE4X5;
-    
+
     /* Restore the GEP */
     if (lp->chipset == DC21140) {
 	outl(GEP_INIT, DE4X5_GEP);
 	outl(0, DE4X5_GEP);
     }
-    
+
     /* Restore CSR6 */
     outl(omr, DE4X5_OMR);
 
@@ -3636,23 +3636,23 @@
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int iobase = dev->base_addr;
     long omr;
-    
+
     /* Deassert the OMR_PS bit in CSR6 */
     omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR));
     outl(omr, DE4X5_OMR);
-    
+
     /* Soft Reset */
     RESET_DE4X5;
-    
+
     /* Restore the GEP */
     if (lp->chipset == DC21140) {
 	outl(GEP_INIT, DE4X5_GEP);
 	outl(0, DE4X5_GEP);
     }
-    
+
     /* Restore CSR6 */
     outl(omr, DE4X5_OMR);
-    
+
     /* Reset CSR8 */
     inl(DE4X5_MFC);
 
@@ -3664,20 +3664,20 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int dt;
-    
+
     /* First, cancel any pending timer events */
     del_timer(&lp->timer);
-    
+
     /* Convert msec to ticks */
     dt = (msec * HZ) / 1000;
     if (dt==0) dt=1;
-    
+
     /* Set up timer */
     lp->timer.expires = jiffies + dt;
     lp->timer.function = fn;
     lp->timer.data = data;
     add_timer(&lp->timer);
-    
+
     return;
 }
 
@@ -3686,7 +3686,7 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int i;
-    
+
     if (de4x5_debug > 1) {
 	printk("%s: de4x5 opening with irq %d\n",dev->name,dev->irq);
 	printk("\tphysical address: ");
@@ -3724,11 +3724,11 @@
 	    }
 	}
 	printk("...0x%8.8x\n", le32_to_cpu(lp->tx_ring[i].buf));
-	printk("Ring size: \nRX: %d\nTX: %d\n", 
-	       (short)lp->rxRingSize, 
-	       (short)lp->txRingSize); 
+	printk("Ring size: \nRX: %d\nTX: %d\n",
+	       (short)lp->rxRingSize,
+	       (short)lp->txRingSize);
     }
-    
+
     return;
 }
 
@@ -3737,7 +3737,7 @@
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int iobase = dev->base_addr;
-    
+
     if (de4x5_debug > 2) {
 	printk("\nMII CR:  %x\n",mii_rd(MII_CR,lp->phy[k].addr,DE4X5_MII));
 	printk("MII SR:  %x\n",mii_rd(MII_SR,lp->phy[k].addr,DE4X5_MII));
@@ -3755,7 +3755,7 @@
 	    printk("MII 20:  %x\n",mii_rd(0x14,lp->phy[k].addr,DE4X5_MII));
 	}
     }
-    
+
     return;
 }
 
@@ -3763,7 +3763,7 @@
 de4x5_dbg_media(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
-    
+
     if (lp->media != lp->c_media) {
 	if (de4x5_debug > 0) {
 	    if (lp->chipset != DC21140) {
@@ -3771,10 +3771,10 @@
 		       (lp->media == NC  ? "unconnected!" :
 			(lp->media == TP  ? "TP." :
 			 (lp->media == ANS ? "TP/Nway." :
-			  (lp->media == BNC ? "BNC." : 
-			   (lp->media == AUI ? "AUI." : 
-			    (lp->media == BNC_AUI ? "BNC/AUI." : 
-			     (lp->media == EXT_SIA ? "EXT SIA." : 
+			  (lp->media == BNC ? "BNC." :
+			   (lp->media == AUI ? "AUI." :
+			    (lp->media == BNC_AUI ? "BNC/AUI." :
+			     (lp->media == EXT_SIA ? "EXT SIA." :
 			      "???."
 			      ))))))));
 	    } else {
@@ -3788,7 +3788,7 @@
 	}
 	lp->c_media = lp->media;
     }
-    
+
     return;
 }
 
@@ -3869,7 +3869,7 @@
 	u16 sval[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
 	u32 lval[(HASH_TABLE_LEN * ETH_ALEN) >> 2];
     } tmp;
-    
+
     switch(ioc->cmd) {
       case DE4X5_GET_HWADDR:           /* Get the hardware address */
 	ioc->len = ETH_ALEN;
@@ -3880,7 +3880,7 @@
 	    tmp.addr[i] = dev->dev_addr[i];
 	}
 	copy_to_user(ioc->data, tmp.addr, ioc->len);
-	
+
 	break;
       case DE4X5_SET_HWADDR:           /* Set the hardware address */
 	status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN);
@@ -3897,12 +3897,12 @@
 	build_setup_frame(dev, PHYS_ADDR_ONLY);
 	/* Set up the descriptor and give ownership to the card */
 	while (set_bit(0, (void *)&dev->tbusy) != 0);/* Wait for lock to free*/
-	load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | 
+	load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
 		                                        SETUP_FRAME_LEN, NULL);
 	lp->tx_new = (++lp->tx_new) % lp->txRingSize;
 	outl(POLL_DEMAND, DE4X5_TPD);                /* Start the TX */
 	dev->tbusy = 0;                              /* Unlock the TX ring */
-	
+
 	break;
       case DE4X5_SET_PROM:             /* Set Promiscuous Mode */
 	if (suser()) {
@@ -3912,7 +3912,7 @@
 	} else {
 	    status = -EPERM;
 	}
-	
+
 	break;
       case DE4X5_CLR_PROM:             /* Clear Promiscuous Mode */
 	if (suser()) {
@@ -3922,19 +3922,19 @@
 	} else {
 	    status = -EPERM;
 	}
-	
+
 	break;
       case DE4X5_SAY_BOO:              /* Say "Boo!" to the kernel log file */
 	printk("%s: Boo!\n", dev->name);
-	
+
 	break;
       case DE4X5_GET_MCA:              /* Get the multicast address table */
 	ioc->len = (HASH_TABLE_LEN >> 3);
 	status = verify_area(VERIFY_WRITE, ioc->data, ioc->len);
 	if (!status) {
-	    copy_to_user(ioc->data, lp->setup_frame, ioc->len); 
+	    copy_to_user(ioc->data, lp->setup_frame, ioc->len);
 	}
-	
+
 	break;
       case DE4X5_SET_MCA:              /* Set a multicast address */
 	if (suser()) {
@@ -3950,7 +3950,7 @@
 	} else {
 	    status = -EPERM;
 	}
-	
+
 	break;
       case DE4X5_CLR_MCA:              /* Clear all multicast addresses */
 	if (suser()) {
@@ -3959,7 +3959,7 @@
 	} else {
 	    status = -EPERM;
 	}
-	
+
 	break;
       case DE4X5_MCA_EN:               /* Enable pass all multicast addressing */
 	if (suser()) {
@@ -3969,18 +3969,18 @@
 	} else {
 	    status = -EPERM;
 	}
-	
+
 	break;
       case DE4X5_GET_STATS:            /* Get the driver statistics */
 	ioc->len = sizeof(lp->pktStats);
 	status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len);
 	if (status)
 	  break;
-	
+
 	cli();
-	copy_to_user(ioc->data, &lp->pktStats, ioc->len); 
+	copy_to_user(ioc->data, &lp->pktStats, ioc->len);
 	sti();
-	
+
 	break;
       case DE4X5_CLR_STATS:            /* Zero out the driver statistics */
 	if (suser()) {
@@ -3990,14 +3990,14 @@
 	} else {
 	    status = -EPERM;
 	}
-	
+
 	break;
       case DE4X5_GET_OMR:              /* Get the OMR Register contents */
 	tmp.addr[0] = inl(DE4X5_OMR);
 	if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, 1))) {
 	    copy_to_user(ioc->data, tmp.addr, 1);
 	}
-	
+
 	break;
       case DE4X5_SET_OMR:              /* Set the OMR Register contents */
 	if (suser()) {
@@ -4008,7 +4008,7 @@
 	} else {
 	    status = -EPERM;
 	}
-	
+
 	break;
       case DE4X5_GET_REG:              /* Get the DE4X5 Registers */
 	j = 0;
@@ -4025,9 +4025,9 @@
 	    copy_to_user(ioc->data, tmp.addr, ioc->len);
 	}
 	break;
-	
+
 #define DE4X5_DUMP              0x0f /* Dump the DE4X5 Status */
-	
+
       case DE4X5_DUMP:
 	j = 0;
 	tmp.addr[j++] = dev->irq;
@@ -4037,7 +4037,7 @@
 	tmp.addr[j++] = lp->rxRingSize;
 	tmp.lval[j>>2] = (long)lp->rx_ring; j+=4;
 	tmp.lval[j>>2] = (long)lp->tx_ring; j+=4;
-	
+
 	for (i=0;i<lp->rxRingSize-1;i++){
 	    if (i < 3) {
 		tmp.lval[j>>2] = (long)&lp->rx_ring[i].status; j+=4;
@@ -4050,7 +4050,7 @@
 	    }
 	}
 	tmp.lval[j>>2] = (long)&lp->tx_ring[i].status; j+=4;
-	
+
 	for (i=0;i<lp->rxRingSize-1;i++){
 	    if (i < 3) {
 		tmp.lval[j>>2] = (s32)le32_to_cpu(lp->rx_ring[i].buf); j+=4;
@@ -4063,14 +4063,14 @@
 	    }
 	}
 	tmp.lval[j>>2] = (s32)le32_to_cpu(lp->tx_ring[i].buf); j+=4;
-	
+
 	for (i=0;i<lp->rxRingSize;i++){
 	    tmp.lval[j>>2] = le32_to_cpu(lp->rx_ring[i].status); j+=4;
 	}
 	for (i=0;i<lp->txRingSize;i++){
 	    tmp.lval[j>>2] = le32_to_cpu(lp->tx_ring[i].status); j+=4;
 	}
-	
+
 	tmp.lval[j>>2] = inl(DE4X5_BMR);  j+=4;
 	tmp.lval[j>>2] = inl(DE4X5_TPD);  j+=4;
 	tmp.lval[j>>2] = inl(DE4X5_RPD);  j+=4;
@@ -4079,18 +4079,18 @@
 	tmp.lval[j>>2] = inl(DE4X5_STS);  j+=4;
 	tmp.lval[j>>2] = inl(DE4X5_OMR);  j+=4;
 	tmp.lval[j>>2] = inl(DE4X5_IMR);  j+=4;
-	tmp.lval[j>>2] = lp->chipset; j+=4; 
+	tmp.lval[j>>2] = lp->chipset; j+=4;
 	if (lp->chipset == DC21140) {
 	    tmp.lval[j>>2] = inl(DE4X5_GEP);  j+=4;
 	} else {
 	    tmp.lval[j>>2] = inl(DE4X5_SISR); j+=4;
 	    tmp.lval[j>>2] = inl(DE4X5_SICR); j+=4;
 	    tmp.lval[j>>2] = inl(DE4X5_STRR); j+=4;
-	    tmp.lval[j>>2] = inl(DE4X5_SIGR); j+=4; 
+	    tmp.lval[j>>2] = inl(DE4X5_SIGR); j+=4;
 	}
-	tmp.lval[j>>2] = lp->phy[lp->active].id; j+=4; 
+	tmp.lval[j>>2] = lp->phy[lp->active].id; j+=4;
 	if (lp->phy[lp->active].id) {
-	    tmp.lval[j>>2] = lp->active; j+=4; 
+	    tmp.lval[j>>2] = lp->active; j+=4;
 	    tmp.lval[j>>2]=mii_rd(MII_CR,lp->phy[lp->active].addr,DE4X5_MII); j+=4;
 	    tmp.lval[j>>2]=mii_rd(MII_SR,lp->phy[lp->active].addr,DE4X5_MII); j+=4;
 	    tmp.lval[j>>2]=mii_rd(MII_ID0,lp->phy[lp->active].addr,DE4X5_MII); j+=4;
@@ -4107,20 +4107,20 @@
 		tmp.lval[j>>2]=mii_rd(0x14,lp->phy[lp->active].addr,DE4X5_MII); j+=4;
 	    }
 	}
-	
+
 	tmp.addr[j++] = lp->txRingSize;
 	tmp.addr[j++] = dev->tbusy;
-	
+
 	ioc->len = j;
 	if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) {
 	    copy_to_user(ioc->data, tmp.addr, ioc->len);
 	}
-	
+
 	break;
       default:
 	status = -EOPNOTSUPP;
     }
-    
+
     return status;
 }
 
@@ -4143,15 +4143,16 @@
     0, 0, 0, NULL, de4x5_probe };
 
 static int io=0x0b; /* EDIT THESE LINES FOR YOUR CONFIGURATION              */
+MODULE_PARM(io, "i");
 
 int
 init_module(void)
 {
     struct device *p  = (struct device *)&thisDE4X5;
-    
+
     thisDE4X5.base_addr = io;                   /* Now autoprobe the module */
     thisDE4X5.irq = 0;
-    
+
     for (; p!=NULL; p=p->next) {
 	if (register_netdev(p) != 0)
 	  return -EIO;
@@ -4166,25 +4167,25 @@
     struct de4x5_private *lp = (struct de4x5_private *) thisDE4X5.priv;
     struct device *p  = (struct device *)&thisDE4X5;
     int keep_loaded = 0;
-    
+
     for (; p!=NULL; p=p->next) {
 	keep_loaded += (p->flags & IFF_UP);     /* Is an interface up?       */
     }
-    
+
     if (keep_loaded) {
 	printk("de4x5: Cannot unload modules - %d interface%s%s still active.\n",
 	       keep_loaded, (keep_loaded>1 ? "s ": " "),
 	       (keep_loaded>1 ? "are": "is"));
 	return;
     }
-    
+
     for (p=thisDE4X5.next; p!=NULL; p=p->next) {
 	if (p->priv) {                          /* Private area allocated?   */
 	    struct de4x5_private *lp = (struct de4x5_private *)p->priv;
 	    if (lp->cache.buf) {                /* MAC buffers allocated?    */
 		kfree(lp->cache.buf);           /* Free the MAC buffers      */
 	    }
-	    release_region(p->base_addr, (lp->bus == PCI ? 
+	    release_region(p->base_addr, (lp->bus == PCI ?
 					  DE4X5_PCI_TOTAL_SIZE :
 					  DE4X5_EISA_TOTAL_SIZE));
 	    kfree(lp->cache.priv);              /* Free the private area     */
@@ -4198,7 +4199,7 @@
             kfree(lp->cache.buf);
 	}
 	release_region(thisDE4X5.base_addr,
-		      (lp->bus == PCI ? 
+		      (lp->bus == PCI ?
 		       DE4X5_PCI_TOTAL_SIZE :
 		       DE4X5_EISA_TOTAL_SIZE));
 	kfree(lp->cache.priv);
diff -u --recursive --new-file v2.1.18/linux/drivers/net/de600.c linux/drivers/net/de600.c
--- v2.1.18/linux/drivers/net/de600.c	Fri Mar  1 07:50:43 1996
+++ linux/drivers/net/de600.c	Tue Dec 31 10:30:00 1996
@@ -36,7 +36,7 @@
  *
  *	You should have received a copy of the GNU General Public License
  *	along with this program; if not, write to the Free Software
- *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  **************************************************************/
 /* Add another "; SLOW_DOWN_IO" here if your adapter won't work OK: */
@@ -89,6 +89,7 @@
 #define PRINTK(x) /**/
 #endif
 unsigned int de600_debug = DE600_DEBUG;
+MODULE_PARM(de600_debug, "i");
 
 #include <linux/module.h>
 
@@ -468,9 +469,9 @@
 		dev->tbusy = !free_tx_pages;
 		select_prn();
 	}
-	
+
 	sti(); /* interrupts back on */
-	
+
 #ifdef FAKE_SMALL_MAX
 	/* This will "patch" the socket TCP proto at an early moment */
 	if (skb->sk && (skb->sk->protocol == IPPROTO_TCP) &&
@@ -613,7 +614,7 @@
 
 	skb->dev = dev;
 	skb_reserve(skb,2);	/* Align */
-	
+
 	/* 'skb->data' points to the start of sk_buff data area. */
 	buffer = skb_put(skb,size);
 
@@ -621,11 +622,11 @@
 	de600_setup_address(read_from, RW_ADDR);
 	for (i = size; i > 0; --i, ++buffer)
 		*buffer = de600_read_byte(READ_DATA, dev);
-	
+
 	((struct netstats *)(dev->priv))->rx_packets++; /* count all receives */
 
 	skb->protocol=eth_type_trans(skb,dev);
-	
+
 	netif_rx(skb);
 	/*
 	 * If any worth-while packets have been received, netif_rx()
@@ -707,9 +708,9 @@
 	dev->hard_start_xmit = &de600_start_xmit;
 
 	ether_setup(dev);
-	
+
 	dev->flags&=~IFF_MULTICAST;
-	
+
 	select_prn();
 	return 0;
 }
diff -u --recursive --new-file v2.1.18/linux/drivers/net/de620.c linux/drivers/net/de620.c
--- v2.1.18/linux/drivers/net/de620.c	Mon Dec 30 15:39:09 1996
+++ linux/drivers/net/de620.c	Tue Dec 31 10:30:00 1996
@@ -35,7 +35,7 @@
  *
  *	You should have received a copy of the GNU General Public License
  *	along with this program; if not, write to the Free Software
- *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *****************************************************************************/
 static const char *version =
@@ -192,6 +192,13 @@
 
 static unsigned int de620_debug = DE620_DEBUG;
 
+MODULE_PARM(bnc, "i");
+MODULE_PARM(utp, "i");
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(clone, "i");
+MODULE_PARM(de620_debug, "i");
+
 /***********************************************
  *                                             *
  * Index to functions, as function prototypes. *
@@ -485,18 +492,18 @@
 
 static void de620_set_multicast_list(struct device *dev)
 {
-	if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 
+	if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
 	{ /* Enable promiscuous mode */
 		/*
 		 *	We must make the kernel realise we had to move
 		 *	into promisc mode or we start all out war on
 		 *	the cable. - AC
 		 */
-		dev->flags|=IFF_PROMISC;		
-	
+		dev->flags|=IFF_PROMISC;
+
 		de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
 	}
-	else 
+	else
 	{ /* Disable promiscuous mode, use normal mode */
 		de620_set_register(dev, W_TCR, TCR_DEF);
 	}
@@ -584,9 +591,9 @@
 	dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
 
 	((struct netstats *)(dev->priv))->tx_packets++;
-	
+
 	restore_flags(flags); /* interrupts maybe back on */
-	
+
 	dev_kfree_skb (skb, FREE_WRITE);
 
 	return 0;
@@ -897,7 +904,7 @@
 	/* base_addr and irq are already set, see above! */
 
 	ether_setup(dev);
-	
+
 	/* dump eeprom */
 	if (de620_debug) {
 		printk("\nEEPROM contents:\n");
diff -u --recursive --new-file v2.1.18/linux/drivers/net/depca.c linux/drivers/net/depca.c
--- v2.1.18/linux/drivers/net/depca.c	Tue Nov 12 15:56:07 1996
+++ linux/drivers/net/depca.c	Tue Dec 31 10:30:00 1996
@@ -4,9 +4,9 @@
 
 
                       Copyright 1994 David C. Davies
-		                   and 
+		                   and
 			 United States Government
-	 (as represented by the Director, National Security Agency).  
+	 (as represented by the Director, National Security Agency).
 
                Copyright 1995  Digital Equipment Corporation.
 
@@ -61,7 +61,7 @@
        Digital Equipment Corporation, 1989
     8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
        Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
-    
+
 
     Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
     driver.
@@ -135,20 +135,20 @@
        [Alan Cox: Changed the code to allow command line irq/io assignments]
        [Dave Davies: Changed the code to allow command line mem/name
                                                                 assignments]
-    6) run the net startup bits for your eth?? interface manually 
-    (usually /etc/rc.inet[12] at boot time). 
+    6) run the net startup bits for your eth?? interface manually
+    (usually /etc/rc.inet[12] at boot time).
     7) enjoy!
 
     Note that autoprobing is not allowed in loadable modules - the system is
     already up and running and you're messing with interrupts.
 
-    To unload a module, turn off the associated interface 
+    To unload a module, turn off the associated interface
     'ifconfig eth?? down' then 'rmmod depca'.
 
     To assign a base memory address for the shared memory  when running as a
     loadable module, see 5 above.  To include the adapter  name (if you have
     no PROM  but know the card name)  also see 5  above. Note that this last
-    option  will not work  with kernel  built-in  depca's. 
+    option  will not work  with kernel  built-in  depca's.
 
     The shared memory assignment for a loadable module  makes sense to avoid
     the 'memory autoprobe' picking the wrong shared memory  (for the case of
@@ -163,7 +163,7 @@
     ----------------
 
     Version   Date        Description
-  
+
       0.1     25-jan-94   Initial writing.
       0.2     27-jan-94   Added LANCE TX hardware buffer chaining.
       0.3      1-feb-94   Added multiple DEPCA support.
@@ -177,7 +177,7 @@
       0.351   30-apr-94   Added EISA support. Added DE422 recognition.
       0.36    16-may-94   DE422 fix released.
       0.37    22-jul-94   Added MODULE support
-      0.38    15-aug-94   Added DBR ROM switch in depca_close(). 
+      0.38    15-aug-94   Added DBR ROM switch in depca_close().
                           Multi DEPCA bug fix.
       0.38axp 15-sep-94   Special version for Alpha AXP Linux V1.0.
       0.381   12-dec-94   Added DE101 recognition, fix multicast bug.
@@ -185,17 +185,17 @@
       0.383   22-feb-95   Fix for conflict with VESA SCSI reported by
                           <stromain@alf.dec.com>
       0.384   17-mar-95   Fix a ring full bug reported by <bkm@star.rl.ac.uk>
-      0.385    3-apr-95   Fix a recognition bug reported by 
+      0.385    3-apr-95   Fix a recognition bug reported by
                                                 <ryan.niemi@lastfrontier.com>
       0.386   21-apr-95   Fix the last fix...sorry, must be galloping senility
       0.40    25-May-95   Rewrite for portability & updated.
                           ALPHA support from <jestabro@amt.tay1.dec.com>
       0.41    26-Jun-95   Added verify_area() calls in depca_ioctl() from
                           suggestion by <heiko@colossus.escape.de>
-      0.42    27-Dec-95   Add 'mem' shared memory assignment for loadable 
+      0.42    27-Dec-95   Add 'mem' shared memory assignment for loadable
                           modules.
                           Add 'adapter_name' for loadable modules when no PROM.
-			  Both above from a suggestion by 
+			  Both above from a suggestion by
 			  <pchen@woodruffs121.residence.gatech.edu>.
 			  Add new multicasting code.
       0.421   22-Apr-96	  Fix alloc_device() bug <jari@markkus2.fimr.fi>
@@ -300,14 +300,14 @@
 ** Memory Alignment. Each descriptor is 4 longwords long. To force a
 ** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
 ** DESC_ALIGN. ALIGN aligns the start address of the private memory area
-** and hence the RX descriptor ring's first entry. 
+** and hence the RX descriptor ring's first entry.
 */
 #define ALIGN4      ((u_long)4 - 1)       /* 1 longword align */
 #define ALIGN8      ((u_long)8 - 1)       /* 2 longword (quadword) align */
 #define ALIGN         ALIGN8              /* Keep the LANCE happy... */
 
 /*
-** The DEPCA Rx and Tx ring descriptors. 
+** The DEPCA Rx and Tx ring descriptors.
 */
 struct depca_rx_desc {
     volatile s32 base;
@@ -454,7 +454,7 @@
     eisa_probe(dev, iobase);
 
     if ((tmp == num_depcas) && (iobase != 0) && loading_module) {
-      printk("%s: depca_probe() cannot find device at 0x%04lx.\n", dev->name, 
+      printk("%s: depca_probe() cannot find device at 0x%04lx.\n", dev->name,
 	                                                               iobase);
     }
 
@@ -496,7 +496,7 @@
       dev->base_addr = ioaddr;
 
       if ((ioaddr&0x0fff)==DEPCA_EISA_IO_PORTS) {/* EISA slot address */
-	printk("%s: %s at 0x%04lx (EISA slot %d)", 
+	printk("%s: %s at 0x%04lx (EISA slot %d)",
 	                    dev->name, name, ioaddr, (int)((ioaddr>>12)&0x0f));
       } else {                             /* ISA port address */
 	printk("%s: %s at 0x%04lx", dev->name, name, ioaddr);
@@ -515,7 +515,7 @@
 	if ((nicsr & _128KB) && (adapter == de422)) netRAM = 128;
 	offset = 0x0000;
 
-	/* Shared Memory Base Address */ 
+	/* Shared Memory Base Address */
 	if (nicsr & BUF) {
 	  offset = 0x8000;              /* 32kbyte RAM offset*/
 	  nicsr &= ~BS;                 /* DEPCA RAM in top 32k */
@@ -533,7 +533,7 @@
 	    nicsr |= SHE;
 	    outb(nicsr, DEPCA_NICSR);
 	  }
- 
+
 	  /* Define the device private memory */
 	  dev->priv = (void *) kmalloc(sizeof(struct depca_private), GFP_KERNEL);
 	  if (dev->priv == NULL)
@@ -591,7 +591,7 @@
 #ifndef MODULE
 	    unsigned char irqnum;
 	    autoirq_setup(0);
-	    
+
 	    /* Assign the correct irq list */
 	    switch (lp->adapter) {
 	    case DEPCA:
@@ -612,7 +612,7 @@
 
 	    /* Trigger an initialization just for the interrupt. */
 	    outw(INEA | INIT, DEPCA_DATA);
-	  
+
 	    irqnum = autoirq_report(1);
 	    if (!irqnum) {
 	      printk(" and failed to detect IRQ line.\n");
@@ -624,7 +624,7 @@
 		  printk(" and uses IRQ%d.\n", dev->irq);
 		}
 	      }
-	      
+
 	      if (!dev->irq) {
 		printk(" but incorrect IRQ line detected.\n");
 		status = -ENXIO;
@@ -636,7 +636,7 @@
 	  }
 	  if (status) release_region(ioaddr, DEPCA_TOTAL_SIZE);
 	} else {
-	  printk(",\n      requests %dkB RAM: only %dkB is available!\n", 
+	  printk(",\n      requests %dkB RAM: only %dkB is available!\n",
 	         	                                (mem_len>>10), netRAM);
 	  status = -ENXIO;
 	}
@@ -661,7 +661,7 @@
       dev->do_ioctl = &depca_ioctl;
 
       dev->mem_start = 0;
-	
+
       /* Fill in the generic field of the device structure. */
       ether_setup(dev);
     } else {                           /* Incorrectly initialised hardware */
@@ -711,11 +711,11 @@
     nicsr = ((nicsr & ~IM & ~LED)|IEN);
     outb(nicsr, DEPCA_NICSR);
     outw(CSR0,DEPCA_ADDR);
-    
-    dev->tbusy = 0;                         
+
+    dev->tbusy = 0;
     dev->interrupt = 0;
     dev->start = 1;
-    
+
     status = InitRestartDepca(dev);
 
     if (depca_debug > 1){
@@ -725,7 +725,7 @@
   }
 
   MOD_INC_USE_COUNT;
-  
+
   return status;
 }
 
@@ -770,8 +770,8 @@
   return;
 }
 
-/* 
-** Writes a socket buffer to TX descriptor ring and starts transmission 
+/*
+** Writes a socket buffer to TX descriptor ring and starts transmission
 */
 static int
 depca_start_xmit(struct sk_buff *skb, struct device *dev)
@@ -788,7 +788,7 @@
     } else {
       printk("%s: transmit timed out, status %04x, resetting.\n",
 	     dev->name, inw(DEPCA_DATA));
-	
+
       STOP_DEPCA;
       depca_init_ring(dev);
       LoadCSRs(dev);
@@ -814,24 +814,24 @@
 	  /* Trigger an immediate send demand. */
 	  outw(CSR0, DEPCA_ADDR);
 	  outw(INEA | TDMD, DEPCA_DATA);
-	  
+
 	  dev->trans_start = jiffies;
 	  dev_kfree_skb(skb, FREE_WRITE);
 	}
 	if (TX_BUFFS_AVAIL) {
 	  dev->tbusy=0;
-	}  
+	}
       } else {
 	status = -1;
       }
     }
   }
-  
+
   return status;
 }
 
 /*
-** The DEPCA interrupt handler. 
+** The DEPCA interrupt handler.
 */
 static void
 depca_interrupt(int irq, void *dev_id, struct pt_regs * regs)
@@ -846,7 +846,7 @@
   } else {
     lp = (struct depca_private *)dev->priv;
     ioaddr = dev->base_addr;
-    
+
     if (dev->interrupt)
       printk("%s: Re-entering the interrupt handler.\n", dev->name);
 
@@ -891,7 +891,7 @@
   int i, entry;
   s32 status;
 
-  for (entry=lp->rx_new; 
+  for (entry=lp->rx_new;
        !(readl(&lp->rx_ring[entry].base) & R_OWN);
        entry=lp->rx_new){
     status = readl(&lp->rx_ring[entry].base) >> 16 ;
@@ -905,7 +905,7 @@
 	if (status & R_OFLO) lp->stats.rx_over_errors++;
 	if (status & R_CRC)  lp->stats.rx_crc_errors++;
 	if (status & R_BUFF) lp->stats.rx_fifo_errors++;
-      } else {	
+      } else {
 	short len, pkt_len = readw(&lp->rx_ring[entry].msg_length);
 	struct sk_buff *skb;
 
@@ -923,13 +923,13 @@
 	    memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], pkt_len);
 	  }
 
-	  /* 
-	  ** Notify the upper protocol layers that there is another 
+	  /*
+	  ** Notify the upper protocol layers that there is another
 	  ** packet to handle
 	  */
 	  skb->protocol=eth_type_trans(skb,dev);
 	  netif_rx(skb);
- 
+
 	  /*
 	  ** Update stats
 	  */
@@ -953,7 +953,7 @@
 		     (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) {
 	    lp->pktStats.unicast++;
 	  }
-	  
+
 	  lp->pktStats.bins[0]++;           /* Duplicates stats.rx_packets */
 	  if (lp->pktStats.bins[0] == 0) {  /* Reset counters */
 	    memset((char *)&lp->pktStats, 0, sizeof(lp->pktStats));
@@ -966,7 +966,7 @@
       }
       /* Change buffer ownership for this last frame, back to the adapter */
       for (; lp->rx_old!=entry; lp->rx_old=(++lp->rx_old)&lp->rxRingMask) {
-	writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN, 
+	writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN,
 	                                        &lp->rx_ring[lp->rx_old].base);
       }
       writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base);
@@ -1039,9 +1039,9 @@
 	   dev->name, inw(DEPCA_DATA));
   }
 
-  /* 
+  /*
   ** We stop the DEPCA here -- it occasionally polls
-  ** memory if we don't. 
+  ** memory if we don't.
   */
   outw(STOP, DEPCA_DATA);
 
@@ -1095,7 +1095,7 @@
   outw(INIT, DEPCA_DATA);                /* initialize DEPCA */
 
   /* wait for lance to complete initialisation */
-  for (i=0;(i<100) && !(inw(DEPCA_DATA) & IDON); i++); 
+  for (i=0;(i<100) && !(inw(DEPCA_DATA) & IDON); i++);
 
   if (i!=100) {
     /* clear IDON by writing a "1", enable interrupts and start lance */
@@ -1131,7 +1131,7 @@
 {
   struct depca_private *lp = (struct depca_private *)dev->priv;
   u_long ioaddr = dev->base_addr;
-  
+
   if (irq2dev_map[dev->irq] != NULL) {
     while(dev->tbusy);                /* Stop ring access */
     set_bit(0, (void*)&dev->tbusy);
@@ -1180,10 +1180,10 @@
     for (i=0;i<dev->mc_count;i++) {        /* for each address in the list */
       addrs=dmi->dmi_addr;
       dmi=dmi->next;
-      if ((*addrs & 0x01) == 1) {          /* multicast address? */ 
+      if ((*addrs & 0x01) == 1) {          /* multicast address? */
 	crc = 0xffffffff;                  /* init CRC for each address */
 	for (byte=0;byte<ETH_ALEN;byte++) {/* for each address byte */
-	                                   /* process each address bit */ 
+	                                   /* process each address bit */
 	  for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
 	    crc = (crc << 1) ^ ((((crc<0?1:0) ^ bit) & 0x01) ? poly : 0);
 	  }
@@ -1191,9 +1191,9 @@
 	hashcode = (crc & 1);              /* hashcode is 6 LSb of CRC ... */
 	for (j=0;j<5;j++) {                /* ... in reverse order. */
 	  hashcode = (hashcode << 1) | ((crc>>=1) & 1);
-	}                                      
-	
-	
+	}
+
+
 	byte = hashcode >> 3;              /* bit[3-5] -> byte in filter */
 	bit = 1 << (hashcode & 0x07);      /* bit[0-2] -> bit in byte */
 	lp->init_block.mcast_table[byte] |= bit;
@@ -1224,7 +1224,7 @@
   }
 
   for (; (i<maxSlots) && (dev!=NULL) && ports[i]; i++) {
-    if (DevicePresent(ports[i]) == 0) { 
+    if (DevicePresent(ports[i]) == 0) {
       if (check_region(ports[i], DEPCA_TOTAL_SIZE) == 0) {
 	if ((dev = alloc_device(dev, ports[i])) != NULL) {
 	  if (depca_hw_init(dev, ports[i]) == 0) {
@@ -1267,7 +1267,7 @@
 
   for (; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
     if (EISA_signature(name, EISA_ID)) {
-      if (DevicePresent(iobase) == 0) { 
+      if (DevicePresent(iobase) == 0) {
 	if (check_region(iobase, DEPCA_TOTAL_SIZE) == 0) {
 	  if ((dev = alloc_device(dev, iobase)) != NULL) {
 	    if (depca_hw_init(dev, iobase) == 0) {
@@ -1299,7 +1299,7 @@
 
     num_eth = depca_dev_index(dev->name);
     if (loading_module) return dev;
-    
+
     while (1) {
 	if (((dev->base_addr == DEPCA_NDA) || (dev->base_addr==0)) && !adev) {
 	    adev=dev;
@@ -1322,13 +1322,13 @@
 	new_dev = 0;
     }
 
-    if (((dev->next == NULL) &&  
+    if (((dev->next == NULL) &&
 	((dev->base_addr != DEPCA_NDA) && (dev->base_addr != 0)) && !fixed) ||
 	new_dev) {
 	num_eth++;                         /* New device */
 	dev = insert_device(dev, iobase, depca_probe);
     }
-    
+
     return dev;
 }
 
@@ -1426,7 +1426,7 @@
 ** if the first address octet is a 0x08 - this minimises the chances of
 ** messing around with some other hardware, but it assumes that this DEPCA
 ** card initialized itself correctly.
-** 
+**
 ** Search the Ethernet address ROM for the signature. Since the ROM address
 ** counter can start at an arbitrary point, the search must include the entire
 ** probe sequence length plus the (length_of_the_signature - 1).
@@ -1456,7 +1456,7 @@
     nicsr |= AAC;
     outb(nicsr, DEPCA_NICSR);
   }
-  
+
   dev.llsig.a = ETH_PROM_SIG;
   dev.llsig.b = ETH_PROM_SIG;
   sigLength = sizeof(u32) << 1;
@@ -1525,7 +1525,7 @@
   entry = lp->tx_new;  		               /* Ring around buffer number. */
   end = (entry + (skb->len - 1) / TX_BUFF_SZ) & lp->txRingMask;
   if (!(readl(&lp->tx_ring[end].base) & T_OWN)) {/* Enough room? */
-    /* 
+    /*
     ** Caution: the write order is important here... don't set up the
     ** ownership rights until all the other information is in place.
     */
@@ -1560,9 +1560,9 @@
                                                /* ownership of packet */
       writel(readl(&lp->tx_ring[i].base) | T_OWN, &lp->tx_ring[i].base);
       if (i == 0) i=lp->txRingMask+1;
-    }   
+    }
     writel(readl(&lp->tx_ring[entry].base) | T_OWN, &lp->tx_ring[entry].base);
- 
+
     lp->tx_new = (++end) & lp->txRingMask;     /* update current pointers */
   } else {
     status = -1;
@@ -1610,7 +1610,7 @@
   struct depca_private *lp = (struct depca_private *)dev->priv;
   u_long ioaddr = dev->base_addr;
   struct depca_init *p = (struct depca_init *)lp->sh_mem;
-  int i; 
+  int i;
 
   if (depca_debug > 1){
     /* Copy the shadow init_block to shared memory */
@@ -1662,11 +1662,11 @@
     printk("\trx_ring at: 0x%8.8x\n",readl(&p->rx_ring));
     printk("\ttx_ring at: 0x%8.8x\n",readl(&p->tx_ring));
     printk("dma_buffs: 0x%8.8lx\n",lp->dma_buffs);
-    printk("Ring size:\nRX: %d  Log2(rxRingMask): 0x%8.8x\n", 
-	   (int)lp->rxRingMask + 1, 
+    printk("Ring size:\nRX: %d  Log2(rxRingMask): 0x%8.8x\n",
+	   (int)lp->rxRingMask + 1,
 	   lp->rx_rlen);
-    printk("TX: %d  Log2(txRingMask): 0x%8.8x\n", 
-	   (int)lp->txRingMask + 1, 
+    printk("TX: %d  Log2(txRingMask): 0x%8.8x\n",
+	   (int)lp->txRingMask + 1,
 	   lp->tx_rlen);
     outw(CSR2,DEPCA_ADDR);
     printk("CSR2&1: 0x%4.4x",inw(DEPCA_DATA));
@@ -1772,7 +1772,7 @@
   case DEPCA_GET_MCA:                /* Get the multicast address table */
     ioc->len = (HASH_TABLE_LEN >> 3);
     if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
-      copy_to_user(ioc->data, lp->init_block.mcast_table, ioc->len); 
+      copy_to_user(ioc->data, lp->init_block.mcast_table, ioc->len);
     }
 
     break;
@@ -1807,7 +1807,7 @@
     cli();
     ioc->len = sizeof(lp->pktStats);
     if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
-      copy_to_user(ioc->data, &lp->pktStats, ioc->len); 
+      copy_to_user(ioc->data, &lp->pktStats, ioc->len);
     }
     sti();
 
@@ -1851,8 +1851,10 @@
 
 static int irq=7;	/* EDIT THESE LINE FOR YOUR CONFIGURATION */
 static int io=0x200;    /* Or use the irq= io= options to insmod */
+MODULE_PARM(irq, "i");
+MODULE_PARM(io, "i");
 
-/* See depca_probe() for autoprobe messages when a module */	
+/* See depca_probe() for autoprobe messages when a module */
 int
 init_module(void)
 {
diff -u --recursive --new-file v2.1.18/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c
--- v2.1.18/linux/drivers/net/dgrs.c	Sun Dec 22 16:37:32 1996
+++ linux/drivers/net/dgrs.c	Tue Dec 31 10:30:01 1996
@@ -886,7 +886,7 @@
 		privN->bcomm->bc_filter_port = ioc.port;
 		privN->bcomm->bc_filter_num = ioc.filter;
 		privN->bcomm->bc_filter_len = ioc.len;
-		
+
 		if (ioc.len)
 		{
 			COPY_FROM_USER(S2HN(privN->bcomm->bc_filter_area),
@@ -914,7 +914,7 @@
 	I596_CB		*cbp;
 	int		cmd;
 	int		i;
-	
+
 	++priv0->intrcnt;
 	if (1) ++priv0->bcomm->bc_cnt[4];
 	if (0)
@@ -1483,7 +1483,7 @@
 				+ (inb(io+ES4H_AS_23_16) << 16);
 
 			irq = is2iv[ inb(io+ES4H_IS) & ES4H_IS_INTMASK ];
-			
+
 			dgrs_found_device(dev, io, mem, irq, 0L, 0L);
 
 			dev = 0;
@@ -1514,6 +1514,15 @@
 static long	ipxnet = -1;
 static int	nicmode = -1;
 
+MODULE_PARM(debug, "i");
+MODULE_PARM(dma, "i");
+MODULE_PARM(hashexpire, "i");
+MODULE_PARM(spantree, "i");
+MODULE_PARM(ipaddr, "1-4i");
+MODULE_PARM(iptrap, "1-4i");
+MODULE_PARM(ipxnet, "i");
+MODULE_PARM(nicmode, "i");
+
 int
 init_module(void)
 {
@@ -1549,13 +1558,13 @@
 			dgrs_iptrap[i] = iptrap[i];
 	if (ipxnet != -1)
 		dgrs_ipxnet = htonl( ipxnet );
-		
+
 	if (dgrs_debug)
 	{
 		printk("dgrs: SW=%s FW=Build %d %s\n",
 			version, dgrs_firmnum, dgrs_firmdate);
 	}
-	
+
 	/*
 	 *	Find and configure all the cards
 	 */
diff -u --recursive --new-file v2.1.18/linux/drivers/net/e2100.c linux/drivers/net/e2100.c
--- v2.1.18/linux/drivers/net/e2100.c	Fri Mar  1 07:50:43 1996
+++ linux/drivers/net/e2100.c	Tue Dec 31 10:30:01 1996
@@ -59,7 +59,7 @@
 #define E21_MEM_ENABLE	0x10
 #define  E21_MEM_ON		0x05	/* Enable memory in 16 bit mode. */
 #define  E21_MEM_ON_8	0x07	/* Enable memory in  8 bit mode. */
-#define E21_MEM_BASE	0x11	
+#define E21_MEM_BASE	0x11
 #define E21_IRQ_LOW		0x12	/* The low three bits of the IRQ number. */
 #define E21_IRQ_HIGH	0x14	/* The high IRQ bit and media select ...  */
 #define E21_MEDIA		0x14	/* (alias). */
@@ -226,7 +226,7 @@
 	   over the 128K region! */
 	if (dev->mem_start == 0)
 		dev->mem_start = 0xd0000;
-	
+
 #ifdef notdef
 	/* These values are unused.  The E2100 has a 2K window into the packet
 	   buffer.  The window can be set to start on any page boundary. */
@@ -397,6 +397,11 @@
 static int irq[MAX_E21_CARDS]  = { 0, };
 static int mem[MAX_E21_CARDS] = { 0, };
 static int xcvr[MAX_E21_CARDS] = { 0, };		/* choose int. or ext. xcvr */
+
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
+MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.1.18/linux/drivers/net/eepro.c linux/drivers/net/eepro.c
--- v2.1.18/linux/drivers/net/eepro.c	Wed Oct  9 08:55:19 1996
+++ linux/drivers/net/eepro.c	Tue Dec 31 10:30:01 1996
@@ -8,7 +8,7 @@
 	according to the terms of the GNU Public License,
 	incorporated herein by reference.
 
-	The author may be reached at bao.ha@srs.gov 
+	The author may be reached at bao.ha@srs.gov
 	or 418 Hastings Place, Martinez, GA 30907.
 
 	Things remaining to do:
@@ -38,7 +38,7 @@
 	0.07a	Fix a stat report which counts every packet as a
 		heart-beat failure. (BCH, 6/3/95)
 
-	0.07	Modified to support all other 82595-based lan cards.  
+	0.07	Modified to support all other 82595-based lan cards.
 		The IRQ vector of the EtherExpress Pro will be set
 		according to the value saved in the EEPROM.  For other
 		cards, I will do autoirq_request() to grab the next
@@ -48,14 +48,14 @@
 		print out format. (BCH, 3/9/95 and 3/14/95)
 
 	0.06	First stable release that I am comfortable with. (BCH,
-		3/2/95)	
+		3/2/95)
 
-	0.05	Complete testing of multicast. (BCH, 2/23/95)	
+	0.05	Complete testing of multicast. (BCH, 2/23/95)
 
-	0.04	Adding multicast support. (BCH, 2/14/95)	
+	0.04	Adding multicast support. (BCH, 2/14/95)
 
-	0.03	First widely alpha release for public testing. 
-		(BCH, 2/14/95)	
+	0.03	First widely alpha release for public testing.
+		(BCH, 2/14/95)
 
 */
 
@@ -67,18 +67,18 @@
 /*
   Sources:
 
-	This driver wouldn't have been written without the availability 
-	of the Crynwr's Lan595 driver source code.  It helps me to 
-	familiarize with the 82595 chipset while waiting for the Intel 
-	documentation.  I also learned how to detect the 82595 using 
+	This driver wouldn't have been written without the availability
+	of the Crynwr's Lan595 driver source code.  It helps me to
+	familiarize with the 82595 chipset while waiting for the Intel
+	documentation.  I also learned how to detect the 82595 using
 	the packet driver's technique.
 
 	This driver is written by cutting and pasting the skeleton.c driver
 	provided by Donald Becker.  I also borrowed the EEPROM routine from
 	Donald Becker's 82586 driver.
 
-	Datasheet for the Intel 82595 (including the TX and FX version). It 
-	provides just enough info that the casual reader might think that it 
+	Datasheet for the Intel 82595 (including the TX and FX version). It
+	provides just enough info that the casual reader might think that it
 	documents the i82595.
 
 	The User Manual for the 82595.  It provides a lot of the missing
@@ -147,7 +147,7 @@
 
 /* Index to functions, as function prototypes. */
 
-extern int eepro_probe(struct device *dev);	
+extern int eepro_probe(struct device *dev);
 
 static int	eepro_probe1(struct device *dev, short ioaddr);
 static int	eepro_open(struct device *dev);
@@ -184,10 +184,10 @@
 network traffics, the ring linked list should improve performance by
 allowing up to 8K worth of packets to be queued.
 
-The sizes of the receive and transmit buffers can now be changed via lilo 
+The sizes of the receive and transmit buffers can now be changed via lilo
 or insmod.  Lilo uses the appended line "ether=io,irq,debug,rx-buffer,eth0"
 where rx-buffer is in KB unit.  Modules uses the parameter mem which is
-also in KB unit, for example "insmod io=io-address irq=0 mem=rx-buffer."  
+also in KB unit, for example "insmod io=io-address irq=0 mem=rx-buffer."
 The receive buffer has to be more than 3K or less than 29K.  Otherwise,
 it is reset to the default of 24K, and, hence, 8K for the trasnmit
 buffer (transmit-buffer = 32K - receive-buffer).
@@ -198,11 +198,11 @@
 #define RCV_RAM         0x6000  /* 24KB default for RCV buffer */
 #define RCV_LOWER_LIMIT 0x00    /* 0x0000 */
 /* #define RCV_UPPER_LIMIT ((RCV_RAM - 2) >> 8) */    /* 0x5ffe */
-#define RCV_UPPER_LIMIT (((rcv_ram) - 2) >> 8)   
+#define RCV_UPPER_LIMIT (((rcv_ram) - 2) >> 8)
 /* #define XMT_RAM         (RAM_SIZE - RCV_RAM) */    /* 8KB for XMT buffer */
 #define XMT_RAM         (RAM_SIZE - (rcv_ram))    /* 8KB for XMT buffer */
 /* #define XMT_LOWER_LIMIT (RCV_RAM >> 8) */  /* 0x6000 */
-#define XMT_LOWER_LIMIT ((rcv_ram) >> 8) 
+#define XMT_LOWER_LIMIT ((rcv_ram) >> 8)
 #define XMT_UPPER_LIMIT ((RAM_SIZE - 2) >> 8)   /* 0x7ffe */
 #define	XMT_HEADER	8
 
@@ -216,9 +216,9 @@
 #define	XMT_CHAIN	0x04
 #define	XMT_COUNT	0x06
 
-#define	BANK0_SELECT	0x00		
-#define	BANK1_SELECT	0x40		
-#define	BANK2_SELECT	0x80		
+#define	BANK0_SELECT	0x00
+#define	BANK1_SELECT	0x40
+#define	BANK2_SELECT	0x80
 
 /* Bank 0 registers */
 #define	COMMAND_REG	0x00	/* Register 0 */
@@ -278,7 +278,7 @@
 #define	REG13		0x0d
 #define	FDX		0x00
 #define	A_N_ENABLE	0x02
-	
+
 #define	I_ADD_REG0	0x04
 #define	I_ADD_REG1	0x05
 #define	I_ADD_REG2	0x06
@@ -349,9 +349,9 @@
 		/* We seem to have the 82595 signature, let's
 		   play with its counter (last 2 bits of
 		   register 2 of bank 0) to be sure. */
-	
-		counter = (id & R_ROBIN_BITS);	
-		if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS) == 
+
+		counter = (id & R_ROBIN_BITS);
+		if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS) ==
 			(counter + 0x40)) {
 
 			/* Yes, the 82595 has been found */
@@ -367,33 +367,33 @@
 
 			if (station_addr[2] != 0x00aa || (station_addr[1] & 0xff00) != 0x0000) {
 				eepro = 0;
-				printk("%s: Intel 82595-based lan card at %#x,", 
+				printk("%s: Intel 82595-based lan card at %#x,",
 					dev->name, ioaddr);
 			}
 			else {
 				eepro = 1;
-				printk("%s: Intel EtherExpress Pro/10 at %#x,", 
+				printk("%s: Intel EtherExpress Pro/10 at %#x,",
 					dev->name, ioaddr);
 			}
 
    			/* Fill in the 'dev' fields. */
 			dev->base_addr = ioaddr;
-			
+
 			for (i=0; i < 6; i++) {
 				dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
 				printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
 			}
-			
+
 			if ((dev->mem_end & 0x3f) < 3 ||	/* RX buffer must be more than 3K */
 				(dev->mem_end & 0x3f) > 29)	/* and less than 29K */
 				dev->mem_end = RCV_RAM;		/* or it will be set to 24K */
 			else dev->mem_end = 1024*dev->mem_end;  /* Maybe I should shift << 10 */
 
 			/* From now on, dev->mem_end contains the actual size of rx buffer */
-			
+
 			if (net_debug > 3)
 				printk(", %dK RCV buffer", (int)(dev->mem_end)/1024);
-				
+
 			outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
 			id = inb(ioaddr + REG3);
 			if (id & TPE_BIT)
@@ -425,7 +425,7 @@
 				}
 			}
 			else printk(", %s.\n", ifmap[dev->if_port]);
-			
+
 			if ((dev->mem_start & 0xf) > 0)	/* I don't know if this is */
 				net_debug = dev->mem_start & 7; /* still useful or not */
 
@@ -436,7 +436,7 @@
 						dev->name);
 			}
 
-			if (net_debug) 
+			if (net_debug)
 				printk(version);
 
 			/* Grab the region so we can find another board if autoIRQ fails. */
@@ -481,27 +481,27 @@
 static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1};
 static int	eepro_grab_irq(struct device *dev)
 {
-	int irqlist[] = { 5, 9, 10, 11, 4, 3, 0};	
+	int irqlist[] = { 5, 9, 10, 11, 4, 3, 0};
 	int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr;
 
 	outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
 
 	/* Enable the interrupt line. */
 	temp_reg = inb(ioaddr + REG1);
-	outb(temp_reg | INT_ENABLE, ioaddr + REG1); 
-	
+	outb(temp_reg | INT_ENABLE, ioaddr + REG1);
+
 	outb(BANK0_SELECT, ioaddr); /* be CAREFUL, BANK 0 now */
 
 	/* clear all interrupts */
-	outb(ALL_MASK, ioaddr + STATUS_REG); 
+	outb(ALL_MASK, ioaddr + STATUS_REG);
 	/* Let EXEC event to interrupt */
-	outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG); 
+	outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG);
 
 	do {
 		outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
 
 		temp_reg = inb(ioaddr + INT_NO_REG);
-		outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG); 
+		outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG);
 
 		outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
 
@@ -510,13 +510,13 @@
 			autoirq_setup(0);
 
 			outb(DIAGNOSE_CMD, ioaddr); /* RESET the 82595 */
-				
+
 			if (*irqp == autoirq_report(2) &&  /* It's a good IRQ line */
-				(request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro", NULL) == 0)) 
+				(request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro", NULL) == 0))
 					break;
 
 			/* clear all interrupts */
-			outb(ALL_MASK, ioaddr + STATUS_REG); 
+			outb(ALL_MASK, ioaddr + STATUS_REG);
 		}
 	} while (*++irqp);
 
@@ -524,15 +524,15 @@
 
 	/* Disable the physical interrupt line. */
 	temp_reg = inb(ioaddr + REG1);
-	outb(temp_reg & 0x7f, ioaddr + REG1); 
+	outb(temp_reg & 0x7f, ioaddr + REG1);
 
 	outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
 
 	/* Mask all the interrupts. */
-	outb(ALL_MASK, ioaddr + INT_MASK_REG); 
+	outb(ALL_MASK, ioaddr + INT_MASK_REG);
 
 	/* clear all interrupts */
-	outb(ALL_MASK, ioaddr + STATUS_REG); 
+	outb(ALL_MASK, ioaddr + STATUS_REG);
 
 	return dev->irq;
 }
@@ -553,12 +553,12 @@
 		lp->eepro = 1; /* Yes, an Intel EtherExpress Pro/10 */
 	else lp->eepro = 0; /* No, it is a generic 82585 lan card */
 
-	/* Get the interrupt vector for the 82595 */	
+	/* Get the interrupt vector for the 82595 */
 	if (dev->irq < 2 && eepro_grab_irq(dev) == 0) {
 		printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
-				
+
 	if (irq2dev_map[dev->irq] != 0
 		|| (irq2dev_map[dev->irq] = dev) == 0)
 		return -EAGAIN;
@@ -569,18 +569,18 @@
 	temp_reg = inb(ioaddr + EEPROM_REG);
 
 	lp->stepping = temp_reg >> 5;	/* Get the stepping number of the 595 */
-	
+
 	if (net_debug > 3)
 		printk("The stepping of the 82595 is %d\n", lp->stepping);
 
 	if (temp_reg & 0x10) /* Check the TurnOff Enable bit */
 		outb(temp_reg & 0xef, ioaddr + EEPROM_REG);
-	for (i=0; i < 6; i++) 
-		outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i); 
-			
+	for (i=0; i < 6; i++)
+		outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i);
+
 	temp_reg = inb(ioaddr + REG1);    /* Setup Transmit Chaining */
 	outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop /* and discard bad RCV frames */
-		| RCV_Discard_BadFrame, ioaddr + REG1);  
+		| RCV_Discard_BadFrame, ioaddr + REG1);
 
 	temp_reg = inb(ioaddr + REG2); /* Match broadcast */
 	outb(temp_reg | 0x14, ioaddr + REG2);
@@ -590,34 +590,34 @@
 
 	/* Set the receiving mode */
 	outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
-	
+
 	temp_reg = inb(ioaddr + INT_NO_REG);
-	outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG); 
+	outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
 
 	/* Initialize the RCV and XMT upper and lower limits */
-	outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG); 
-	outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG); 
-	outb(XMT_LOWER_LIMIT, ioaddr + XMT_LOWER_LIMIT_REG); 
-	outb(XMT_UPPER_LIMIT, ioaddr + XMT_UPPER_LIMIT_REG); 
+	outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG);
+	outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG);
+	outb(XMT_LOWER_LIMIT, ioaddr + XMT_LOWER_LIMIT_REG);
+	outb(XMT_UPPER_LIMIT, ioaddr + XMT_UPPER_LIMIT_REG);
 
 	/* Enable the interrupt line. */
 	temp_reg = inb(ioaddr + REG1);
-	outb(temp_reg | INT_ENABLE, ioaddr + REG1); 
+	outb(temp_reg | INT_ENABLE, ioaddr + REG1);
 
 	outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
 
 	/* Let RX and TX events to interrupt */
-	outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
+	outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
 	/* clear all interrupts */
-	outb(ALL_MASK, ioaddr + STATUS_REG); 
+	outb(ALL_MASK, ioaddr + STATUS_REG);
 
 	/* Initialize RCV */
-	outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR); 
+	outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR);
 	lp->rx_start = (RCV_LOWER_LIMIT << 8) ;
-	outw((RCV_UPPER_LIMIT << 8) | 0xfe, ioaddr + RCV_STOP); 
+	outw((RCV_UPPER_LIMIT << 8) | 0xfe, ioaddr + RCV_STOP);
 
 	/* Initialize XMT */
-	outw(XMT_LOWER_LIMIT << 8, ioaddr + XMT_BAR); 
+	outw(XMT_LOWER_LIMIT << 8, ioaddr + XMT_BAR);
 
 	/* Check for the i82595TX and i82595FX */
 	old8 = inb(ioaddr + 8);
@@ -652,15 +652,15 @@
 		else if (net_debug > 3)
 			printk("i82595TX detected!\n");
 	}
-	
+
 	outb(SEL_RESET_CMD, ioaddr);
 	/* We are supposed to wait for 2 us after a SEL_RESET */
 	SLOW_DOWN_IO;
-	SLOW_DOWN_IO;	
+	SLOW_DOWN_IO;
 
 	lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT << 8; /* or = RCV_RAM */
-	lp->tx_last = 0;  
-	
+	lp->tx_last = 0;
+
 	dev->tbusy = 0;
 	dev->interrupt = 0;
 	dev->start = 1;
@@ -683,7 +683,7 @@
 
 	if (net_debug > 5)
 		printk("eepro: entering eepro_send_packet routine.\n");
-	
+
 	if (dev->tbusy) {
 		/* If we get here, some higher level has decided we are broken.
 		   There should really be a "kick me" function call instead. */
@@ -696,15 +696,15 @@
 		lp->stats.tx_errors++;
 
 		/* Try to restart the adaptor. */
-		outb(SEL_RESET_CMD, ioaddr); 
+		outb(SEL_RESET_CMD, ioaddr);
 		/* We are supposed to wait for 2 us after a SEL_RESET */
 		SLOW_DOWN_IO;
 		SLOW_DOWN_IO;
 
 		/* Do I also need to flush the transmit buffers here? YES? */
-		lp->tx_start = lp->tx_end = rcv_ram; 
+		lp->tx_start = lp->tx_end = rcv_ram;
 		lp->tx_last = 0;
-	
+
 		dev->tbusy=0;
 		dev->trans_start = jiffies;
 
@@ -738,7 +738,7 @@
 
 	if (net_debug > 5)
 		printk("eepro: exiting eepro_send_packet routine.\n");
-	
+
 	return 0;
 }
 
@@ -753,24 +753,24 @@
 
 	if (net_debug > 5)
 		printk("eepro: entering eepro_interrupt routine.\n");
-	
+
 	if (dev == NULL) {
 		printk ("eepro_interrupt(): irq %d for unknown device.\n", irq);
 		return;
 	}
 	dev->interrupt = 1;
-	
+
 	ioaddr = dev->base_addr;
 
-	do { 
+	do {
 		status = inb(ioaddr + STATUS_REG);
-		
+
 		if (status & RX_INT) {
 			if (net_debug > 4)
 				printk("eepro: packet received interrupt.\n");
 
 			/* Acknowledge the RX_INT */
-			outb(RX_INT, ioaddr + STATUS_REG); 
+			outb(RX_INT, ioaddr + STATUS_REG);
 
 			/* Get the received packets */
 			eepro_rx(dev);
@@ -781,18 +781,18 @@
 				printk("eepro: packet transmit interrupt.\n");
 
 			/* Acknowledge the TX_INT */
-			outb(TX_INT, ioaddr + STATUS_REG); 
+			outb(TX_INT, ioaddr + STATUS_REG);
 
 			/* Process the status of transmitted packets */
 			eepro_transmit_interrupt(dev);
 		}
-	
+
 	} while ((boguscount-- > 0) && (status & 0x06));
 
 	dev->interrupt = 0;
 	if (net_debug > 5)
 		printk("eepro: exiting eepro_interrupt routine.\n");
-	
+
 	return;
 }
 
@@ -811,23 +811,23 @@
 
 	/* Disable the physical interrupt line. */
 	temp_reg = inb(ioaddr + REG1);
-	outb(temp_reg & 0x7f, ioaddr + REG1); 
+	outb(temp_reg & 0x7f, ioaddr + REG1);
 
 	outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
 
 	/* Flush the Tx and disable Rx. */
-	outb(STOP_RCV_CMD, ioaddr); 
+	outb(STOP_RCV_CMD, ioaddr);
 	lp->tx_start = lp->tx_end = rcv_ram ;
-	lp->tx_last = 0;  
+	lp->tx_last = 0;
 
 	/* Mask all the interrupts. */
-	outb(ALL_MASK, ioaddr + INT_MASK_REG); 
+	outb(ALL_MASK, ioaddr + INT_MASK_REG);
 
 	/* clear all interrupts */
-	outb(ALL_MASK, ioaddr + STATUS_REG); 
+	outb(ALL_MASK, ioaddr + STATUS_REG);
 
 	/* Reset the 82595 */
-	outb(RESET_CMD, ioaddr); 
+	outb(RESET_CMD, ioaddr);
 
 	/* release the interrupt */
 	free_irq(dev->irq, NULL);
@@ -864,7 +864,7 @@
 	unsigned short mode;
 	struct dev_mc_list *dmi=dev->mc_list;
 
-	if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63) 
+	if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63)
 	{
 		/*
 		 *	We must make the kernel realise we had to move
@@ -872,17 +872,17 @@
 		 *	the cable. If it was a promisc request the
 		 *	flag is already set. If not we assert it.
 		 */
-		dev->flags|=IFF_PROMISC;		
+		dev->flags|=IFF_PROMISC;
 
 		outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
 		mode = inb(ioaddr + REG2);
-		outb(mode | PRMSC_Mode, ioaddr + REG2);	
+		outb(mode | PRMSC_Mode, ioaddr + REG2);
 		mode = inb(ioaddr + REG3);
 		outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
 		outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
 		printk("%s: promiscuous mode enabled.\n", dev->name);
-	} 
-	else if (dev->mc_count==0 ) 
+	}
+	else if (dev->mc_count==0 )
 	{
 		outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
 		mode = inb(ioaddr + REG2);
@@ -891,11 +891,11 @@
 		outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
 		outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
 	}
-	else 
+	else
 	{
 		unsigned short status, *eaddrs;
 		int i, boguscount = 0;
-		
+
 		/* Disable RX and TX interrupts.  Necessary to avoid
 		   corruption of the HOST_ADDRESS_REG by interrupt
 		   service routines. */
@@ -903,7 +903,7 @@
 
 		outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
 		mode = inb(ioaddr + REG2);
-		outb(mode | Multi_IA, ioaddr + REG2);	
+		outb(mode | Multi_IA, ioaddr + REG2);
 		mode = inb(ioaddr + REG3);
 		outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
 		outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
@@ -912,7 +912,7 @@
 		outw(0, ioaddr + IO_PORT);
 		outw(0, ioaddr + IO_PORT);
 		outw(6*(dev->mc_count + 1), ioaddr + IO_PORT);
-		for (i = 0; i < dev->mc_count; i++) 
+		for (i = 0; i < dev->mc_count; i++)
 		{
 			eaddrs=(unsigned short *)dmi->dmi_addr;
 			dmi=dmi->next;
@@ -929,9 +929,9 @@
 
 		/* Update the transmit queue */
 		i = lp->tx_end + XMT_HEADER + 6*(dev->mc_count + 1);
-		if (lp->tx_start != lp->tx_end) 
-		{ 
-			/* update the next address and the chain bit in the 
+		if (lp->tx_start != lp->tx_end)
+		{
+			/* update the next address and the chain bit in the
 			   last packet */
 			outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
 			outw(i, ioaddr + IO_PORT);
@@ -948,16 +948,16 @@
 		do { /* We should be doing this in the eepro_interrupt()! */
 			SLOW_DOWN_IO;
 			SLOW_DOWN_IO;
-			if (inb(ioaddr + STATUS_REG) & 0x08) 
+			if (inb(ioaddr + STATUS_REG) & 0x08)
 			{
 				i = inb(ioaddr);
 				outb(0x08, ioaddr + STATUS_REG);
 				if (i & 0x20) { /* command ABORTed */
-					printk("%s: multicast setup failed.\n", 
+					printk("%s: multicast setup failed.\n",
 						dev->name);
 					break;
 				} else if ((i & 0x0f) == 0x03)	{ /* MC-Done */
-					printk("%s: set Rx mode to %d addresses.\n", 
+					printk("%s: set Rx mode to %d addresses.\n",
 						dev->name, dev->mc_count);
 					break;
 				}
@@ -965,8 +965,8 @@
 		} while (++boguscount < 100);
 
 		/* Re-enable RX and TX interrupts */
-		outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
-	
+		outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
+
 	}
 	outb(RCV_ENABLE_CMD, ioaddr);
 }
@@ -986,10 +986,10 @@
 	short ee_addr = ioaddr + EEPROM_REG;
 	int read_cmd = location | EE_READ_CMD;
 	short ctrl_val = EECS ;
-	
+
 	outb(BANK2_SELECT, ioaddr);
 	outb(ctrl_val, ee_addr);
-	
+
 	/* Shift the read command bits out. */
 	for (i = 8; i >= 0; i--) {
 		short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI
@@ -1001,7 +1001,7 @@
 		eeprom_delay();
 	}
 	outb(ctrl_val, ee_addr);
-	
+
 	for (i = 16; i > 0; i--) {
 		outb(ctrl_val | EESK, ee_addr);	 eeprom_delay();
 		retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
@@ -1036,9 +1036,9 @@
 	   	service routines. */
 		outb(ALL_MASK, ioaddr + INT_MASK_REG);
 
-		if (dev->interrupt == 1) {  
+		if (dev->interrupt == 1) {
 			/* Enable RX and TX interrupts */
-			outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
+			outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
 			continue;
 		}
 
@@ -1049,13 +1049,13 @@
 			tx_available = lp->tx_start - lp->tx_end;
 		else tx_available = XMT_RAM;
 
-		if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER) 
+		if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER)
 			>= tx_available)   /* No space available ??? */
 			{
 			eepro_transmit_interrupt(dev); /* Clean up the transmiting queue */
 
 			/* Enable RX and TX interrupts */
-			outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
+			outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
 			continue;
 		}
 
@@ -1063,12 +1063,12 @@
 		end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
 
 		if (end >= RAM_SIZE) { /* the transmit buffer is wrapped around */
-			if ((RAM_SIZE - last) <= XMT_HEADER) {	
+			if ((RAM_SIZE - last) <= XMT_HEADER) {
 			/* Arrrr!!!, must keep the xmt header together,
 			  several days were lost to chase this one down. */
 				last = rcv_ram;
 				end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
-			}	
+			}
 			else end = rcv_ram + (end - RAM_SIZE);
 		}
 
@@ -1088,15 +1088,15 @@
 		}
 
 		/* A dummy read to flush the DRAM write pipeline */
-		status = inw(ioaddr + IO_PORT); 
+		status = inw(ioaddr + IO_PORT);
 
-		if (lp->tx_start == lp->tx_end) {	
+		if (lp->tx_start == lp->tx_end) {
 			outw(last, ioaddr + XMT_BAR);
 			outb(XMT_CMD, ioaddr);
 			lp->tx_start = last;   /* I don't like to change tx_start here */
 		}
 		else {
-			/* update the next address and the chain bit in the 
+			/* update the next address and the chain bit in the
 		   	last packet */
 			if (lp->tx_end != last) {
 				outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
@@ -1114,8 +1114,8 @@
 		lp->tx_end = end;
 
 		/* Enable RX and TX interrupts */
-		outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
-	
+		outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
+
 		if (dev->tbusy) {
 			dev->tbusy = 0;
 		}
@@ -1141,7 +1141,7 @@
 
 	if (net_debug > 5)
 		printk("eepro: entering eepro_rx routine.\n");
-	
+
 	/* Set the read pointer to the start of the RCV */
 	outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
 	rcv_event = inw(ioaddr + IO_PORT);
@@ -1174,12 +1174,12 @@
 				outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
 			}
 
-	
-			skb->protocol = eth_type_trans(skb,dev);	
+
+			skb->protocol = eth_type_trans(skb,dev);
 			netif_rx(skb);
 			lp->stats.rx_packets++;
 		}
-		else { /* Not sure will ever reach here, 
+		else { /* Not sure will ever reach here,
 			  I set the 595 to discard bad received frames */
 			lp->stats.rx_errors++;
 			if (rcv_status & 0x0100)
@@ -1188,7 +1188,7 @@
 				lp->stats.rx_frame_errors++;
 			else if (rcv_status & 0x0800)
 				lp->stats.rx_crc_errors++;
-			printk("%s: event = %#x, status = %#x, next = %#x, size = %#x\n", 
+			printk("%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
 				dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
 		}
 		if (rcv_status & 0x1000)
@@ -1201,7 +1201,7 @@
 		outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
 		rcv_event = inw(ioaddr + IO_PORT);
 
-	} 
+	}
 	if (rcv_car == 0)
 		rcv_car = (RCV_UPPER_LIMIT << 8) | 0xff;
 	outw(rcv_car - 1, ioaddr + RCV_STOP);
@@ -1215,10 +1215,10 @@
 {
 	struct eepro_local *lp = (struct eepro_local *)dev->priv;
 	short ioaddr = dev->base_addr;
-	short boguscount = 20; 
+	short boguscount = 20;
 	short xmt_status;
 
-	while (lp->tx_start != lp->tx_end) { 
+	while (lp->tx_start != lp->tx_end) {
 
 		outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
 		xmt_status = inw(ioaddr+IO_PORT);
@@ -1231,7 +1231,7 @@
 		mark_bh(NET_BH);
 
 		if (xmt_status & 0x2000)
-			lp->stats.tx_packets++; 
+			lp->stats.tx_packets++;
 		else {
 			lp->stats.tx_errors++;
 			if (xmt_status & 0x0400)
@@ -1247,7 +1247,7 @@
 		}
 
 		if (--boguscount == 0)
-			break;  
+			break;
 	}
 }
 
@@ -1262,6 +1262,10 @@
 static int io = 0x200;
 static int irq = 0;
 static int mem = (RCV_RAM/1024);	/* Size of the rx buffer in KB */
+
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(mem, "i");
 
 int
 init_module(void)
diff -u --recursive --new-file v2.1.18/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v2.1.18/linux/drivers/net/eexpress.c	Sat Sep 28 22:06:12 1996
+++ linux/drivers/net/eexpress.c	Tue Dec 31 10:30:01 1996
@@ -13,10 +13,10 @@
  * as far as I know, to the similarly-named "EtherExpress Pro" range.
  *
  * Historically, Linux support for these cards has been very bad.  However,
- * things seem to be getting better slowly. 
+ * things seem to be getting better slowly.
  */
 
-/* It would be nice to seperate out all the 82586-specific code, so that it 
+/* It would be nice to seperate out all the 82586-specific code, so that it
  * could be shared between drivers (as with 8390.c).  But this would be quite
  * a messy job.  The main motivation for doing this would be to bring 3c507
  * support back up to scratch.
@@ -37,14 +37,14 @@
  * as follows:
  *
  * (the low five bits of the SMPTR are ignored)
- * 
+ *
  *  base+0x4000..400f      memory at SMPTR+0..15
  *  base+0x8000..800f      memory at SMPTR+16..31
  *  base+0xc000..c007      dubious stuff (memory at SMPTR+16..23 apparently)
  *  base+0xc008..c00f      memory at 0x0008..0x000f
  *
- * This last set (the one at c008) is particularly handy because the SCB 
- * lives at 0x0008.  So that set of ports gives us easy random access to data 
+ * This last set (the one at c008) is particularly handy because the SCB
+ * lives at 0x0008.  So that set of ports gives us easy random access to data
  * in the SCB without having to mess around setting up pointers and the like.
  * We always use this method to access the SCB (via the scb_xx() functions).
  *
@@ -63,7 +63,7 @@
  * - 8-bit mode is not supported, and makes things go wrong.
  * - Multicast and promiscuous modes are not supported.
  * - The card seems to want to give us two interrupts every time something
- *   happens, where just one would be better. 
+ *   happens, where just one would be better.
  * - The statistics may not be getting reported properly.
  */
 
@@ -90,7 +90,7 @@
 #include <linux/malloc.h>
 
 #ifndef NET_DEBUG
-#define NET_DEBUG 4 
+#define NET_DEBUG 4
 #endif
 
 #include "eexpress.h"
@@ -101,7 +101,7 @@
  * Private data declarations
  */
 
-struct net_local 
+struct net_local
 {
 	struct enet_statistics stats;
 	unsigned long init_time;     /* jiffies when eexp_hw_init586 called */
@@ -128,7 +128,7 @@
 static unsigned short start_code[] = {
 /* 0xfff6 */
 	0x0000,                 /* set bus to 16 bits */
-	0x0000,0x0000,         
+	0x0000,0x0000,
 	0x0000,0x0000,          /* address of ISCP (lo,hi) */
 
 /* 0x0000 */
@@ -136,7 +136,7 @@
 	0x0008,0x0000,0x0000,   /* offset,address (lo,hi) of SCB */
 
 	0x0000,0x0000,          /* SCB: status, commands */
-	0x0000,0x0000,          /* links to first command block, 
+	0x0000,0x0000,          /* links to first command block,
 				   first receive descriptor */
 	0x0000,0x0000,          /* CRC error, alignment error counts */
 	0x0000,0x0000,          /* out of resources, overrun error counts */
@@ -146,7 +146,7 @@
 
 /* 0x0020 -- start of 82586 CU program */
 #define CONF_LINK 0x0020
-	0x0000,Cmd_Config,      
+	0x0000,Cmd_Config,
 	0x0032,                 /* link to next command */
 	0x080c,                 /* 12 bytes follow : fifo threshold=8 */
 	0x2e40,                 /* don't rx bad frames
@@ -156,9 +156,9 @@
 				 */
 	0x6000,                 /* default backoff method & priority
 				 * interframe spacing = 0x60 */
-	0xf200,                 /* slot time=0x200 
+	0xf200,                 /* slot time=0x200
 				 * max collision retry = 0xf */
-	0x0000,                 /* no HDLC : normal CRC : enable broadcast 
+	0x0000,                 /* no HDLC : normal CRC : enable broadcast
 				 * disable promiscuous/multicast modes */
 	0x003c,                 /* minimum frame length = 60 octets) */
 
@@ -245,12 +245,12 @@
 
 static inline void set_loopback(struct device *dev)
 {
-	outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config); 
+	outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config);
 }
 
 static inline void clear_loopback(struct device *dev)
 {
-	outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config); 
+	outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config);
 }
 
 static inline short int SHADOW(short int addr)
@@ -278,17 +278,17 @@
 	else if (ioaddr)
 		return ENXIO;
 
-	for (port=&ports[0] ; *port ; port++ ) 
+	for (port=&ports[0] ; *port ; port++ )
 	{
 		unsigned short sum = 0;
 		int i;
-		for ( i=0 ; i<4 ; i++ ) 
+		for ( i=0 ; i<4 ; i++ )
 		{
 			unsigned short t;
 			t = inb(*port + ID_PORT);
 			sum |= (t>>4) << ((t & 0x03)<<2);
 		}
-		if (sum==0xbaba && !eexp_hw_probe(dev,*port)) 
+		if (sum==0xbaba && !eexp_hw_probe(dev,*port))
 			return 0;
 	}
 	return ENODEV;
@@ -307,12 +307,12 @@
 	printk(KERN_DEBUG "%s: eexp_open()\n", dev->name);
 #endif
 
-	if (!irq || !irqrmap[irq]) 
+	if (!irq || !irqrmap[irq])
 		return -ENXIO;
 
 	if (irq2dev_map[irq] ||
 	   ((irq2dev_map[irq]=dev),0) ||
-	     request_irq(irq,&eexp_irq,0,"EtherExpress",NULL)) 
+	     request_irq(irq,&eexp_irq,0,"EtherExpress",NULL))
 		return -EAGAIN;
 
 	request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress");
@@ -338,9 +338,9 @@
 
 	int irq = dev->irq;
 
-	dev->tbusy = 1; 
+	dev->tbusy = 1;
 	dev->start = 0;
-  
+
 	outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
 	lp->started = 0;
 	scb_command(dev, SCB_CUsuspend|SCB_RUsuspend);
@@ -365,7 +365,7 @@
 	return &lp->stats;
 }
 
-/* 
+/*
  * This gets called when a higher level thinks we are broken.  Check that
  * nothing has become jammed in the CU.
  */
@@ -375,11 +375,11 @@
 	struct net_local *lp = (struct net_local *)dev->priv;
 	unsigned short ioaddr = dev->base_addr;
 
-	if (lp->started) 
+	if (lp->started)
 	{
-		if ((jiffies - dev->trans_start)>50) 
+		if ((jiffies - dev->trans_start)>50)
 		{
-			if (lp->tx_link==lp->last_tx_restart) 
+			if (lp->tx_link==lp->last_tx_restart)
 			{
 				unsigned short boguscount=200,rsst;
 				printk(KERN_WARNING "%s: Retransmit timed out, status %04x, resetting...\n",
@@ -389,9 +389,9 @@
 				scb_wrcbl(dev, lp->tx_link);
 				scb_command(dev, SCB_CUstart);
 				outb(0,ioaddr+SIGNAL_CA);
-				while (!SCB_complete(rsst=scb_status(dev))) 
+				while (!SCB_complete(rsst=scb_status(dev)))
 				{
-					if (!--boguscount) 
+					if (!--boguscount)
 					{
 						boguscount=200;
 						printk(KERN_WARNING "%s: Reset timed out status %04x, retrying...\n",
@@ -407,7 +407,7 @@
 			else
 			{
 				unsigned short status = scb_status(dev);
-				if (SCB_CUdead(status)) 
+				if (SCB_CUdead(status))
 				{
 					unsigned short txstatus = eexp_hw_lasttxstat(dev);
 					printk(KERN_WARNING "%s: Transmit timed out, CU not active status %04x %04x, restarting...\n",
@@ -417,11 +417,11 @@
 				else
 				{
 					unsigned short txstatus = eexp_hw_lasttxstat(dev);
-					if (dev->tbusy && !txstatus) 
+					if (dev->tbusy && !txstatus)
 					{
 						printk(KERN_WARNING "%s: CU wedged, status %04x %04x, resetting...\n",
 						       dev->name,status,txstatus);
-						eexp_hw_init586(dev); 
+						eexp_hw_init586(dev);
 						dev->tbusy = 0;
 						mark_bh(NET_BH);
 					}
@@ -460,21 +460,21 @@
 #endif
 
 	outb(SIRQ_dis|irqrmap[dev->irq],dev->base_addr+SET_IRQ);
-	
+
 	/* If dev->tbusy is set, all our tx buffers are full but the kernel
 	 * is calling us anyway.  Check that nothing bad is happening.
 	 */
-	if (dev->tbusy) 
+	if (dev->tbusy)
 		unstick_cu(dev);
 
-	if (buf==NULL) 
+	if (buf==NULL)
 	{
 		/* Some higher layer thinks we might have missed a
 		 * tx-done interrupt.  Does this ever actually happen?
 		 */
 		unsigned short status = scb_status(dev);
 		unsigned short txstatus = eexp_hw_lasttxstat(dev);
-		if (SCB_CUdead(status)) 
+		if (SCB_CUdead(status))
 		{
 			printk(KERN_WARNING "%s: CU has died! status %04x %04x, attempting to restart...\n",
 				dev->name, status, txstatus);
@@ -486,7 +486,7 @@
 		return 0;
 	}
 
-	if (set_bit(0,(void *)&dev->tbusy)) 
+	if (set_bit(0,(void *)&dev->tbusy))
 	{
 		lp->stats.tx_dropped++;
 	}
@@ -516,7 +516,7 @@
 	struct net_local *lp;
 	unsigned short ioaddr,status,ack_cmd;
 
-	if (dev==NULL) 
+	if (dev==NULL)
 	{
 		printk(KERN_WARNING "eexpress: irq %d for unknown device\n",
 		       irq);
@@ -526,10 +526,10 @@
 	lp = (struct net_local *)dev->priv;
 	ioaddr = dev->base_addr;
 
-	outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ); 
+	outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
+
+	dev->interrupt = 1;
 
-	dev->interrupt = 1; 
-  
 	status = scb_status(dev);
 
 #if NET_DEBUG > 4
@@ -538,7 +538,7 @@
 
 	ack_cmd = SCB_ack(status);
 
-	if (lp->started==0 && SCB_complete(status)) 
+	if (lp->started==0 && SCB_complete(status))
 	{
 		while (SCB_CUstat(status)==2)
 				status = scb_status(dev);
@@ -554,7 +554,7 @@
 			tdr_status = inw(dev->base_addr + 0x8004);
 			if (tdr_status & TDR_SHORT) {
 					printk(KERN_WARNING "%s: TDR reports cable short at %d tick%s\n", dev->name, tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : "");
-			} 
+			}
 			else if (tdr_status & TDR_OPEN) {
 					printk(KERN_WARNING "%s: TDR reports cable broken at %d tick%s\n", dev->name, tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : "");
 			}
@@ -573,18 +573,18 @@
 		scb_wrrfa(dev, lp->rx_buf_start);
 		ack_cmd |= SCB_CUstart | SCB_RUstart | 0x2000;
 	}
-	else if (lp->started) 
+	else if (lp->started)
 	{
 		unsigned short txstatus;
 		txstatus = eexp_hw_lasttxstat(dev);
 	}
 
-	if (SCB_rxdframe(status)) 
+	if (SCB_rxdframe(status))
 	{
 		eexp_hw_rx_pio(dev);
 	}
 
-	if ((lp->started&2)!=0 && SCB_RUstat(status)!=4) 
+	if ((lp->started&2)!=0 && SCB_RUstat(status)!=4)
 	{
 		printk(KERN_WARNING "%s: RU stopped: status %04x\n",
 			dev->name,status);
@@ -592,14 +592,14 @@
 		eexp_hw_rxinit(dev);
 		scb_wrrfa(dev, lp->rx_buf_start);
 		ack_cmd |= SCB_RUstart;
-	} 
-	else if (lp->started==1 && SCB_RUstat(status)==4) 
+	}
+	else if (lp->started==1 && SCB_RUstat(status)==4)
 		lp->started|=2;
 
 	scb_command(dev, ack_cmd);
 	outb(0,ioaddr+SIGNAL_CA);
 
-	outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ); 
+	outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ);
 
 	dev->interrupt = 0;
 #if NET_DEBUG > 6
@@ -617,7 +617,7 @@
  * to the upper levels. Basic sanity check on each frame
  * descriptor, though we don't bother trying to fix broken ones.
  */
- 
+
 static void eexp_hw_rx_pio(struct device *dev)
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
@@ -629,7 +629,7 @@
 	printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name);
 #endif
 
-	while (boguscount--) 
+	while (boguscount--)
 	{
 		unsigned short status, rfd_cmd, rx_next, pbuf, pkt_len;
 
@@ -639,13 +639,13 @@
 		rx_next = inw(ioaddr + DATAPORT);
 		pbuf = inw(ioaddr + DATAPORT);
 
-		if (FD_Done(status)) 
+		if (FD_Done(status))
 		{
 			outw(pbuf, ioaddr + READ_PTR);
 			pkt_len = inw(ioaddr + DATAPORT);
 
 			if (rfd_cmd!=0x0000 || pbuf!=rx_block+0x16
-				|| (pkt_len & 0xc000)!=0xc000) 
+				|| (pkt_len & 0xc000)!=0xc000)
 			{
 				/* This should never happen.  If it does,
 				 * we almost certainly have a driver bug.
@@ -655,10 +655,10 @@
 					status,rfd_cmd,rx_next,pbuf,pkt_len);
 				continue;
 			}
-			else if (!FD_OK(status)) 
+			else if (!FD_OK(status))
 			{
 				lp->stats.rx_errors++;
-				if (FD_CRC(status)) 
+				if (FD_CRC(status))
 					lp->stats.rx_crc_errors++;
 				if (FD_Align(status))
 					lp->stats.rx_frame_errors++;
@@ -674,7 +674,7 @@
 				struct sk_buff *skb;
 				pkt_len &= 0x3fff;
 				skb = dev_alloc_skb(pkt_len+16);
-				if (skb == NULL) 
+				if (skb == NULL)
 				{
 					printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name);
 					lp->stats.rx_dropped++;
@@ -732,11 +732,11 @@
 
 	dev->trans_start = jiffies;
 	lp->tx_tail = lp->tx_head;
-	if (lp->tx_head==TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE)) 
+	if (lp->tx_head==TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
 		lp->tx_head = TX_BUF_START;
-	else 
+	else
 		lp->tx_head += TX_BUF_SIZE;
-	if (lp->tx_head != lp->tx_reap) 
+	if (lp->tx_head != lp->tx_reap)
 		dev->tbusy = 0;
 }
 
@@ -768,7 +768,7 @@
 	hw_addr[1] = eexp_hw_readeeprom(ioaddr,3);
 	hw_addr[2] = eexp_hw_readeeprom(ioaddr,4);
 
-	if (hw_addr[2]!=0x00aa || ((hw_addr[1] & 0xff00)!=0x0000)) 
+	if (hw_addr[2]!=0x00aa || ((hw_addr[1] & 0xff00)!=0x0000))
 	{
 		printk(" rejected: invalid address %04x%04x%04x\n",
 			hw_addr[2],hw_addr[1],hw_addr[0]);
@@ -776,15 +776,15 @@
 	}
 
 	/* Calculate the EEPROM checksum.  Carry on anyway if it's bad,
-	 * though. 
+	 * though.
 	 */
 	for (i = 0; i < 64; i++)
 		xsum += eexp_hw_readeeprom(ioaddr, i);
-	if (xsum != 0xbaba) 
+	if (xsum != 0xbaba)
 		printk(" (bad EEPROM xsum 0x%02x)", xsum);
 
 	dev->base_addr = ioaddr;
-	for ( i=0 ; i<6 ; i++ ) 
+	for ( i=0 ; i<6 ; i++ )
 		dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i];
 
 	{
@@ -800,11 +800,11 @@
 	}
 
 	dev->priv = lp = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-	if (!dev->priv) 
+	if (!dev->priv)
 		return ENOMEM;
 
 	memset(dev->priv, 0, sizeof(struct net_local));
-	
+
 	printk("; using IRQ %d, %s connector", dev->irq,ifmap[dev->if_port]);
 
 	/* Find out how much RAM we have on the card */
@@ -816,7 +816,7 @@
 	{
 		outw(memory_size<<10, dev->base_addr + WRITE_PTR);
 		outw(memory_size<<10, dev->base_addr + READ_PTR);
-		if (inw(dev->base_addr+DATAPORT)) 
+		if (inw(dev->base_addr+DATAPORT))
 			break;
 		outw(memory_size | 0x5000, dev->base_addr+DATAPORT);
 		outw(memory_size<<10, dev->base_addr + READ_PTR);
@@ -863,19 +863,19 @@
  * Read a word from the EtherExpress on-board serial EEPROM.
  * The EEPROM contains 64 words of 16 bits.
  */
-static unsigned short eexp_hw_readeeprom(unsigned short ioaddr, 
+static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
 					 unsigned char location)
 {
 	unsigned short cmd = 0x180|(location&0x7f);
 	unsigned short rval = 0,wval = EC_CS|i586_RST;
 	int i;
- 
+
 	outb(EC_CS|i586_RST,ioaddr+EEPROM_Ctrl);
-	for (i=0x100 ; i ; i>>=1 ) 
+	for (i=0x100 ; i ; i>>=1 )
 	{
-		if (cmd&i) 
+		if (cmd&i)
 			wval |= EC_Wr;
-		else 
+		else
 			wval &= ~EC_Wr;
 
 		outb(wval,ioaddr+EEPROM_Ctrl);
@@ -883,14 +883,14 @@
 		eeprom_delay();
 		outb(wval,ioaddr+EEPROM_Ctrl);
 		eeprom_delay();
-	}	
+	}
 	wval &= ~EC_Wr;
 	outb(wval,ioaddr+EEPROM_Ctrl);
-	for (i=0x8000 ; i ; i>>=1 ) 
+	for (i=0x8000 ; i ; i>>=1 )
 	{
 		outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
 		eeprom_delay();
-		if (inb(ioaddr+EEPROM_Ctrl)&EC_Rd) 
+		if (inb(ioaddr+EEPROM_Ctrl)&EC_Rd)
 			rval |= i;
 		outb(wval,ioaddr+EEPROM_Ctrl);
 		eeprom_delay();
@@ -918,36 +918,36 @@
 	struct net_local *lp = (struct net_local *)dev->priv;
 	unsigned short tx_block = lp->tx_reap;
 	unsigned short status;
-  
-	if ((!dev->tbusy) && lp->tx_head==lp->tx_reap) 
+
+	if ((!dev->tbusy) && lp->tx_head==lp->tx_reap)
 		return 0x0000;
 
 	do
 	{
 		outw(tx_block, dev->base_addr + SM_PTR);
 		status = inw(SHADOW(tx_block));
-		if (!Stat_Done(status)) 
+		if (!Stat_Done(status))
 		{
 			lp->tx_link = tx_block;
 			return status;
 		}
-		else 
+		else
 		{
 			lp->last_tx_restart = 0;
 			lp->stats.collisions += Stat_NoColl(status);
-			if (!Stat_OK(status)) 
+			if (!Stat_OK(status))
 			{
-				if (Stat_Abort(status)) 
+				if (Stat_Abort(status))
 					lp->stats.tx_aborted_errors++;
-				if (Stat_TNoCar(status) || Stat_TNoCTS(status)) 
+				if (Stat_TNoCar(status) || Stat_TNoCTS(status))
 					lp->stats.tx_carrier_errors++;
-				if (Stat_TNoDMA(status)) 
+				if (Stat_TNoDMA(status))
 					lp->stats.tx_fifo_errors++;
 			}
 			else
 				lp->stats.tx_packets++;
 		}
-		if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE)) 
+		if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
 			lp->tx_reap = tx_block = TX_BUF_START;
 		else
 			lp->tx_reap = tx_block += TX_BUF_SIZE;
@@ -961,7 +961,7 @@
 	return status;
 }
 
-/* 
+/*
  * This should never happen. It is called when some higher routine detects
  * that the CU has stopped, to try to restart it from the last packet we knew
  * we were working on, or the idle loop if we had finished for the time.
@@ -971,7 +971,7 @@
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
 	unsigned short ioaddr = dev->base_addr;
-  
+
 	lp->last_tx_restart = lp->tx_link;
 	scb_wrcbl(dev, lp->tx_link);
 	scb_command(dev, SCB_CUstart);
@@ -979,11 +979,11 @@
 
 	{
 		unsigned short boguscount=50,failcount=5;
-		while (!scb_status(dev)) 
+		while (!scb_status(dev))
 		{
-			if (!--boguscount) 
+			if (!--boguscount)
 			{
-				if (--failcount) 
+				if (--failcount)
 				{
 					printk(KERN_WARNING "%s: CU start timed out, status %04x, cmd %04x\n", dev->name, scb_status(dev), scb_rdcmd(dev));
 				        scb_wrcbl(dev, lp->tx_link);
@@ -1007,10 +1007,10 @@
 /*
  * Writes down the list of transmit buffers into card memory.  Each
  * entry consists of an 82586 transmit command, followed by a jump
- * pointing to itself.  When we want to transmit a packet, we write 
+ * pointing to itself.  When we want to transmit a packet, we write
  * the data into the appropriate transmit buffer and then modify the
  * preceding jump to point at the new transmit command.  This means that
- * the 586 command unit is continuously active. 
+ * the 586 command unit is continuously active.
  */
 
 static void eexp_hw_txinit(struct device *dev)
@@ -1020,7 +1020,7 @@
 	unsigned short curtbuf;
 	unsigned short ioaddr = dev->base_addr;
 
-	for ( curtbuf=0 ; curtbuf<lp->num_tx_bufs ; curtbuf++ ) 
+	for ( curtbuf=0 ; curtbuf<lp->num_tx_bufs ; curtbuf++ )
 	{
 		outw(tx_block, ioaddr + WRITE_PTR);
 
@@ -1052,23 +1052,23 @@
  * Write the circular list of receive buffer descriptors to card memory.
  * The end of the list isn't marked, which means that the 82586 receive
  * unit will loop until buffers become available (this avoids it giving us
- * "out of resources" messages). 
+ * "out of resources" messages).
  */
 
 static void eexp_hw_rxinit(struct device *dev)
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
 	unsigned short rx_block = lp->rx_buf_start;
-	unsigned short ioaddr = dev->base_addr; 
+	unsigned short ioaddr = dev->base_addr;
 
 	lp->num_rx_bufs = 0;
 	lp->rx_first = rx_block;
-	do 
+	do
 	{
 		lp->num_rx_bufs++;
 
 		outw(rx_block, ioaddr + WRITE_PTR);
-		
+
 		outw(0, ioaddr + DATAPORT);  outw(0, ioaddr+DATAPORT);
 		outw(rx_block + RX_BUF_SIZE, ioaddr+DATAPORT);
 		outw(rx_block + 0x16, ioaddr+DATAPORT);
@@ -1080,8 +1080,8 @@
 		outw(0xdead, ioaddr+DATAPORT);
 		outw(0xdead, ioaddr+DATAPORT);
 		outw(0xdead, ioaddr+DATAPORT);
-		
-		outw(0x8000, ioaddr+DATAPORT); 
+
+		outw(0x8000, ioaddr+DATAPORT);
 		outw(0xffff, ioaddr+DATAPORT);
 		outw(rx_block + 0x20, ioaddr+DATAPORT);
 		outw(0, ioaddr+DATAPORT);
@@ -1114,7 +1114,7 @@
 
 	lp->started = 0;
 
-	set_loopback(dev);  
+	set_loopback(dev);
 
 	/* Bash the startup code a bit */
 	start_code[28] = (dev->flags & IFF_PROMISC)?(start_code[28] | 1):
@@ -1122,7 +1122,7 @@
 	lp->promisc = dev->flags & IFF_PROMISC;
 	memcpy(&start_code[33], &dev->dev_addr[0], 6);
 
-	outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ); 
+	outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
 
 	/* Download the startup code */
 	outw(lp->rx_buf_end & ~31, ioaddr + SM_PTR);
@@ -1155,16 +1155,16 @@
 
 	{
 		unsigned short rboguscount=50,rfailcount=5;
-		while (inw(ioaddr+0x4000)) 
+		while (inw(ioaddr+0x4000))
 		{
-			if (!--rboguscount) 
+			if (!--rboguscount)
 			{
 				printk(KERN_WARNING "%s: i82586 reset timed out, kicking...\n",
 					dev->name);
 				scb_command(dev, 0);
 				outb(0,ioaddr+SIGNAL_CA);
 				rboguscount = 100;
-				if (!--rfailcount) 
+				if (!--rfailcount)
 				{
 					printk(KERN_WARNING "%s: i82586 not responding, giving up.\n",
 						dev->name);
@@ -1180,11 +1180,11 @@
 
 	{
 		unsigned short iboguscount=50,ifailcount=5;
-		while (!scb_status(dev)) 
+		while (!scb_status(dev))
 		{
-			if (!--iboguscount) 
+			if (!--iboguscount)
 			{
-				if (--ifailcount) 
+				if (--ifailcount)
 				{
 					printk(KERN_WARNING "%s: i82586 initialization timed out, status %04x, cmd %04x\n",
 						dev->name, scb_status(dev), scb_rdcmd(dev));
@@ -1193,7 +1193,7 @@
 					outb(0,ioaddr+SIGNAL_CA);
 					iboguscount = 100;
 				}
-				else 
+				else
 				{
 					printk(KERN_WARNING "%s: Failed to initialize i82586, giving up.\n",dev->name);
 					return;
@@ -1201,9 +1201,9 @@
 			}
 		}
 	}
-  
-	clear_loopback(dev); 
-	outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ); 
+
+	clear_loopback(dev);
+	outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ);
 
 	lp->init_time = jiffies;
 #if NET_DEBUG > 6
@@ -1232,15 +1232,18 @@
 
 static char namelist[NAMELEN * EEXP_MAX_CARDS] = { 0, };
 
-static struct device dev_eexp[EEXP_MAX_CARDS] = 
+static struct device dev_eexp[EEXP_MAX_CARDS] =
 {
         { NULL,         /* will allocate dynamically */
-	  0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe },  
+	  0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe },
 };
 
 static int irq[EEXP_MAX_CARDS] = {0, };
 static int io[EEXP_MAX_CARDS] = {0, };
 
+MODULE_PARM(io, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i");
+
 /* Ideally the user would give us io=, irq= for every card.  If any parameters
  * are specified, we verify and then use them.  If no parameters are given, we
  * autoprobe for one card only.
@@ -1271,7 +1274,7 @@
 void cleanup_module(void)
 {
 	int this_dev;
-        
+
 	for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
 		struct device *dev = &dev_eexp[this_dev];
 		if (dev->priv != NULL) {
diff -u --recursive --new-file v2.1.18/linux/drivers/net/es3210.c linux/drivers/net/es3210.c
--- v2.1.18/linux/drivers/net/es3210.c	Thu Dec 12 19:37:06 1996
+++ linux/drivers/net/es3210.c	Tue Dec 31 10:30:01 1996
@@ -17,8 +17,8 @@
 	3) Info for getting IRQ and sh-mem gleaned from the EISA cfg files.
 	   Too bad it doesn't work -- see below.
 
-	The ES3210 is an EISA shared memory NS8390 implementation. Note 
-	that all memory copies to/from the board must be 32bit transfers. 
+	The ES3210 is an EISA shared memory NS8390 implementation. Note
+	that all memory copies to/from the board must be 32bit transfers.
 	Which rules out using eth_io_copy_and_sum() in this driver.
 
 	Apparently there are two slightly different revisions of the
@@ -26,7 +26,7 @@
 	and !rii0102.cfg) One has media select in the cfg file and the
 	other doesn't. Hopefully this will work with either.
 
-	That is about all I can tell you about it, having never actually 
+	That is about all I can tell you about it, having never actually
 	even seen one of these cards. :)  Try http://www.interlan.com
 	if you want more info.
 
@@ -86,7 +86,7 @@
 #define ES_ADDR2	0x01
 
 /*
- * Two card revisions. EISA ID's are always rev. minor, rev. major,, and 
+ * Two card revisions. EISA ID's are always rev. minor, rev. major,, and
  * then the three vendor letters stored in 5 bits each, with an "a" = 1.
  * For eg: "rii" = 10010 01001 01001 = 0x4929, which is how the EISA
  * config utility determines automagically what config file(s) to use.
@@ -117,7 +117,7 @@
 static unsigned char lo_irq_map[] = {3, 4, 5, 6, 7, 9, 10};
 static unsigned char hi_irq_map[] = {11, 12, 0, 14, 0, 0, 0, 15};
 
-/* 
+/*
  *	Probe for the card. The best way is to read the EISA ID if it
  *	is known. Then we check the prefix of the station address
  *	PROM for a match against the Racal-Interlan assigned value.
@@ -168,7 +168,7 @@
 	if ((eisa_id != ES_EISA_ID1) && (eisa_id != ES_EISA_ID2)) {
 		return ENODEV;
 	}
-	
+
 /*	Check the Racal vendor ID as well. */
 	if (inb(ioaddr + ES_SA_PROM + 0) != ES_ADDR0
 		|| inb(ioaddr + ES_SA_PROM + 1) != ES_ADDR1
@@ -187,7 +187,7 @@
 	}
 
 	printk("es3210.c: ES3210 rev. %ld at %#x, node", eisa_id>>24, ioaddr);
-	for(i = 0; i < ETHER_ADDR_LEN; i++) 
+	for(i = 0; i < ETHER_ADDR_LEN; i++)
 		printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i)));
 
 	/* Snarf the interrupt now. */
@@ -303,7 +303,7 @@
  *	that the associated memcpy will only use "rep; movsl" as long as
  *	we keep the counts as some multiple of doublewords. This is a
  *	requirement of the hardware, and also prevents us from using
- *	eth_io_copy_and_sum() since we can't guarantee it will limit 
+ *	eth_io_copy_and_sum() since we can't guarantee it will limit
  *	itself to doubleword access.
  */
 
@@ -321,7 +321,7 @@
 	hdr->count = (hdr->count + 3) & ~3;     /* Round up allocation. */
 }
 
-/*	
+/*
  *	Block input and output are easy on shared memory ethercards, the only
  *	complication is when the ring buffer wraps. The count will already
  *	be rounded up to a doubleword value via es_get_8390_hdr() above.
@@ -392,6 +392,10 @@
 static int irq[MAX_ES_CARDS]  = { 0, };
 static int mem[MAX_ES_CARDS] = { 0, };
 
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
+
 int
 init_module(void)
 {
@@ -435,4 +439,3 @@
 	}
 }
 #endif /* MODULE */
-
diff -u --recursive --new-file v2.1.18/linux/drivers/net/eth16i.c linux/drivers/net/eth16i.c
--- v2.1.18/linux/drivers/net/eth16i.c	Tue Nov 19 15:53:56 1996
+++ linux/drivers/net/eth16i.c	Tue Dec 31 10:30:01 1996
@@ -17,20 +17,20 @@
    Sources:
      - skeleton.c  a sample network driver core for linux,
        written by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
-     - at1700.c a driver for Allied Telesis AT1700, written 
+     - at1700.c a driver for Allied Telesis AT1700, written
        by Donald Becker.
      - e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
        written by Markku Viima
      - The Fujitsu MB86965 databook.
-   
+
    Valuable assistance from:
-	Markku Viima (ICL) 
+	Markku Viima (ICL)
 	Ari Valve (ICL)
-   
+
    Revision history:
 
    Version	Date		Description
-   
+
    0.01		15.12-94	Initial version (card detection)
    0.02         23.01-95        Interrupt is now hooked correctly
    0.03         01.02-95        Rewrote initialization part
@@ -44,7 +44,7 @@
    0.05		08.02-95	If there were more than one packet to send,
 				transmit was jammed due to invalid
 				register write...now fixed
-   0.06         19.02-95        Rewrote interrupt handling        
+   0.06         19.02-95        Rewrote interrupt handling
    0.07         13.04-95        Wrote EEPROM read routines
                                 Card configuration now set according to
 				data read from EEPROM
@@ -52,54 +52,54 @@
                                 port if AUTO is selected
 
    0.09         01.09-95	Added module support
-   
-   0.10         04.09-95	Fixed receive packet allocation to work		
+
+   0.10         04.09-95	Fixed receive packet allocation to work
         			with kernels > 1.3.x
-   
-   0.20		20.09-95	Added support for EtherTeam32 EISA	
 
-   0.21         17.10-95        Removed the unnecessary extern 
+   0.20		20.09-95	Added support for EtherTeam32 EISA
+
+   0.21         17.10-95        Removed the unnecessary extern
 				init_etherdev() declaration. Some
 				other cleanups.
    Bugs:
-	In some cases the interface autoprobing code doesn't find 
-	the correct interface type. In this case you can 
-	manually choose the interface type in DOS with E16IC.EXE which is 
+	In some cases the interface autoprobing code doesn't find
+	the correct interface type. In this case you can
+	manually choose the interface type in DOS with E16IC.EXE which is
 	configuration software for EtherTeam16i and EtherTeam32 cards.
-	
+
    To do:
 	- Real multicast support
 */
 
-static char *version = 
+static char *version =
 	"eth16i.c: v0.21 17-10-95 Mika Kuoppala (miku@elt.icl.fi)\n";
 
 #include <linux/module.h>
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/types.h>		  
-#include <linux/fcntl.h>		  
-#include <linux/interrupt.h>		  
-#include <linux/ptrace.h>		  
-#include <linux/ioport.h>		  
-#include <linux/in.h>		  
-#include <linux/malloc.h>		  
-#include <linux/string.h>		  
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
 #include <linux/errno.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
-#include <asm/system.h>		  
-#include <asm/bitops.h>		  
-#include <asm/io.h>		  
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
 #include <asm/dma.h>
 
 /* Few macros */
-#define BIT(a)		        ( (1 << (a)) )  
-#define BITSET(ioaddr, bnum)   ((outb(((inb(ioaddr)) | (bnum)), ioaddr))) 
+#define BIT(a)		        ( (1 << (a)) )
+#define BITSET(ioaddr, bnum)   ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
 #define BITCLR(ioaddr, bnum)   ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
 
 /* This is the I/O address space for Etherteam 16i adapter. */
@@ -114,7 +114,7 @@
 /* Some interrupt masks */
 #define ETH16I_INTR_ON	       0x8f82
 #define ETH16I_INTR_OFF	       0x0000
-	 
+
 /* Buffers header status byte meanings */
 #define PKT_GOOD               BIT(5)
 #define PKT_GOOD_RMT           BIT(4)
@@ -140,7 +140,7 @@
 #define ALIGN_ERR              BIT(2)
 #define CRC_ERR                BIT(1)
 #define RX_BUF_OVERFLOW        BIT(0)
-              
+
 /* Transmit Interrupt Enable Register (DLCR2) */
 #define TX_INTR_REG            2
 #define TX_INTR_DONE           BIT(7)
@@ -179,14 +179,14 @@
 #define SRAM_CYCLE_TIME_100NS  BIT(6)
 #define SYSTEM_BUS_WIDTH_8     BIT(5)       /* 1 = 8bit, 0 = 16bit */
 #define BUFFER_WIDTH_8         BIT(4)       /* 1 = 8bit, 0 = 16bit */
-#define TBS1                   BIT(3)       
+#define TBS1                   BIT(3)
 #define TBS0                   BIT(2)
 #define MBS1                   BIT(1)       /* 00=8kb,  01=16kb  */
 #define MBS0                   BIT(0)       /* 10=32kb, 11=64kb  */
 
-#ifndef ETH16I_TX_BUF_SIZE                   /* 0 = 2kb, 1 = 4kb  */ 
+#ifndef ETH16I_TX_BUF_SIZE                   /* 0 = 2kb, 1 = 4kb  */
 #define ETH16I_TX_BUF_SIZE     2             /* 2 = 8kb, 3 = 16kb */
-#endif                                      
+#endif
 #define TX_BUF_1x2048            0
 #define TX_BUF_2x2048            1
 #define TX_BUF_2x4098            2
@@ -221,7 +221,7 @@
 
 /* DMA Burst and Transceiver Mode Register (BMPR13) */
 #define TRANSCEIVER_MODE_REG   13
-#define TRANSCEIVER_MODE_RB    2         
+#define TRANSCEIVER_MODE_RB    2
 #define IO_BASE_UNLOCK	       BIT(7)
 #define LOWER_SQUELCH_TRESH    BIT(6)
 #define LINK_TEST_DISABLE      BIT(5)
@@ -261,7 +261,7 @@
   #define E_PORT_TP                    2
   #define E_PORT_AUTO                  3
 #define E_PRODUCT_CFG                  0x30
- 
+
 
 /* Macro to slow down io between EEPROM clock transitions */
 #define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { __SLOW_DOWN_IO; }}while(0)
@@ -286,7 +286,7 @@
 static unsigned int eth16i_irqmap[] = { 9, 10, 5, 15 };
 
 /* This is the Interrupt lookup table for Eth32i card */
-static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15 };  
+static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15 };
 #define EISA_IRQ_REG	0xc89
 
 static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
@@ -303,7 +303,7 @@
   struct enet_statistics stats;
   unsigned int tx_started:1;
   unsigned char tx_queue;         /* Number of packets in transmit buffer */
-  unsigned short tx_queue_len;         
+  unsigned short tx_queue_len;
   unsigned int tx_buf_size;
   unsigned long open_time;
 };
@@ -327,17 +327,17 @@
 static int eth16i_tx(struct sk_buff *skb, struct device *dev);
 static void eth16i_rx(struct device *dev);
 static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void eth16i_multicast(struct device *dev); 
+static void eth16i_multicast(struct device *dev);
 static void eth16i_select_regbank(unsigned char regbank, short ioaddr);
 static void eth16i_initialize(struct device *dev);
 static struct enet_statistics *eth16i_get_stats(struct device *dev);
 
 static char *cardname = "ICL EtherTeam 16i/32";
 
-#ifdef HAVE_DEVLIST 
+#ifdef HAVE_DEVLIST
 /* Support for alternate probe manager */
-/struct netdev_entry eth16i_drv = 
-   {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list}; 
+/struct netdev_entry eth16i_drv =
+   {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list};
 
 #else  /* Not HAVE_DEVLIST */
 int eth16i_probe(struct device *dev)
@@ -346,7 +346,7 @@
   int ioaddr;
   int base_addr = dev ? dev->base_addr : 0;
 
-  if(eth16i_debug > 4) 
+  if(eth16i_debug > 4)
     printk("Probing started for %s\n", cardname);
 
   if(base_addr > 0x1ff)           /* Check only single location */
@@ -381,12 +381,12 @@
   boot = 1;          /* To inform initialization that we are in boot probe */
 
   /*
-     The MB86985 chip has on register which holds information in which 
+     The MB86985 chip has on register which holds information in which
      io address the chip lies. First read this register and compare
      it to our current io address and if match then this could
      be our chip.
   */
-  
+
   if(ioaddr < 0x1000) {
     if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] != ioaddr)
       return -ENODEV;
@@ -396,21 +396,21 @@
 
   if(eth16i_check_signature(ioaddr) != 0) /* Can we find the signature here */
     return -ENODEV;
-  
-  /* 
+
+  /*
      Now it seems that we have found an ethernet chip in this particular
-     ioaddr. The MB86985 chip has this feature, that when you read a 
+     ioaddr. The MB86985 chip has this feature, that when you read a
      certain register it will increase its io base address to next
      configurable slot. Now when we have found the chip, first thing is
      to make sure that the chip's ioaddr will hold still here.
   */
-  
+
   eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
   outb(0x00, ioaddr + TRANSCEIVER_MODE_REG);
-  
+
   outb(0x00, ioaddr + RESET);             /* Will reset some parts of chip */
   BITSET(ioaddr + CONFIG_REG_0, BIT(7));  /* This will disable the data link */
-  
+
   if(dev == NULL)
     dev = init_etherdev(0, sizeof(struct eth16i_local));
 
@@ -418,18 +418,18 @@
     printk(version);
 
   dev->base_addr = ioaddr;
- 
+
   irq = eth16i_get_irq(ioaddr);
   dev->irq = irq;
 
   /* Try to obtain interrupt vector */
   if(request_irq(dev->irq, &eth16i_interrupt, 0, "eth16i", NULL)) {
-    printk("%s: %s at %#3x, but is unusable due 
+    printk("%s: %s at %#3x, but is unusable due
            conflict on IRQ %d.\n", dev->name, cardname, ioaddr, irq);
     return EAGAIN;
   }
 
-  printk("%s: %s at %#3x, IRQ %d, ", 
+  printk("%s: %s at %#3x, IRQ %d, ",
 	 dev->name, cardname, ioaddr, dev->irq);
 
   /* Let's grab the region */
@@ -437,13 +437,13 @@
 
   /* Now we will have to lock the chip's io address */
   eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
-  outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); 
+  outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
 
   eth16i_initialize(dev);   /* Initialize rest of the chip's registers */
-  
+
   /* Now let's same some energy by shutting down the chip ;) */
   BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
-   
+
   /* Initialize the device structure */
   if(dev->priv == NULL)
     dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL);
@@ -477,7 +477,7 @@
     ((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
   }
 
-  for(i = 0; i < 6; i++) { 
+  for(i = 0; i < 6; i++) {
     outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
     if(boot) {
       printk("%02x", inb(ioaddr + NODE_ID_0 + i));
@@ -488,11 +488,11 @@
 
   /* Now we will set multicast addresses to accept none */
   eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
-  for(i = 0; i < 8; i++) 
+  for(i = 0; i < 8; i++)
     outb(0x00, ioaddr + HASH_TABLE_0 + i);
 
   /*
-     Now let's disable the transmitter and receiver, set the buffer ram 
+     Now let's disable the transmitter and receiver, set the buffer ram
      cycle time, bus width and buffer data path width. Also we shall
      set transmit buffer size and total buffer size.
   */
@@ -509,7 +509,7 @@
 
   if( (node_w & 0x00FF) == 64)
     node_byte |= MBS0;
-  
+
   node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2);
 
   outb(node_byte, ioaddr + CONFIG_REG_0);
@@ -520,15 +520,15 @@
   if(boot) /* Now set port type */
   {
     char *porttype[] = {"BNC", "DIX", "TP", "AUTO"};
-    
+
     ushort ptype = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
     dev->if_port = (ptype & 0x00FF);
-    
+
     printk(" %s interface.\n", porttype[dev->if_port]);
 
     if(ptype == E_PORT_AUTO)
       ptype = eth16i_probe_port(ioaddr);
-    
+
     eth16i_set_port(ioaddr, ptype);
   }
 
@@ -563,7 +563,7 @@
     BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
     BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
     eth16i_set_port(ioaddr, i);
-   
+
     if(eth16i_debug > 1)
     	printk("Set port number %d\n", i);
 
@@ -581,15 +581,15 @@
       	printk("TRANSMIT_DONE timeout\n");
     }
   }
-  
+
   if( eth16i_debug > 1)
   	printk("Using default port\n");
- 
+
  return E_PORT_BNC;
 }
 
 static void eth16i_set_port(short ioaddr, int porttype)
-{ 
+{
     unsigned short temp = 0;
 
     eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
@@ -605,12 +605,12 @@
 
     case E_PORT_TP :
       break;
-      
+
     case E_PORT_DIX :
       temp |= AUI_SELECT;
       BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
       break;
-    }  
+    }
     outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
 
     if(eth16i_debug > 1) {
@@ -626,29 +626,29 @@
   outb(0xff, ioaddr + TX_STATUS_REG);
 
   outw(l, ioaddr + DATAPORT);
-  outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);  
-  
+  outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);
+
   starttime = jiffies;
-  outb(TX_START | 1, ioaddr + TRANSMIT_START_REG); 
+  outb(TX_START | 1, ioaddr + TRANSMIT_START_REG);
 
   while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
     if( (jiffies - starttime) > TIMEOUT_TICKS) {
       break;
     }
   }
-  
+
   return(0);
 }
 
 static int eth16i_receive_probe_packet(short ioaddr)
 {
   int starttime;
-  
+
   starttime = jiffies;
-  
+
   while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) {
     if( (jiffies - starttime) > TIMEOUT_TICKS) {
-      
+
       if(eth16i_debug > 1)
 	printk("Timeout occurred waiting transmit packet received\n");
       starttime = jiffies;
@@ -659,7 +659,7 @@
         return -1;
         }
       }
-      
+
       if(eth16i_debug > 1)
       	printk("RECEIVE_PACKET\n");
       return(0); /* Found receive packet */
@@ -677,7 +677,7 @@
 static int eth16i_get_irq(short ioaddr)
 {
   unsigned char cbyte;
-  
+
   if( ioaddr < 0x1000) {
   	cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
 	return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
@@ -696,11 +696,11 @@
 {
   int i;
   unsigned char creg[4] = { 0 };
-  
+
   for(i = 0; i < 4 ; i++) {
 
     creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
-  
+
     if(eth16i_debug > 1)
 	printk("eth16i: read signature byte %x at %x\n", creg[i],
 	       ioaddr + TRANSMIT_MODE_REG + i);
@@ -710,7 +710,7 @@
   creg[2] &= 0x7F;      /* Mask DCLEN bit */
 
 #ifdef 0
-/* 
+/*
 	This was removed because the card was sometimes left to state
   	from which it couldn't be find anymore. If there is need
 	to more strict chech still this have to be fixed.
@@ -746,7 +746,7 @@
   data = eth16i_read_eeprom_word(ioaddr);
   outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
 
-  return(data);  
+  return(data);
 }
 
 static int eth16i_read_eeprom_word(int ioaddr)
@@ -769,7 +769,7 @@
 static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
 {
   int i;
-  
+
   outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
   outb(DI_0, ioaddr + EEPROM_DATA_REG);
   outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
@@ -783,31 +783,31 @@
     eeprom_slow_io();
     outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
     eeprom_slow_io();
-  } 
+  }
 }
 
 static int eth16i_open(struct device *dev)
 {
   struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
   int ioaddr = dev->base_addr;
-  
+
   irq2dev_map[dev->irq] = dev;
 
   /* Powerup the chip */
   outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
-  
+
   /* Initialize the chip */
-  eth16i_initialize(dev);  
-  
+  eth16i_initialize(dev);
+
   /* Set the transmit buffer size */
   lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
-  
+
   if(eth16i_debug > 3)
     printk("%s: transmit buffer size %d\n", dev->name, lp->tx_buf_size);
 
   /* Now enable Transmitter and Receiver sections */
   BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
- 
+
   /* Now switch to register bank 2, for run time operation */
   eth16i_select_regbank(2, ioaddr);
 
@@ -817,7 +817,7 @@
   lp->tx_queue_len = 0;
 
   /* Turn on interrupts*/
-  outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);  
+  outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
 
   dev->tbusy = 0;
   dev->interrupt = 0;
@@ -862,24 +862,24 @@
   int ioaddr = dev->base_addr;
 
   if(dev->tbusy) {
-    /* 
-       If we get here, some higher level has decided that we are broken. 
-       There should really be a "kick me" function call instead. 
+    /*
+       If we get here, some higher level has decided that we are broken.
+       There should really be a "kick me" function call instead.
     */
-    
+
     int tickssofar = jiffies - dev->trans_start;
-    if(tickssofar < TIMEOUT_TICKS)  /* Let's not rush with our timeout, */  
+    if(tickssofar < TIMEOUT_TICKS)  /* Let's not rush with our timeout, */
       return 1;                     /* wait a couple of ticks first     */
 
     printk("%s: transmit timed out with status %04x, %s ?\n", dev->name,
-	   inw(ioaddr + TX_STATUS_REG), 
-	   (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ? 
+	   inw(ioaddr + TX_STATUS_REG),
+	   (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
 	   "IRQ conflict" : "network cable problem");
 
     /* Let's dump all registers */
-    if(eth16i_debug > 0) { 
+    if(eth16i_debug > 0) {
       printk("%s: timeout regs: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
-	     dev->name, inb(ioaddr + 0), inb(ioaddr + 1), inb(ioaddr + 2), 
+	     dev->name, inb(ioaddr + 0), inb(ioaddr + 1), inb(ioaddr + 2),
 	     inb(ioaddr + 3), inb(ioaddr + 4), inb(ioaddr + 5),
 	     inb(ioaddr + 6), inb(ioaddr + 7));
 
@@ -893,27 +893,27 @@
     lp->stats.tx_errors++;
 
     /* Now let's try to restart the adaptor */
-    
+
     BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
     outw(0xffff, ioaddr + RESET);
     eth16i_initialize(dev);
     outw(0xffff, ioaddr + TX_STATUS_REG);
     BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
-            
+
     lp->tx_started = 0;
     lp->tx_queue = 0;
     lp->tx_queue_len = 0;
-    
+
     outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-    
+
     dev->tbusy = 0;
     dev->trans_start = jiffies;
   }
 
-  /* 
+  /*
      If some higher layer thinks we've missed an tx-done interrupt
      we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-     itself 
+     itself
   */
   if(skb == NULL) {
     dev_tint(dev);
@@ -931,19 +931,19 @@
   else {
     short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
     unsigned char *buf = skb->data;
-  
+
     outw(length, ioaddr + DATAPORT);
-    
-    if( ioaddr < 0x1000 ) 
+
+    if( ioaddr < 0x1000 )
     	outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
     else {
 	unsigned char frag = length % 4;
 
 	outsl(ioaddr + DATAPORT, buf, length >> 2);
-	
+
 	if( frag != 0 ) {
 	  outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
-	  if( frag == 3 ) 
+	  if( frag == 3 )
 	    outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC) + 2), 1);
 	}
     }
@@ -964,12 +964,12 @@
       /* There is still more room for one more packet in tx buffer */
       dev->tbusy = 0;
     }
-        
+
     outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
 
     /* Turn TX interrupts back on */
     /* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
-  } 
+  }
   dev_kfree_skb(skb, FREE_WRITE);
 
   return 0;
@@ -983,14 +983,14 @@
 
   /* Loop until all packets have been read */
   while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
-    
-    /* Read status byte from receive buffer */ 
+
+    /* Read status byte from receive buffer */
     ushort status = inw(ioaddr + DATAPORT);
 
     if(eth16i_debug > 4)
-      printk("%s: Receiving packet mode %02x status %04x.\n", 
+      printk("%s: Receiving packet mode %02x status %04x.\n",
 	     dev->name, inb(ioaddr + RECEIVE_MODE_REG), status);
-  
+
       if( !(status & PKT_GOOD) ) {
 	/* Hmm..something went wrong. Let's check what error occurred */
 	lp->stats.rx_errors++;
@@ -1006,7 +1006,7 @@
 	ushort pkt_len = inw(ioaddr + DATAPORT);
 
 	if(pkt_len > ETH_FRAME_LEN) {
-	  printk("%s: %s claimed a very large packet, size of %d bytes.\n", 
+	  printk("%s: %s claimed a very large packet, size of %d bytes.\n",
 		 dev->name, cardname, pkt_len);
 	  outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
 	  lp->stats.rx_dropped++;
@@ -1015,29 +1015,29 @@
 
 	skb = dev_alloc_skb(pkt_len + 3);
 	if( skb == NULL ) {
-	  printk("%s: Couldn't allocate memory for packet (len %d)\n", 
+	  printk("%s: Couldn't allocate memory for packet (len %d)\n",
 		 dev->name, pkt_len);
 	  outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
 	  lp->stats.rx_dropped++;
 	  break;
 	}
-	
+
 	skb->dev = dev;
 	skb_reserve(skb,2);
-	/* 
+	/*
 	   Now let's get the packet out of buffer.
 	   size is (pkt_len + 1) >> 1, cause we are now reading words
 	   and it have to be even aligned.
-	*/ 
+	*/
 
-	if( ioaddr < 0x1000) 
+	if( ioaddr < 0x1000)
 	  insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), (pkt_len + 1) >> 1);
-	else {	
+	else {
 	  unsigned char *buf = skb_put(skb, pkt_len);
 	  unsigned char frag = pkt_len % 4;
 
 	  insl(ioaddr + DATAPORT, buf, pkt_len >> 2);
-	
+
 	  if(frag != 0) {
 	  	unsigned short rest[2];
 		rest[0] = inw( ioaddr + DATAPORT );
@@ -1047,19 +1047,19 @@
 		memcpy(buf + (pkt_len & 0xfffc), (char *)rest, frag);
 	  }
 	}
-	
+
         skb->protocol=eth_type_trans(skb, dev);
 	netif_rx(skb);
 	lp->stats.rx_packets++;
-         
+
 	if( eth16i_debug > 5 ) {
 	  int i;
 	  printk("%s: Received packet of length %d.\n", dev->name, pkt_len);
-	  for(i = 0; i < 14; i++) 
+	  for(i = 0; i < 14; i++)
 	    printk(" %02x", skb->data[i]);
 	  printk(".\n");
 	}
-	
+
       } /* else */
 
     if(--boguscount <= 0)
@@ -1099,7 +1099,7 @@
   }
 
   /* Turn off all interrupts from adapter */
-  outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); 
+  outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
 
   dev->interrupt = 1;
 
@@ -1107,12 +1107,12 @@
   lp = (struct eth16i_local *)dev->priv;
   status = inw(ioaddr + TX_STATUS_REG);      /* Get the status */
   outw(status, ioaddr + TX_STATUS_REG);      /* Clear status bits */
-  
+
   if(eth16i_debug > 3)
     printk("%s: Interrupt with status %04x.\n", dev->name, status);
 
   if( status & 0x00ff ) {          /* Let's check the transmit status reg */
-    
+
     if(status & TX_DONE) {         /* The transmit has been done */
       lp->stats.tx_packets++;
 
@@ -1133,14 +1133,14 @@
       }
     }
   }
-    
-  if( ( status & 0xff00 ) || 
+
+  if( ( status & 0xff00 ) ||
      ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
     eth16i_rx(dev);  /* We have packet in receive buffer */
   }
 
   dev->interrupt = 0;
-  
+
   /* Turn interrupts back on */
   outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
 
@@ -1150,11 +1150,11 @@
 static void eth16i_multicast(struct device *dev)
 {
   short ioaddr = dev->base_addr;
-  
-  if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 
+
+  if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
   {
     dev->flags|=IFF_PROMISC;	/* Must do this */
-    outb(3, ioaddr + RECEIVE_MODE_REG);    
+    outb(3, ioaddr + RECEIVE_MODE_REG);
   } else {
     outb(2, ioaddr + RECEIVE_MODE_REG);
   }
@@ -1172,7 +1172,7 @@
   unsigned char data;
 
   data = inb(ioaddr + CONFIG_REG_1);
-  outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1); 
+  outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1);
 }
 
 #ifdef MODULE
@@ -1186,11 +1186,14 @@
 int io = 0x2a0;
 int irq = 0;
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+
 int init_module(void)
 {
 	if(io == 0)
 		printk("eth16i: You should not use auto-probing with insmod!\n");
-	
+
 	dev_eth16i.base_addr = io;
 	dev_eth16i.irq = irq;
 	if( register_netdev( &dev_eth16i ) != 0 ) {
@@ -1210,5 +1213,3 @@
 }
 
 #endif /* MODULE */
-
-
diff -u --recursive --new-file v2.1.18/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- v2.1.18/linux/drivers/net/ewrk3.c	Tue Nov 12 15:56:07 1996
+++ linux/drivers/net/ewrk3.c	Tue Dec 31 10:30:01 1996
@@ -76,14 +76,14 @@
     kernel with the ewrk3 configuration turned off and reboot.
     5) insmod ewrk3.o
           [Alan Cox: Changed this so you can insmod ewrk3.o irq=x io=y]
-    6) run the net startup bits for your new eth?? interface manually 
-    (usually /etc/rc.inet[12] at boot time). 
+    6) run the net startup bits for your new eth?? interface manually
+    (usually /etc/rc.inet[12] at boot time).
     7) enjoy!
 
     Note that autoprobing is not allowed in loadable modules - the system is
     already up and running and you're messing with interrupts.
 
-    To unload a module, turn off the associated interface 
+    To unload a module, turn off the associated interface
     'ifconfig eth?? down' then 'rmmod ewrk3'.
 
     Promiscuous   mode has been  turned  off  in this driver,   but  all the
@@ -105,9 +105,9 @@
     ----------------
 
     Version   Date        Description
-  
+
       0.1     26-aug-94   Initial writing. ALPHA code release.
-      0.11    31-aug-94   Fixed: 2k mode memory base calc., 
+      0.11    31-aug-94   Fixed: 2k mode memory base calc.,
                                  LeMAC version calc.,
 				 IRQ vector assignments during autoprobe.
       0.12    31-aug-94   Tested working on LeMAC2 (DE20[345]-AC) card.
@@ -128,7 +128,7 @@
                           Added verify_area() calls in ewrk3_ioctl() from
                           suggestion by <heiko@colossus.escape.de>.
 			  Add new multicasting code.
-      0.41    20-Jan-96   Fix IRQ set up problem reported by 
+      0.41    20-Jan-96   Fix IRQ set up problem reported by
                           <kenneth@bbs.sas.ntu.ac.sg>.
       0.42    22-Apr-96	  Fix alloc_device() bug <jari@markkus2.fimr.fi>
       0.43    16-Aug-96	  Update alloc_device() to conform to de4x5.c
@@ -196,7 +196,7 @@
 #define MAX_NUM_EWRK3S 21
 #endif
 
-#ifndef EWRK3_EISA_IO_PORTS 
+#ifndef EWRK3_EISA_IO_PORTS
 #define EWRK3_EISA_IO_PORTS 0x0c00      /* I/O port base address, slot 0 */
 #endif
 
@@ -358,7 +358,7 @@
     eisa_probe(dev, iobase);
 
     if ((tmp == num_ewrk3s) && (iobase != 0) && loading_module) {
-      printk("%s: ewrk3_probe() cannot find device at 0x%04lx.\n", dev->name, 
+      printk("%s: ewrk3_probe() cannot find device at 0x%04lx.\n", dev->name,
 	                                                               iobase);
     }
 
@@ -419,7 +419,7 @@
       EthwrkSignature(name, eeprom_image);
       if (*name != '\0') {                         /* found a EWRK3 device */
 	dev->base_addr = iobase;
-      
+
 	if (iobase > 0x400) {
 	  outb(eisa_cr, EISA_CR);                  /* Rewrite the EISA CR */
 	}
@@ -433,12 +433,12 @@
 	  hard_strapped = 1;
 	} else if ((iobase&0x0fff)==EWRK3_EISA_IO_PORTS) {
 	                                           /* EISA slot address */
-	  printk("%s: %s at %#4lx (EISA slot %ld)", 
+	  printk("%s: %s at %#4lx (EISA slot %ld)",
 	                         dev->name, name, iobase, ((iobase>>12)&0x0f));
 	} else {                                   /* ISA port address */
 	  printk("%s: %s at %#4lx", dev->name, name, iobase);
 	}
-	
+
 	if (!status) {
 	  printk(", h/w address ");
 	  if (lemac!=LeMAC2) DevicePresent(iobase);/* need after EWRK3_INIT */
@@ -470,7 +470,7 @@
 	    cr |= eeprom_image[EEPROM_MISC0] & ENA_16;
 	    outb(cr, EWRK3_CR);
 
-	    /* 
+	    /*
 	    ** Determine the base address and window length for the EWRK3
 	    ** RAM from the memory base register.
 	    */
@@ -490,7 +490,7 @@
 		status = -ENXIO;
 	      }
 	    }
-	  
+
 	    /*
 	    ** See the top of this source code for comments about
 	    ** uncommenting this line.
@@ -506,9 +506,9 @@
 	      } else {
 		printk("      is in I/O only mode");
 	      }
-	    
+
 	      /* private area & initialise */
-	      dev->priv = (void *) kmalloc(sizeof(struct ewrk3_private), 
+	      dev->priv = (void *) kmalloc(sizeof(struct ewrk3_private),
 					                           GFP_KERNEL);
 	      if (dev->priv == NULL) {
 		return -ENOMEM;
@@ -521,40 +521,40 @@
 	      lp->hard_strapped = hard_strapped;
 
 	      lp->mPage = 64;
-	      if (cmr & CMR_DRAM) lp->mPage <<= 1 ;/* 2 DRAMS on module */ 
+	      if (cmr & CMR_DRAM) lp->mPage <<= 1 ;/* 2 DRAMS on module */
 
 	      sprintf(lp->adapter_name,"%s (%s)", name, dev->name);
 	      request_region(iobase, EWRK3_TOTAL_SIZE, lp->adapter_name);
 
 	      lp->irq_mask = ICR_TNEM|ICR_TXDM|ICR_RNEM|ICR_RXDM;
-	      
+
 	      if (!hard_strapped) {
 		/*
 		** Enable EWRK3 board interrupts for autoprobing
 		*/
 		icr |= ICR_IE;	                   /* Enable interrupts */
 		outb(icr, EWRK3_ICR);
-	    
+
 		/* The DMA channel may be passed in on this parameter. */
 		dev->dma = 0;
-	
+
 		/* To auto-IRQ we enable the initialization-done and DMA err,
 		   interrupts. For now we will always get a DMA error. */
 		if (dev->irq < 2) {
 #ifndef MODULE
 		  u_char irqnum;
-	      
+
 		  autoirq_setup(0);
 
-		  /* 
+		  /*
 		  ** Trigger a TNE interrupt.
 		  */
 		  icr |=ICR_TNEM;
 		  outb(1,EWRK3_TDQ);          /* Write to the TX done queue */
 		  outb(icr, EWRK3_ICR);       /* Unmask the TXD interrupt */
-	      
+
 		  irqnum = irq[((icr & IRQ_SEL) >> 4)];
-	      
+
 		  dev->irq = autoirq_report(1);
 		  if ((dev->irq) && (irqnum == dev->irq)) {
 		    printk(" and uses IRQ%d.\n", dev->irq);
@@ -568,7 +568,7 @@
 		    }
 		    status = -ENXIO;
 		  }
-		
+
 		  DISABLE_IRQs;                 /* Mask all interrupts */
 
 #endif /* MODULE */
@@ -591,7 +591,7 @@
       if (ewrk3_debug > 1) {
 	printk(version);
       }
-      
+
       /* The EWRK3-specific entries in the device structure. */
       dev->open = &ewrk3_open;
       dev->hard_start_xmit = &ewrk3_queue_pkt;
@@ -601,7 +601,7 @@
       dev->do_ioctl = &ewrk3_ioctl;
 
       dev->mem_start = 0;
-	
+
       /* Fill in the generic field of the device structure. */
       ether_setup(dev);
     }
@@ -634,8 +634,8 @@
       status = -EAGAIN;
     } else {
 
-      /* 
-      ** Re-initialize the EWRK3... 
+      /*
+      ** Re-initialize the EWRK3...
       */
       ewrk3_init(dev);
 
@@ -660,7 +660,7 @@
 	printk("  fmqc: 0x%02x\n", inb(EWRK3_FMQC));
       }
 
-      dev->tbusy = 0;                         
+      dev->tbusy = 0;
       dev->start = 1;
       dev->interrupt = UNMASK_INTERRUPTS;
 
@@ -692,9 +692,9 @@
   struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
   u_char csr, page;
   u_long iobase = dev->base_addr;
-  
-  /* 
-  ** Enable any multicasts 
+
+  /*
+  ** Enable any multicasts
   */
   set_multicast_list(dev);
 
@@ -718,7 +718,7 @@
   START_EWRK3;                              /* Enable the TX and/or RX */
 }
 
-/* 
+/*
 ** Writes a socket buffer to the free page queue
 */
 static int
@@ -737,7 +737,7 @@
     } else if (!lp->hard_strapped) {
       printk("%s: transmit timed/locked out, status %04x, resetting.\n",
 	                                           dev->name, inb(EWRK3_CSR));
-	
+
       /*
       ** Mask all board interrupts
       */
@@ -762,16 +762,16 @@
     dev_tint(dev);
   } else if (skb->len > 0) {
 
-    /* 
+    /*
     ** Block a timer-based transmit from overlapping.  This could better be
-    ** done with atomic_swap(1, dev->tbusy), but set_bit() works as well. 
+    ** done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
     */
     if (set_bit(0, (void*)&dev->tbusy) != 0)
       printk("%s: Transmitter access conflict.\n", dev->name);
 
     DISABLE_IRQs;                      /* So that the page # remains correct */
-    
-    /* 
+
+    /*
     ** Get a free page from the FMQ when resources are available
     */
     if (inb(EWRK3_FMQC) > 0) {
@@ -801,7 +801,7 @@
 
 	if (!status) {
 
-          /* 
+          /*
 	  ** Set up the buffer control structures and copy the data from
 	  ** the socket buffer to the shared memory .
 	  */
@@ -809,7 +809,7 @@
 	  if (lp->shmem_length == IO_ONLY) {
 	    int i;
 	    u_char *p = skb->data;
-	    
+
 	    outb((char)(TCR_QMODE | TCR_PAD | TCR_IFC), EWRK3_DATA);
 	    outb((char)(skb->len & 0xff), EWRK3_DATA);
 	    outb((char)((skb->len >> 8) & 0xff), EWRK3_DATA);
@@ -858,7 +858,7 @@
       printk("ewrk3_queue_pkt(): No free resources...\n");
       printk("ewrk3_queue_pkt(): CSR: %02x ICR: %02x FMQC: %02x\n",inb(EWRK3_CSR),inb(EWRK3_ICR),inb(EWRK3_FMQC));
     }
-    
+
     /* Check for free resources: clear 'tbusy' if there are some */
     if (inb(EWRK3_FMQC) > 0) {
       dev->tbusy = 0;
@@ -871,7 +871,7 @@
 }
 
 /*
-** The EWRK3 interrupt handler. 
+** The EWRK3 interrupt handler.
 */
 static void
 ewrk3_interrupt(int irq, void *dev_id, struct pt_regs * regs)
@@ -895,8 +895,8 @@
       /* get the interrupt information */
       csr = inb(EWRK3_CSR);
 
-      /* 
-      ** Mask the EWRK3 board interrupts and turn on the LED 
+      /*
+      ** Mask the EWRK3 board interrupts and turn on the LED
       */
       DISABLE_IRQs;
 
@@ -1017,8 +1017,8 @@
 	      memcpy_fromio(p, buf, pkt_len);
 	    }
 
-	    /* 
-	    ** Notify the upper protocol layers that there is another 
+	    /*
+	    ** Notify the upper protocol layers that there is another
 	    ** packet to handle
 	    */
 	    skb->protocol=eth_type_trans(skb,dev);
@@ -1131,7 +1131,7 @@
 	   dev->name, inb(EWRK3_CSR));
   }
 
-  /* 
+  /*
   ** We stop the EWRK3 here... mask interrupts and stop TX & RX
   */
   DISABLE_IRQs;
@@ -1150,7 +1150,7 @@
 
   if (!lp->hard_strapped) {
     free_irq(dev->irq, NULL);
-    
+
     irq2dev_map[dev->irq] = 0;
   }
 
@@ -1165,7 +1165,7 @@
   struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
 
   /* Null body since there is no framing error counter */
-    
+
   return &lp->stats;
 }
 
@@ -1181,7 +1181,7 @@
 
   if (irq2dev_map[dev->irq] != NULL) {
     csr = inb(EWRK3_CSR);
-    
+
     if (lp->shmem_length == IO_ONLY) {
       lp->mctbl = (char *) PAGE0_HTE;
     } else {
@@ -1242,11 +1242,11 @@
     if (lp->shmem_length == IO_ONLY) {
       for (i=0; i<(HASH_TABLE_LEN >> 4) - 1; i++) {
 	outb(0x00, EWRK3_DATA);
-      } 
+      }
       outb(0x80, EWRK3_DATA); i++;           /* insert the broadcast bit */
       for (; i<(HASH_TABLE_LEN >> 3); i++) {
 	outb(0x00, EWRK3_DATA);
-      } 
+      }
     } else {
       memset_io(lp->mctbl, 0, (HASH_TABLE_LEN >> 3));
       writeb(0x80, (char *)(lp->mctbl + (HASH_TABLE_LEN >> 4) - 1));
@@ -1256,10 +1256,10 @@
     for (i=0;i<dev->mc_count;i++) {          /* for each address in the list */
       addrs=dmi->dmi_addr;
       dmi=dmi->next;
-      if ((*addrs & 0x01) == 1) {            /* multicast address? */ 
+      if ((*addrs & 0x01) == 1) {            /* multicast address? */
 	crc = 0xffffffff;                    /* init CRC for each address */
 	for (byte=0;byte<ETH_ALEN;byte++) {  /* for each address byte */
-	                                     /* process each address bit */ 
+	                                     /* process each address bit */
 	  for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
 	    crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0);
 	  }
@@ -1276,7 +1276,7 @@
 	  tmp = inb(EWRK3_DATA);
 	  tmp |= bit;
 	  outw((short)((long)lp->mctbl) + byte, EWRK3_PIR1);
-	  outb(tmp, EWRK3_DATA); 
+	  outb(tmp, EWRK3_DATA);
 	} else {
 	  writeb(readb(lp->mctbl + byte) | bit, lp->mctbl + byte);
 	}
@@ -1309,7 +1309,7 @@
   }
 
   for (; (i<maxSlots) && (dev!=NULL);iobase+=EWRK3_IOP_INC, i++) {
-    if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {    
+    if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {
       if (DevicePresent(iobase) == 0) {
 	if ((dev = alloc_device(dev, iobase)) != NULL) {
 	  if (ewrk3_hw_init(dev, iobase) == 0) {
@@ -1383,7 +1383,7 @@
 
     num_eth = ewrk3_dev_index(dev->name);
     if (loading_module) return dev;
-    
+
     while (1) {
 	if (((dev->base_addr == EWRK3_NDA) || (dev->base_addr==0)) && !adev) {
 	    adev=dev;
@@ -1406,13 +1406,13 @@
 	new_dev = 0;
     }
 
-    if (((dev->next == NULL) &&  
+    if (((dev->next == NULL) &&
 	((dev->base_addr != EWRK3_NDA) && (dev->base_addr != 0)) && !fixed) ||
 	new_dev) {
 	num_eth++;                         /* New device */
 	dev = insert_device(dev, iobase, ewrk3_probe);
     }
-    
+
     return dev;
 }
 
@@ -1525,7 +1525,7 @@
 /*
 ** Look for a special sequence in the Ethernet station address PROM that
 ** is common across all EWRK3 products.
-** 
+**
 ** Search the Ethernet address ROM for the signature. Since the ROM address
 ** counter can start at an arbitrary point, the search must include the entire
 ** probe sequence length plus the (length_of_the_signature - 1).
@@ -1737,7 +1737,7 @@
 	memcpy_fromio(tmp.addr, (char *)(lp->shmem_base + PAGE0_HTE), (HASH_TABLE_LEN >> 3));
       }
       ioc->len = (HASH_TABLE_LEN >> 3);
-      copy_to_user(ioc->data, tmp.addr, ioc->len); 
+      copy_to_user(ioc->data, tmp.addr, ioc->len);
     }
     lp->lock = 0;                               /* Unlock the page register */
 
@@ -1776,7 +1776,7 @@
     cli();
     ioc->len = sizeof(lp->pktStats);
     if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
-      copy_to_user(ioc->data, &lp->pktStats, ioc->len); 
+      copy_to_user(ioc->data, &lp->pktStats, ioc->len);
     }
     sti();
 
@@ -1880,10 +1880,13 @@
   0, 0, 0, 0,
   0x300, 5,   /* I/O address, IRQ */
   0, 0, 0, NULL, ewrk3_probe };
-	
+
 static int io=0x300;	/* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
 static int irq=5;	/* or use the insmod io= irq= options 		*/
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+
 int
 init_module(void)
 {
@@ -1916,4 +1919,3 @@
  *  compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c ewrk3.c"
  * End:
  */
-
diff -u --recursive --new-file v2.1.18/linux/drivers/net/fmv18x.c linux/drivers/net/fmv18x.c
--- v2.1.18/linux/drivers/net/fmv18x.c	Wed Oct  9 08:55:19 1996
+++ linux/drivers/net/fmv18x.c	Tue Dec 31 10:30:01 1996
@@ -264,7 +264,7 @@
 	dev->set_multicast_list = &set_multicast_list;
 
 	/* Fill in the fields of 'dev' with ethernet-generic values. */
-	   
+
 	ether_setup(dev);
 	return 0;
 }
@@ -374,7 +374,7 @@
 
 		/* Disable both interrupts. */
 		outw(0x0000, ioaddr + TX_INTR);
-		
+
 		outw(length, ioaddr + DATAPORT);
 		outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
 
@@ -543,7 +543,7 @@
 		}
 
 		if (net_debug > 5 && i > 0)
-			printk("%s: Exint Rx packet with mode %02x after %d ticks.\n", 
+			printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
 				   dev->name, inb(ioaddr + RX_MODE), i);
 	}
 
@@ -600,17 +600,17 @@
 set_multicast_list(struct device *dev)
 {
 	short ioaddr = dev->base_addr;
-	if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI)) 
+	if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI))
 	{
 		/*
 		 *	We must make the kernel realise we had to move
 		 *	into promisc mode or we start all out war on
 		 *	the cable. - AC
 		 */
-		dev->flags|=IFF_PROMISC;		
-	
+		dev->flags|=IFF_PROMISC;
+
 		outb(3, ioaddr + RX_MODE);	/* Enable promiscuous mode */
-	} 
+	}
 	else
 		outb(2, ioaddr + RX_MODE);	/* Disable promiscuous, use normal mode */
 }
@@ -625,6 +625,9 @@
 
 static int io = 0x220;
 static int irq = 0;
+
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.1.18/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c
--- v2.1.18/linux/drivers/net/hp-plus.c	Wed Oct  9 08:55:19 1996
+++ linux/drivers/net/hp-plus.c	Tue Dec 31 10:30:01 1996
@@ -67,7 +67,7 @@
 */
 
 #define HP_ID			0x00	/* ID register, always 0x4850. */
-#define HP_PAGING		0x02	/* Registers visible @ 8-f, see PageName. */ 
+#define HP_PAGING		0x02	/* Registers visible @ 8-f, see PageName. */
 #define HPP_OPTION		0x04	/* Bitmapped options, see HP_Option.	*/
 #define HPP_OUT_ADDR	0x08	/* I/O output location in Perf_Page.	*/
 #define HPP_IN_ADDR		0x0A	/* I/O input location in Perf_Page.		*/
@@ -84,7 +84,7 @@
 	MAC_Page = 1,				/* The ethernet address (+checksum). */
 	HW_Page = 2,				/* EEPROM-loaded hardware parameters. */
 	LAN_Page = 4,				/* Transceiver selection, testing, etc. */
-	ID_Page = 6 }; 
+	ID_Page = 6 };
 
 /* The bit definitions for the HPP_OPTION register. */
 enum HP_Option {
@@ -424,6 +424,9 @@
 
 static int io[MAX_HPP_CARDS] = { 0, };
 static int irq[MAX_HPP_CARDS]  = { 0, };
+
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HPP_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_HPP_CARDS) "i");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.1.18/linux/drivers/net/hp.c linux/drivers/net/hp.c
--- v2.1.18/linux/drivers/net/hp.c	Fri Mar  1 07:50:44 1996
+++ linux/drivers/net/hp.c	Tue Dec 31 10:30:01 1996
@@ -137,7 +137,7 @@
 
 	if (ei_debug  &&  version_printed++ == 0)
 		printk(version);
- 
+
 	printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
 
 	for(i = 0; i < ETHER_ADDR_LEN; i++)
@@ -237,7 +237,7 @@
 
 	outb_p(saved_config, hp_base + HP_CONFIGURE);
 	SLOW_DOWN_IO; SLOW_DOWN_IO;
-	
+
 	if ((inb_p(hp_base+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
 		printk("%s: hp_reset_8390() did not complete.\n", dev->name);
 
@@ -259,14 +259,14 @@
 	outb_p(ring_page, nic_base + EN0_RSARHI);
 	outb_p(E8390_RREAD+E8390_START, nic_base);
 
-	if (ei_status.word16) 
+	if (ei_status.word16)
 	  insw(nic_base - NIC_OFFSET + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
-	else 
+	else
 	  insb(nic_base - NIC_OFFSET + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
 
 	outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE);
 }
-	
+
 /* Block input and output, similar to the Crynwr packet driver. If you are
    porting to a new ethercard look at the packet driver source for hints.
    The HP LAN doesn't use shared memory -- we put the packet
@@ -391,6 +391,9 @@
 
 static int io[MAX_HP_CARDS] = { 0, };
 static int irq[MAX_HP_CARDS]  = { 0, };
+
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HP_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_HP_CARDS) "i");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.1.18/linux/drivers/net/hp100.c linux/drivers/net/hp100.c
--- v2.1.18/linux/drivers/net/hp100.c	Wed Oct  9 08:55:19 1996
+++ linux/drivers/net/hp100.c	Tue Dec 31 10:30:01 1996
@@ -17,13 +17,13 @@
  *
  * This driver is based on the 'hpfepkt' crynwr packet driver.
  *
- * This source/code is public free; you can distribute it and/or modify 
+ * This source/code is public free; you can distribute it and/or modify
  * it under terms of the GNU General Public License (published by the
- * Free Software Foundation) either version two of this License, or any 
+ * Free Software Foundation) either version two of this License, or any
  * later version.
  * ----------------------------------------------------------------------------
  *
- * Note: Some routines (interrupt handling, transmit) assumes that  
+ * Note: Some routines (interrupt handling, transmit) assumes that
  *       there is the PERFORMANCE page selected...
  *
  * ----------------------------------------------------------------------------
@@ -48,7 +48,7 @@
  * Russel Nellson <nelson@crynwr.com> for help with obtaining sources
  * of the 'hpfepkt' packet driver.
  *
- * Also thanks to Abacus Electric s.r.o which let me to use their 
+ * Also thanks to Abacus Electric s.r.o which let me to use their
  * motherboard for my second computer.
  *
  * ----------------------------------------------------------------------------
@@ -65,7 +65,7 @@
  *
  * Revision history:
  * =================
- * 
+ *
  *    Version   Date	    Description
  *
  *	0.1	14-May-95   Initial writing. ALPHA code was released.
@@ -157,17 +157,17 @@
 /*
  *  variables
  */
- 
+
 static struct hp100_eisa_id hp100_eisa_ids[] = {
 
   /* 10/100 EISA card with REVA Cascade chip */
-  { 0x080F1F022, "HP J2577 rev A", HP100_BUS_EISA }, 
+  { 0x080F1F022, "HP J2577 rev A", HP100_BUS_EISA },
 
   /* 10/100 ISA card with REVA Cascade chip */
   { 0x050F1F022, "HP J2573 rev A", HP100_BUS_ISA },
 
   /* 10 only EISA card with Cascade chip */
-  { 0x02019F022, "HP 27248B",      HP100_BUS_EISA }, 
+  { 0x02019F022, "HP 27248B",      HP100_BUS_EISA },
 
   /* 10/100 EISA card with Cascade chip */
   { 0x04019F022, "HP J2577",       HP100_BUS_EISA },
@@ -208,7 +208,7 @@
 /*
  *  probe functions
  */
- 
+
 int hp100_probe( struct device *dev )
 {
   int base_addr = dev ? dev -> base_addr : 0;
@@ -225,7 +225,7 @@
        else
         return hp100_probe1( dev, base_addr, HP100_BUS_EISA );
     }
-   else 
+   else
 #ifdef CONFIG_PCI
   if ( base_addr > 0 && base_addr < 8 + 1 )
     pci_start_index = 0x100 | ( base_addr - 1 );
@@ -234,12 +234,12 @@
     if ( base_addr != 0 ) return -ENXIO;
 
   /* at first - scan PCI bus(es) */
-  
+
 #ifdef CONFIG_PCI
   if ( pcibios_present() )
     {
       int pci_index;
-      
+
 #ifdef HP100_DEBUG_PCI
       printk( "hp100: PCI BIOS is present, checking for devices..\n" );
 #endif
@@ -247,17 +247,17 @@
         {
           u_char pci_bus, pci_device_fn;
           u_short pci_command;
-          
+
           if ( pcibios_find_device( PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A,
           			    pci_index, &pci_bus,
           			    &pci_device_fn ) != 0 ) break;
           pcibios_read_config_dword( pci_bus, pci_device_fn,
               		             PCI_BASE_ADDRESS_0, &ioaddr );
-              				 
+
           ioaddr &= ~3;		/* remove I/O space marker in bit 0. */
-              
+
           if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
-              
+
           pcibios_read_config_word( pci_bus, pci_device_fn,
               			    PCI_COMMAND, &pci_command );
           if ( !( pci_command & PCI_COMMAND_MASTER ) )
@@ -277,23 +277,23 @@
     }
   if ( pci_start_index > 0 ) return -ENODEV;
 #endif /* CONFIG_PCI */
-         
+
   /* at second - probe all EISA possible port regions (if EISA bus present) */
-  
+
   for ( ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400 )
     {
       if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
       if ( hp100_probe1( dev, ioaddr, HP100_BUS_EISA ) == 0 ) return 0;
     }
-         
+
   /* at third - probe all ISA possible port regions */
-         
+
   for ( ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20 )
     {
       if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
       if ( hp100_probe1( dev, ioaddr, HP100_BUS_ISA ) == 0 ) return 0;
     }
-                                                                            
+
   return -ENODEV;
 }
 
@@ -319,7 +319,7 @@
     if ( inb( ioaddr + 0 ) != HP100_HW_ID_0 ||
          inb( ioaddr + 1 ) != HP100_HW_ID_1 ||
          ( inb( ioaddr + 2 ) & 0xf0 ) != HP100_HW_ID_2_REVA ||
-         inb( ioaddr + 3 ) != HP100_HW_ID_3 ) 
+         inb( ioaddr + 3 ) != HP100_HW_ID_3 )
        return -ENODEV;
 
   dev -> base_addr = ioaddr;
@@ -346,7 +346,7 @@
     {
       printk( "hp100_probe: bad EISA ID checksum at base port 0x%x\n", ioaddr );
       return -ENODEV;
-    }  
+    }
 
   for ( i = 0; i < sizeof( hp100_eisa_ids ) / sizeof( struct hp100_eisa_id ); i++ )
     if ( ( hp100_eisa_ids[ i ].id & 0xf0ffffff ) == ( eisa_id & 0xf0ffffff ) )
@@ -359,7 +359,7 @@
   eid = &hp100_eisa_ids[ i ];
   if ( ( eid -> id & 0x0f000000 ) < ( eisa_id & 0x0f000000 ) )
     {
-      printk( "hp100_probe1: newer version of card %s at port 0x%x - unsupported\n", 
+      printk( "hp100_probe1: newer version of card %s at port 0x%x - unsupported\n",
 	eid -> name, ioaddr );
       return -ENODEV;
     }
@@ -368,19 +368,19 @@
     uc += hp100_inb( LAN_ADDR + i );
   if ( uc != 0xff )
     {
-      printk( "hp100_probe1: bad lan address checksum (card %s at port 0x%x)\n", 
+      printk( "hp100_probe1: bad lan address checksum (card %s at port 0x%x)\n",
 	eid -> name, ioaddr );
       return -EIO;
     }
 
 #ifndef HP100_IO_MAPPED
   hp100_page( HW_MAP );
-  mem_mapped = ( hp100_inw( OPTION_LSW ) & 
+  mem_mapped = ( hp100_inw( OPTION_LSW ) &
                  ( HP100_MEM_EN | HP100_BM_WRITE | HP100_BM_READ ) ) != 0;
   mem_ptr_phys = mem_ptr_virt = NULL;
   if ( mem_mapped )
     {
-      mem_ptr_phys = (u_char *)( hp100_inw( MEM_MAP_LSW ) | 
+      mem_ptr_phys = (u_char *)( hp100_inw( MEM_MAP_LSW ) |
                                ( hp100_inw( MEM_MAP_MSW ) << 16 ) );
       (u_int)mem_ptr_phys &= ~0x1fff;	/* 8k alignment */
       if ( bus == HP100_BUS_ISA && ( (u_long)mem_ptr_phys & ~0xfffff ) != 0 )
@@ -416,7 +416,7 @@
   lp -> soft_model = hp100_inb( SOFT_MODEL );
   lp -> mac1_mode = HP100_MAC1MODE3;
   lp -> mac2_mode = HP100_MAC2MODE3;
-  
+
   dev -> base_addr = ioaddr;
   hp100_page( HW_MAP );
   dev -> irq = hp100_inb( IRQ_CHANNEL ) & HP100_IRQ_MASK;
@@ -441,7 +441,7 @@
   ether_setup( dev );
 
   lp -> lan_type = hp100_sense_lan( dev );
-     
+
   printk( "%s: %s at 0x%x, IRQ %d, ",
     dev -> name, lp -> id -> name, ioaddr, dev -> irq );
   switch ( bus ) {
@@ -472,9 +472,9 @@
     default:
       printk( "Warning! Link down.\n" );
   }
-		
+
   hp100_stop_interface( dev );
-  
+
   return 0;
 }
 
@@ -496,7 +496,7 @@
   irq2dev_map[ dev -> irq ] = dev;
 
   MOD_INC_USE_COUNT;
-  
+
   dev -> tbusy = 0;
   dev -> trans_start = jiffies;
   dev -> interrupt = 0;
@@ -505,21 +505,21 @@
   lp -> lan_type = hp100_sense_lan( dev );
   lp -> mac1_mode = HP100_MAC1MODE3;
   lp -> mac2_mode = HP100_MAC2MODE3;
-  
+
   hp100_page( MAC_CTRL );
   hp100_orw( HP100_LINK_BEAT_DIS | HP100_RESET_LB, LAN_CFG_10 );
 
   hp100_stop_interface( dev );
   hp100_load_eeprom( dev );
 
-  hp100_outw( HP100_MMAP_DIS | HP100_SET_HB | 
+  hp100_outw( HP100_MMAP_DIS | HP100_SET_HB |
               HP100_IO_EN | HP100_SET_LB, OPTION_LSW );
   hp100_outw( HP100_DEBUG_EN | HP100_RX_HDR | HP100_EE_EN | HP100_RESET_HB |
               HP100_FAKE_INT | HP100_RESET_LB, OPTION_LSW );
   hp100_outw( HP100_ADV_NXT_PKT | HP100_TX_CMD | HP100_RESET_LB |
                 HP100_PRIORITY_TX | ( hp100_priority_tx ? HP100_SET_HB : HP100_RESET_HB ),
               OPTION_MSW );
-              				
+
   hp100_page( MAC_ADDRESS );
   for ( i = 0; i < 6; i++ )
     hp100_outb( dev -> dev_addr[ i ], MAC_ADDR + i );
@@ -567,7 +567,7 @@
   return 0;
 }
 
-/* 
+/*
  *  transmit
  */
 
@@ -591,7 +591,7 @@
         lp -> hub_status = hp100_login_to_vg_hub( dev );
       hp100_start_interface( dev );
     }
-  
+
   if ( ( i = ( hp100_inl( TX_MEM_FREE ) & ~0x7fffffff ) ) < skb -> len + 16 )
     {
 #ifdef HP100_DEBUG
@@ -635,20 +635,20 @@
       dev -> trans_start = jiffies;
       return -EAGAIN;
     }
-    
+
   if ( skb == NULL )
     {
       dev_tint( dev );
       return 0;
     }
-    
+
   if ( skb -> len <= 0 ) return 0;
 
   for ( i = 0; i < 6000 && ( hp100_inw( OPTION_MSW ) & HP100_TX_CMD ); i++ )
     {
 #ifdef HP100_DEBUG_TX
       printk( "hp100_start_xmit: busy\n" );
-#endif    
+#endif
     }
 
   hp100_ints_off();
@@ -717,7 +717,7 @@
       hp100_page( PERFORMANCE );
     }
 #endif
-  
+
   packets = hp100_inb( RX_PKT_CNT );
 #ifdef HP100_DEBUG
   if ( packets > 1 )
@@ -729,7 +729,7 @@
         {
 #ifdef HP100_DEBUG_TX
           printk( "hp100_rx: busy, remaining packets = %d\n", packets );
-#endif    
+#endif
         }
       if ( lp -> mem_mapped )
         {
@@ -761,7 +761,7 @@
        else
         {
           u_char *ptr;
-        
+
           skb -> dev = dev;
           ptr = (u_char *)skb_put( skb, pkt_len );
           if ( lp -> mem_mapped )
@@ -797,7 +797,7 @@
 /*
  *  statistics
  */
- 
+
 static struct enet_statistics *hp100_get_stats( struct device *dev )
 {
   int ioaddr = dev -> base_addr;
@@ -813,7 +813,7 @@
   int ioaddr = dev -> base_addr;
   u_short val;
   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
-         
+
   hp100_page( MAC_CTRL );		/* get all statistics bytes */
   val = hp100_inw( DROPPED ) & 0x0fff;
   lp -> stats.rx_errors += val;
@@ -845,7 +845,7 @@
 /*
  *  Set or clear the multicast filter for this adapter.
  */
-                                                          
+
 static void hp100_set_multicast_list( struct device *dev)
 {
   int ioaddr = dev -> base_addr;
@@ -956,14 +956,14 @@
       hp100_outw( HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW );
     }
   sti();
-} 
+}
 
 static void hp100_stop_interface( struct device *dev )
 {
   int ioaddr = dev -> base_addr;
   u_short val;
 
-  hp100_outw( HP100_INT_EN | HP100_RESET_LB | 
+  hp100_outw( HP100_INT_EN | HP100_RESET_LB |
               HP100_TRI_INT | HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW );
   val = hp100_inw( OPTION_LSW );
   hp100_page( HW_MAP );
@@ -1030,10 +1030,10 @@
   if ( i <= 0 )				/* not signal - not logout */
     return 0;
   hp100_andw( ~HP100_LINK_CMD, LAN_CFG_VG );
-  time = jiffies + 10*HZ/100; 
+  time = jiffies + 10*HZ/100;
   while ( time > jiffies )
-    if ( !( hp100_inw( LAN_CFG_VG ) & ( HP100_LINK_UP_ST | 
-                                        HP100_LINK_CABLE_ST | 
+    if ( !( hp100_inw( LAN_CFG_VG ) & ( HP100_LINK_UP_ST |
+                                        HP100_LINK_CABLE_ST |
                                         HP100_LINK_GOOD_ST ) ) )
       return 0;
 #ifdef HP100_DEBUG
@@ -1047,7 +1047,7 @@
   int i;
   int ioaddr = dev -> base_addr;
   u_short val;
-  unsigned long time;  
+  unsigned long time;
 
   hp100_page( MAC_CTRL );
   hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
@@ -1062,7 +1062,7 @@
 #endif
       return -EIO;
     }
-    
+
   if ( hp100_down_vg_link( dev ) < 0 )	/* if fail, try reset VG link */
     {
       hp100_andw( ~HP100_VG_RESET, LAN_CFG_VG );
@@ -1081,9 +1081,9 @@
     }
 
   time = jiffies + ( HZ / 2 );
-  do {   
+  do {
     val = hp100_inw( LAN_CFG_VG );
-    if ( ( val & ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) ) == 
+    if ( ( val & ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) ) ==
                  ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) )
       return 0;	/* success */
   } while ( time > jiffies );
@@ -1103,10 +1103,11 @@
 /*
  *  module section
  */
- 
+
 #ifdef MODULE
 
 static int hp100_port = -1;
+MODULE_PARM(hp100_port, "i");
 
 static char devicename[9] = { 0, };
 static struct device dev_hp100 = {
@@ -1125,7 +1126,7 @@
   if ( register_netdev( &dev_hp100 ) != 0 )
     return -EIO;
   return 0;
-}         
+}
 
 void cleanup_module( void )
 {
diff -u --recursive --new-file v2.1.18/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
--- v2.1.18/linux/drivers/net/ibmtr.c	Sun Dec 22 16:37:33 1996
+++ linux/drivers/net/ibmtr.c	Tue Dec 31 10:30:01 1996
@@ -13,7 +13,7 @@
 
 /*
    Changes by Peter De Schrijver (Peter.Deschrijver@linux.cc.kuleuven.ac.be) :
-	
+
 	+ changed name to ibmtr.c in anticipation of other tr boards.
 	+ changed reset code and adapter open code.
 	+ added SAP open code.
@@ -34,10 +34,10 @@
         - removed redundant information display
         - some code reworking
 
-   Changes by Michel Lespinasse (walken@via.ecp.fr), 
+   Changes by Michel Lespinasse (walken@via.ecp.fr),
      Yann Doussot (doussot@via.ecp.fr) and Pascal Andre (andre@via.ecp.fr)
      (February 18, 1996) :
-	- modified shared memory and mmio access port the driver to 
+	- modified shared memory and mmio access port the driver to
           alpha platform (structure access -> readb/writeb)
 
    Changes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com)
@@ -56,7 +56,7 @@
 	  complete. (August 15 1996)
         - completed multiple adapter support. (November 20 1996)
 */
-	
+
 #ifdef PCMCIA
 #define MODULE
 #endif
@@ -85,10 +85,10 @@
 #define USE_MEMCPY 1
 
 /* version and credits */
-static char *version = 
+static char *version =
 "ibmtr.c: v1.3.57  8/ 7/94 Peter De Schrijver and Mark Swanson\n"
 "         v2.1.10 11/20/96 Paul Norton <pnorton@cts.com>\n";
- 
+
 static char pcchannelid[]={0x05, 0x00, 0x04, 0x09,
 			   0x04, 0x03, 0x04, 0x0f,
 			   0x03, 0x06, 0x03, 0x01,
@@ -184,13 +184,13 @@
 /*  This routine combined with the #DEFINE DPRINTD serves
     to workaround the gcc apparent bug.   in tr_tx() */
 
-static void DummyCall(const char * fmt,...) 
+static void DummyCall(const char * fmt,...)
 { DummyCallCount++; return; }
 #endif
 
 static void PrtChanID(char *pcid, short stride) {
 	short i, j;
-	for (i=0, j=0; i<24; i++, j+=stride) 
+	for (i=0, j=0; i<24; i++, j+=stride)
 		printk("%1x", ((int) pcid[j]) & 0x0f);
 	printk("\n");
 }
@@ -255,19 +255,19 @@
 	__u32 cd_chanid;
 	unsigned char *tchanid, ctemp;
 
-#ifndef MODULE 		
+#ifndef MODULE
 	dev = init_trdev(dev,0);
 #endif
 
 	/* Query the adapter PIO base port which will return
-	indication of where MMIO was placed. We also have a 
+	indication of where MMIO was placed. We also have a
 	coded interrupt number. */
-		
+
        	segment = inb(PIOaddr);
 	/* out of range values so we'll assume non-existent IO device */
 	if (segment < 0x40 || segment > 0xe0)
-                return -ENODEV; 
-		
+                return -ENODEV;
+
 	/* Compute the linear base address of the MMIO area
 	   as LINUX doesn't care about segments          */
 	t_mmio=(((__u32)(segment & 0xfc) << 11) + 0x80000);
@@ -275,22 +275,22 @@
 	if (ibmtr_debug_trace & TRC_INIT)
 		DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %08X intr: %d\n",
                          PIOaddr, (int)segment, t_mmio, (int)intr);
-		
+
 	/* Now we will compare expected 'channelid' strings with
 	   what we is there to learn of ISA/MCA or not TR card */
 	cd_chanid = (CHANNEL_ID + t_mmio);  /* for efficiency */
-	tchanid=pcchannelid; 
+	tchanid=pcchannelid;
 	cardpresent=TR_ISA;  /* try ISA */
 
 	/* suboptimize knowing first byte different */
 	ctemp = readb(cd_chanid) & 0x0f;
 	if (ctemp != *tchanid) { /* NOT ISA card, try MCA */
-		tchanid=mcchannelid; 
+		tchanid=mcchannelid;
 		cardpresent=TR_MCA;
 		if (ctemp != *tchanid)  /* Neither ISA nor MCA */
 			cardpresent=NOTOK;
 	}
-		
+
 	if (cardpresent != NOTOK) { /* know presumed type, try rest of ID */
 		for (i=2,j=1; i<=46; i=i+2,j++) {
 			if ((readb(cd_chanid+i) & 0x0f) != tchanid[j]) {
@@ -299,12 +299,12 @@
 			}
 		}
 	}
-		
+
 	/* If we have an ISA board check for the ISA P&P version,
 	   as it has different IRQ settings */
 	if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio)==0x0e))
 	        cardpresent=TR_ISAPNP;
-		
+
 	if (cardpresent == NOTOK) { /* "channel_id" did not match, report */
 		if (ibmtr_debug_trace & TRC_INIT) {
 			DPRINTK("Channel ID string not found for PIOaddr: %4hx\n", PIOaddr);
@@ -314,11 +314,11 @@
 		}
                 return -ENODEV;
 	}
-		
+
 	/* Now, allocate some of the pl0 buffers for this driver.. */
 	ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
 	if (ti == NULL) return -ENOMEM;
-		
+
 	memset(ti, 0, sizeof(struct tok_info));
 
 	ti->mmio= t_mmio;
@@ -362,7 +362,7 @@
 		ti->global_int_enable=PIOaddr+ADAPTINTREL;
 		ti->adapter_int_enable=PIOaddr+ADAPTINTREL;
 		break;
-      
+
 	}
 
 	if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
@@ -375,7 +375,7 @@
 	}
 
 	/* Get hw address of token ring card */
-#if !TR_NEWFORMAT 
+#if !TR_NEWFORMAT
 	DPRINTK("hw address: ");
 #endif
 	j=0;
@@ -420,7 +420,7 @@
 #if !TR_NEWFORMAT
 	DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, "
 		"dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type,
-		ti->data_rate, ti->token_release, ti->avail_shared_ram/2, 
+		ti->data_rate, ti->token_release, ti->avail_shared_ram/2,
 		ti->shared_ram_paging, ti->dhb_size4mb, ti->dhb_size16mb);
 #endif
 
@@ -430,7 +430,7 @@
 	   maximum space will will use for two adapters is 64K so if the
 	   adapter we are working on demands 64K (it also doesn't support
 	   paging), then only one adapter can be supported.  */
-	
+
 	/* determine how much of total RAM is mapped into PC space */
 	ti->mapped_ram_size=1<<((((readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)) >>2) & 0x03) + 4);
 	ti->page_mask=0;
@@ -479,7 +479,7 @@
 				pg_size, ti->mapped_ram_size);
 				ti->page_mask = 0;    /* reset paging */
 		} else {
-			ti->mapped_ram_size=ti->avail_shared_ram; 
+			ti->mapped_ram_size=ti->avail_shared_ram;
 			DPRINTK("Shared RAM paging enabled. Page size : %uK\n",
 				((ti->page_mask^ 0xff)+1)>>2);
 		}
@@ -543,7 +543,7 @@
 
 	trdev_init(dev);
 	tok_init_card(dev);
-	
+
 	return 0;  /* Return 0 to indicate we have found a Token Ring card. */
 }
 
@@ -551,10 +551,10 @@
 
 unsigned char get_sram_size(struct tok_info *adapt_info)
 {
-		
+
 	unsigned char avail_sram_code;
 	static unsigned char size_code[]={ 0,16,32,64,127,128 };
-	
+
 	/* Adapter gives
 	   'F' -- use RRR bits 3,2
 	   'E' -- 8kb   'D' -- 16kb
@@ -563,7 +563,7 @@
 	   (WARNING ... must zero top bytes in INIT */
 
 	avail_sram_code=0xf-readb(adapt_info->mmio + AIPAVAILSHRAM);
-	if (avail_sram_code) 
+	if (avail_sram_code)
 		return size_code[avail_sram_code];
 	else  /* for code 'F', must compute size from RRR(3,2) bits */
 		return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4);
@@ -585,7 +585,7 @@
 
 #ifndef MODULE
   tr_setup(dev);
-#endif 
+#endif
 
 
   return 0;
@@ -593,48 +593,48 @@
 
 
 
-static int tok_open(struct device *dev) 
+static int tok_open(struct device *dev)
 {
 	struct tok_info *ti=(struct tok_info *)dev->priv;
-	
+
 	if (ti->open_status==CLOSED) tok_init_card(dev);
-	
+
 	if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);
-	
+
 	if (ti->open_status==SUCCESS) {
 		dev->tbusy=0;
 		dev->interrupt=0;
 		dev->start=1;
 		/* NEED to see smem size *AND* reset high 512 bytes if needed */
-		
+
 		MOD_INC_USE_COUNT;
-		
+
 		return 0;
 	} else return -EAGAIN;
-	
+
 }
 
-static int tok_close(struct device *dev) 
+static int tok_close(struct device *dev)
 {
-	
+
 	struct tok_info *ti=(struct tok_info *) dev->priv;
-	
-	writeb(DIR_CLOSE_ADAPTER, 
+
+	writeb(DIR_CLOSE_ADAPTER,
 	       ti->srb + offsetof(struct srb_close_adapter, command));
 	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-	
+
 	ti->open_status=CLOSED;
-	
-	sleep_on(&ti->wait_for_tok_int);		
-	
+
+	sleep_on(&ti->wait_for_tok_int);
+
 	if (readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)))
 		DPRINTK("close adapter failed: %02X\n",
 			(int)readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)));
-		
+
         dev->start = 0;
 	DPRINTK("Adapter closed.\n");
 	MOD_DEC_USE_COUNT;
-	
+
 	return 0;
 }
 
@@ -643,13 +643,13 @@
 	unsigned char status;
 	struct tok_info *ti;
 	struct device *dev;
-	
+
 #if TR_VERBOSE
 	DPRINTK("Int from tok_driver, dev : %p\n",dev);
 #endif
 	dev = (struct device *)(irq2dev_map[irq]);
 	ti  = (struct tok_info *) dev->priv;
-	
+
       	/* Disable interrupts till processing is finished */
 	dev->interrupt=1;
 	writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
@@ -659,16 +659,16 @@
                 outb(0,ti->adapter_int_enable);
 	else
 		outb(0,ti->global_int_enable);
-		
+
 
 	switch (ti->do_tok_int) {
-		
+
 	      case NOT_FIRST:
-		
+
 		/*  Begin the regular interrupt handler HERE inline to avoid
 		    the extra levels of logic and call depth for the
 		    original solution.   */
-		
+
 		status=readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
 		#ifdef PCMCIA
       		/* Check if the PCMCIA card was pulled. */
@@ -688,48 +688,48 @@
       		 }
 		#endif
 
-		
+
 		if (status & ADAP_CHK_INT) {
-			
+
 			int i;
 			__u32 check_reason;
 
 			check_reason=ti->mmio + ntohs(readw(ti->sram + ACA_OFFSET + ACA_RW +WWCR_EVEN));
-			
+
 			DPRINTK("Adapter check interrupt\n");
 			DPRINTK("8 reason bytes follow: ");
 			for(i=0; i<8; i++, check_reason++)
-				printk("%02X ", (int)readb(check_reason));	
+				printk("%02X ", (int)readb(check_reason));
 			printk("\n");
-			
+
 			writeb((~ADAP_CHK_INT), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 			writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);
 			dev->interrupt=0;
-			
+
 		}	else if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)
 				 & (TCR_INT | ERR_INT | ACCESS_INT)) {
-			
-			DPRINTK("adapter error: ISRP_EVEN : %02x\n", 
+
+			DPRINTK("adapter error: ISRP_EVEN : %02x\n",
 				(int)readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));
 			writeb(~(TCR_INT | ERR_INT | ACCESS_INT),
 			       ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
 			writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);
 			dev->interrupt=0;
 
-		} else if (status 
+		} else if (status
 			   & (SRB_RESP_INT | ASB_FREE_INT | ARB_CMD_INT | SSB_RESP_INT)) {
 			/* SRB, ASB, ARB or SSB response */
-			
+
 			if (status & SRB_RESP_INT) { /* SRB response */
-				
+
 				switch(readb(ti->srb)) { /* SRB command check */
-					
+
 				      case XMIT_DIR_FRAME: {
 					      unsigned char xmit_ret_code;
-					      
+
 					      xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));
 					      if (xmit_ret_code != 0xff) {
-						      DPRINTK("error on xmit_dir_frame request: %02X\n", 
+						      DPRINTK("error on xmit_dir_frame request: %02X\n",
 							      xmit_ret_code);
 						      if (ti->current_skb) {
 							      dev_kfree_skb(ti->current_skb, FREE_WRITE);
@@ -740,10 +740,10 @@
 					      }
 				      }
 				      break;
-				      
+
 				      case XMIT_UI_FRAME: {
 					      unsigned char xmit_ret_code;
-					      
+
 					      xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));
 					      if (xmit_ret_code != 0xff) {
 						      DPRINTK("error on xmit_ui_frame request: %02X\n",
@@ -757,22 +757,22 @@
 					      }
 				      }
 				      break;
-				      
+
 				      case DIR_OPEN_ADAPTER: {
 					      unsigned char open_ret_code;
 					      __u16 open_error_code;
-					      
+
 					      ti->srb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr)));
 					      ti->ssb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr)));
 					      ti->arb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr)));
 					      ti->asb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr)));
 					      ti->current_skb=NULL;
-					      
+
 					      open_ret_code = readb(ti->init_srb +offsetof(struct srb_open_response, ret_code));
 					      open_error_code = ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, error_code)));
 
 					      if (open_ret_code==7) {
-						      
+
 						      if (!ti->auto_ringspeedsave && (open_error_code==0x24)) {
 							      DPRINTK("open failed: Adapter speed must match ring "
 								      "speed if Automatic Ring Speed Save is disabled\n");
@@ -782,41 +782,41 @@
 							      DPRINTK("retrying open to adjust to ring speed\n");
 						      else if ((open_error_code==0x2d) && ti->auto_ringspeedsave)
 							      DPRINTK("No signal detected for Auto Speed Detection\n");
-						      else DPRINTK("Unrecoverable error: error code = %04x\n", 
+						      else DPRINTK("Unrecoverable error: error code = %04x\n",
 								   open_error_code);
-						      
+
 					      } else if (!open_ret_code) {
 #if !TR_NEWFORMAT
 						      DPRINTK("board opened...\n");
 #else
 						      DPRINTK("Adapter initialized and opened.\n");
 #endif
-						      writeb(~(SRB_RESP_INT), 
+						      writeb(~(SRB_RESP_INT),
 							     ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-						      writeb(~(CMD_IN_SRB), 
+						      writeb(~(CMD_IN_SRB),
 							     ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
 						      open_sap(EXTENDED_SAP,dev);
-						      
+
 						      /* YdW probably hates me */
 						      goto skip_reset;
 					      } else
 						      DPRINTK("open failed: ret_code = %02X, retrying\n",
 							      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);
 					      }
-					      
+
 				      }
 				      break;
-				      
+
 				      case DIR_CLOSE_ADAPTER:
 					wake_up(&ti->wait_for_tok_int);
 					break;
-					
+
 				      case DLC_OPEN_SAP:
 					if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) {
 						DPRINTK("open_sap failed: ret_code = %02X,retrying\n",
@@ -832,9 +832,9 @@
 						wake_up(&ti->wait_for_reset);
 					}
 					break;
-					
+
 				      case DIR_INTERRUPT:
-				      case DIR_MOD_OPEN_PARAMS:	
+				      case DIR_MOD_OPEN_PARAMS:
 				      case DIR_SET_GRP_ADDR:
 				      case DIR_SET_FUNC_ADDR:
 				      case DLC_CLOSE_SAP:
@@ -843,7 +843,7 @@
 							(int)readb(ti->srb+offsetof(struct srb_interrupt, command)),
 							(int)readb(ti->srb+offsetof(struct srb_interrupt, ret_code)));
 					break;
-					
+
 				      case DIR_READ_LOG:
 					if (readb(ti->srb+offsetof(struct srb_read_log, ret_code)))
 						DPRINTK("error on dir_read_log: %02X\n",
@@ -854,96 +854,96 @@
 							"A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n"
 							"Receive congestion count %02X, Frame copied errors %02X\n"
 							"Frequency errors %02X, Token errors %02X\n",
-							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+							(int)readb(ti->srb+offsetof(struct srb_read_log,
 										    line_errors)),
-							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+							(int)readb(ti->srb+offsetof(struct srb_read_log,
 										    internal_errors)),
-							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+							(int)readb(ti->srb+offsetof(struct srb_read_log,
 										    burst_errors)),
 							(int)readb(ti->srb+offsetof(struct srb_read_log, A_C_errors)),
-							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+							(int)readb(ti->srb+offsetof(struct srb_read_log,
 										    abort_delimiters)),
-							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+							(int)readb(ti->srb+offsetof(struct srb_read_log,
 										    lost_frames)),
-							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+							(int)readb(ti->srb+offsetof(struct srb_read_log,
 												    recv_congest_count)),
-							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+							(int)readb(ti->srb+offsetof(struct srb_read_log,
 										    frame_copied_errors)),
-							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+							(int)readb(ti->srb+offsetof(struct srb_read_log,
 										    frequency_errors)),
-							(int)readb(ti->srb+offsetof(struct srb_read_log, 
+							(int)readb(ti->srb+offsetof(struct srb_read_log,
 												    token_errors)));
 					dev->tbusy=0;
 					break;
-					
+
 				      default:
 					DPRINTK("Unknown command %02X encountered\n",
 						(int)readb(ti->srb));
-					
+
 				} /* SRB command check */
-				
+
 				writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
 				writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-				
+
 			  skip_reset:
 			} /* SRB response */
-			
+
 			if (status & ASB_FREE_INT) { /* ASB response */
-				
+
 				switch(readb(ti->asb)) { /* ASB command check */
-					
+
 				      case REC_DATA:
 				      case XMIT_UI_FRAME:
 				      case XMIT_DIR_FRAME:
 					break;
-					
+
 				      default:
 					DPRINTK("unknown command in asb %02X\n",
 						(int)readb(ti->asb));
-					
+
 				} /* ASB command check */
-				
+
 				if (readb(ti->asb+2)!=0xff) /* checks ret_code */
-				    DPRINTK("ASB error %02X in cmd %02X\n", 
+				    DPRINTK("ASB error %02X in cmd %02X\n",
 					    (int)readb(ti->asb+2),(int)readb(ti->asb));
 				writeb(~ASB_FREE_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-				
+
 			} /* ASB response */
-			
+
 			if (status & ARB_CMD_INT) { /* ARB response */
-				
+
 				switch (readb(ti->arb)) { /* ARB command check */
-					
+
 				      case DLC_STATUS:
-					DPRINTK("DLC_STATUS new status: %02X on station %02X\n", 
+					DPRINTK("DLC_STATUS new status: %02X on station %02X\n",
 						ntohs(readw(ti->arb + offsetof(struct arb_dlc_status, status))),
-						ntohs(readw(ti->arb 
+						ntohs(readw(ti->arb
 									    +offsetof(struct arb_dlc_status, station_id))));
 					break;
-					
+
 				      case REC_DATA:
 					tr_rx(dev);
 					break;
-					
+
 				      case RING_STAT_CHANGE: {
 					      unsigned short ring_status;
-					      
+
 					      ring_status=ntohs(readw(ti->arb
 								      +offsetof(struct arb_ring_stat_change, ring_status)));
-					      
+
 					      if (ring_status & (SIGNAL_LOSS | LOBE_FAULT)) {
-						      
+
 						      DPRINTK("Signal loss/Lobe fault\n");
-						      DPRINTK("We try to reopen the adapter.\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);
-						      
-					      } else if (ring_status & (HARD_ERROR | XMIT_BEACON 
+
+					      } else if (ring_status & (HARD_ERROR | XMIT_BEACON
 											| AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER))
 						      DPRINTK("New ring status: %02X\n", ring_status);
-					      
+
 					      if (ring_status & LOG_OVERFLOW) {
 						      if (dev->tbusy)
                                                               ti->readlog_pending = 1;
@@ -952,50 +952,50 @@
 					      }
 				      }
 				      break;
-				      
+
 				      case XMIT_DATA_REQ:
 					tr_tx(dev);
 					break;
-					
+
 				      default:
-					DPRINTK("Unknown command %02X in arb\n", 
+					DPRINTK("Unknown command %02X in arb\n",
 						(int)readb(ti->arb));
 					break;
-					
+
 				} /* ARB command check */
-				
+
 				writeb(~ARB_CMD_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 				writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-				
+
 			} /* ARB response */
-			
+
 			if (status & SSB_RESP_INT) { /* SSB response */
-						
+
 				switch (readb(ti->ssb)) { /* SSB command check */
-					
+
 				      case XMIT_DIR_FRAME:
 				      case XMIT_UI_FRAME:
 					if (readb(ti->ssb+2)) /* checks ret_code */
-						DPRINTK("xmit ret_code: %02X xmit error code: %02X\n", 
-							(int)readb(ti->ssb+2), (int)readb(ti->ssb+6));		
+						DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",
+							(int)readb(ti->ssb+2), (int)readb(ti->ssb+6));
 					else ti->tr_stats.tx_packets++;
 					break;
-					
+
 				      case XMIT_XID_CMD:
 					DPRINTK("xmit xid ret_code: %02X\n", (int)readb(ti->ssb+2));
-					
+
 				      default:
 					DPRINTK("Unknown command %02X in ssb\n", (int)readb(ti->ssb));
-					
+
 				} /* SSB command check */
-				
+
 				writeb(~SSB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 				writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-				
+
 			} /* SSB response */
-			
+
 		}	 /* SRB, ARB, ASB or SSB response */
-		
+
 		dev->interrupt=0;
 		writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
 		break;
@@ -1003,24 +1003,24 @@
 	      case FIRST_INT:
 		initial_tok_int(dev);
 		break;
-		
+
 	      default:
 		DPRINTK("Unexpected interrupt from tr adapter\n");
 
 	}
 }
 
-static void initial_tok_int(struct device *dev) 
+static void initial_tok_int(struct device *dev)
 {
 
 	__u32 encoded_addr;
 	__u32 hw_encoded_addr;
 	struct tok_info *ti;
-	
+
 	ti=(struct tok_info *) dev->priv;
-	
+
 	ti->do_tok_int=NOT_FIRST;
-	
+
 #ifndef TR_NEWFORMAT
 	DPRINTK("Initial tok int received\n");
 #endif
@@ -1036,7 +1036,7 @@
 
 	dev->mem_start = ti->sram;
 	dev->mem_end = ti->sram + (ti->mapped_ram_size<<9) - 1;
-	
+
 #if TR_VERBOSE
 	{
 		int i;
@@ -1045,28 +1045,28 @@
 		printk("\n");
 	}
 #endif
-	
-	hw_encoded_addr = readw(ti->init_srb 
+
+	hw_encoded_addr = readw(ti->init_srb
 				+ offsetof(struct srb_init_response, encoded_address));
-	
-#if !TR_NEWFORMAT		
+
+#if !TR_NEWFORMAT
 	DPRINTK("srb_init_response->encoded_address: %04X\n", hw_encoded_addr);
 	DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",
 		ntohs(hw_encoded_addr));
 #endif
-	
+
 	encoded_addr=(ti->sram + ntohs(hw_encoded_addr));
-	
+
 #if !TR_NEWFORMAT
-	DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr, 
+	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);
-#endif	
-	
+#endif
+
 	ti->auto_ringspeedsave=readb(ti->init_srb
 				     +offsetof(struct srb_init_response, init_status_2)) & 0x4 ? TRUE : FALSE;
-	
+
 #if !TR_NEWFORMAT
 	for(i=0;i<TR_ALEN;i++) {
 		dev->dev_addr[i]=readb(encoded_addr + i);
@@ -1074,114 +1074,114 @@
 	}
 	printk("\n");
 #endif
-	
+
 	tok_open_adapter((unsigned long)dev);
 }
 
-static int tok_init_card(struct device *dev) 
+static int tok_init_card(struct device *dev)
 {
 	struct tok_info *ti;
 	short PIOaddr;
 	int i;
 	PIOaddr = dev->base_addr;
 	ti=(struct tok_info *) dev->priv;
-	
+
 	/* Special processing for first interrupt after reset */
 	ti->do_tok_int=FIRST_INT;
-	
+
 	/* Reset adapter */
 	dev->tbusy=1; /* nothing can be done before reset and open completed */
-	
+
 #ifdef ENABLE_PAGING
 	if(ti->page_mask)
 		writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
 #endif
-	
+
 	writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
-	
+
 #if !TR_NEWFORMAT
 	DPRINTK("resetting card\n");
 #endif
-	
+
 	outb(0, PIOaddr+ADAPTRESET);
 	for (i=jiffies+TR_RESET_INTERVAL; jiffies<=i;); /* wait 50ms */
 	outb(0,PIOaddr+ADAPTRESETREL);
-	
+
 #if !TR_NEWFORMAT
 	DPRINTK("card reset\n");
 #endif
-	
+
 	ti->open_status=IN_PROGRESS;
 	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
-	return 0;	
+	return 0;
 }
 
-static void open_sap(unsigned char type,struct device *dev) 
+static void open_sap(unsigned char type,struct device *dev)
 {
 	int i;
 	struct tok_info *ti=(struct tok_info *) dev->priv;
-	
+
 	SET_PAGE(ti->srb);
 	for (i=0; i<sizeof(struct dlc_open_sap); i++)
 		writeb(0, ti->srb+i);
-	
+
 	writeb(DLC_OPEN_SAP, ti->srb + offsetof(struct dlc_open_sap, command));
-	writew(htons(MAX_I_FIELD), 
+	writew(htons(MAX_I_FIELD),
 	       ti->srb + offsetof(struct dlc_open_sap, max_i_field));
-	writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, 
+	writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY,
 	       ti->srb + offsetof(struct dlc_open_sap, sap_options));
-	writeb(SAP_OPEN_STATION_CNT, 
+	writeb(SAP_OPEN_STATION_CNT,
 	       ti->srb + offsetof(struct dlc_open_sap, station_count));
 	writeb(type, ti->srb + offsetof(struct dlc_open_sap, sap_value));
-	
+
 	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 
 }
 
-void tok_open_adapter(unsigned long dev_addr) 
+void tok_open_adapter(unsigned long dev_addr)
 {
-	
+
 	struct device *dev=(struct device *)dev_addr;
 	struct tok_info *ti;
 	int i;
-	
+
 	ti=(struct tok_info *) dev->priv;
-	
+
 #if !TR_NEWFORMAT
 	DPRINTK("now opening the board...\n");
 #endif
-	
+
 	writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 	writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
-	
+
 	for (i=0; i<sizeof(struct dir_open_adapter); i++)
 		writeb(0, ti->init_srb+i);
-	
-	writeb(DIR_OPEN_ADAPTER, 
+
+	writeb(DIR_OPEN_ADAPTER,
 	       ti->init_srb + offsetof(struct dir_open_adapter, command));
-	writew(htons(OPEN_PASS_BCON_MAC), 
+	writew(htons(OPEN_PASS_BCON_MAC),
 	       ti->init_srb + offsetof(struct dir_open_adapter, open_options));
-	writew(htons(NUM_RCV_BUF), 
+	writew(htons(NUM_RCV_BUF),
 	       ti->init_srb + offsetof(struct dir_open_adapter, num_rcv_buf));
-	writew(htons(RCV_BUF_LEN), 
+	writew(htons(RCV_BUF_LEN),
 	       ti->init_srb + offsetof(struct dir_open_adapter, rcv_buf_len));
-	writew(htons(DHB_LENGTH), 
+	writew(htons(DHB_LENGTH),
 	       ti->init_srb + offsetof(struct dir_open_adapter, dhb_length));
-	writeb(NUM_DHB, 
+	writeb(NUM_DHB,
 	       ti->init_srb + offsetof(struct dir_open_adapter, num_dhb));
-	writeb(DLC_MAX_SAP, 
+	writeb(DLC_MAX_SAP,
 	       ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sap));
-	writeb(DLC_MAX_STA, 
+	writeb(DLC_MAX_STA,
 	       ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sta));
-	
+
 	ti->srb=ti->init_srb; /* We use this one in the interrupt handler */
-	
+
 	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
 	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-	
+
 }
 
-static void tr_tx(struct device *dev) 
+static void tr_tx(struct device *dev)
 {
 	struct tok_info *ti=(struct tok_info *) dev->priv;
 	struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data;
@@ -1190,21 +1190,21 @@
 	unsigned char xmit_command;
 	int i;
 	struct trllc	*llc;
-	
+
 	if (readb(ti->asb + offsetof(struct asb_xmit_resp, ret_code))!=0xFF)
 		DPRINTK("ASB not free !!!\n");
-	
+
 	/* in providing the transmit interrupts,
 	   is telling us it is ready for data and
 	   providing a shared memory address for us
 	   to stuff with data.  Here we compute the
 	   effective address where we will place data.*/
-	dhb=ti->sram 
+	dhb=ti->sram
 		+ntohs(readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address)));
 	llc = (struct trllc *) &(ti->current_skb->data[sizeof(struct trh_hdr)]);
-	
+
 	xmit_command = readb(ti->srb + offsetof(struct srb_xmit, command));
-	
+
 	writeb(xmit_command, ti->asb + offsetof(struct asb_xmit_resp, command));
 	writew(readb(ti->srb + offsetof(struct srb_xmit, station_id)),
 	       ti->asb + offsetof(struct asb_xmit_resp, station_id));
@@ -1212,23 +1212,23 @@
 	writeb(readb(ti->srb + offsetof(struct srb_xmit, cmd_corr)),
 	       ti->asb + offsetof(struct asb_xmit_resp, cmd_corr));
 	writeb(0, ti->asb + offsetof(struct asb_xmit_resp, ret_code));
-	
+
 	if ((xmit_command==XMIT_XID_CMD) || (xmit_command==XMIT_TEST_CMD)) {
-		
-		writew(htons(0x11), 
+
+		writew(htons(0x11),
 		       ti->asb + offsetof(struct asb_xmit_resp, frame_length));
 		writeb(0x0e, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
 		writeb(AC, dhb);
 		writeb(LLC_FRAME, dhb+1);
-		
+
 		for (i=0; i<TR_ALEN; i++) writeb((int)0x0FF, dhb+i+2);
 		for (i=0; i<TR_ALEN; i++) writeb(0, dhb+i+TR_ALEN+2);
-		
+
 		writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 		return;
-		
+
 	}
-	
+
 	/* the token ring packet is copied from sk_buff to the adapter
 	   buffer identified in the command data received with the
 	   interrupt.  The sk_buff area was set up with a maximum
@@ -1236,20 +1236,20 @@
 	   out the extra (all) rif fields.   */
 	/* nb/dwm .... I re-arranged code here to avoid copy of extra
 	   bytes, ended up with fewer statements as well. */
-	
+
 	/* TR arch. identifies if RIF present by high bit of source
 	   address.  So here we check if RIF present */
 
 	if (!(trhdr->saddr[0] & 0x80)) { /* RIF present : preserve it */
 		hdr_len=sizeof(struct trh_hdr)-18;
-		
+
 #if TR_VERBOSE
 		DPRINTK("hdr_length: %d, frame length: %ld\n", hdr_len,
 			ti->current_skb->len-18);
 #endif
 	} else hdr_len=((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK)>>8)
 		  +sizeof(struct trh_hdr)-18;
-	
+
 	/* header length including rif is computed above, now move the data
 	   and set fields appropriately. */
 #if USE_MEMCPY
@@ -1258,22 +1258,22 @@
 	for (i=0; i<hdr_len; i++)
 		writeb(*(unsigned char *)(ti->current_skb->data +i), dhb++);
 #endif
-	
+
 	writeb(hdr_len, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
 	writew(htons(ti->current_skb->len-sizeof(struct trh_hdr)+hdr_len),
 	       ti->asb + offsetof(struct asb_xmit_resp, frame_length));
-	
+
 	/*  now copy the actual packet data next to hdr */
 #if USE_MEMCPY
 	memcpy_toio(dhb + hdr_len,
-		    ti->current_skb->data + sizeof(struct trh_hdr), 
+		    ti->current_skb->data + sizeof(struct trh_hdr),
 		    ti->current_skb->len - sizeof(struct trh_hdr));
 #else
 	for (i=0; i<ti->current_skb->len-sizeof(struct trh_hdr); i++)
 		writeb(*(unsigned char *)(ti->current_skb->data +sizeof(struct trh_hdr)+i),
 		       dhb+i);
 #endif
-	
+
 	writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 	dev->tbusy=0;
 	dev_kfree_skb(ti->current_skb,FREE_WRITE);
@@ -1282,11 +1282,11 @@
 	if (ti->readlog_pending) tr_readlog(dev);
 }
 
-static void tr_rx(struct device *dev) 
+static void tr_rx(struct device *dev)
 {
 	int i;
 	struct tok_info *ti=(struct tok_info *) dev->priv;
-	__u32 rbuffer;	
+	__u32 rbuffer;
 	__u32 llc;
 	unsigned char *data;
 	unsigned int rbuffer_len, lan_hdr_len;
@@ -1294,29 +1294,29 @@
 	struct sk_buff *skb;
 	unsigned int skb_size = 0;
 	int	is8022 = 0;
-	
+
 	rbuffer=(ti->sram
 		 +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))));
-	
+
 	if(readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF)
 		DPRINTK("ASB not free !!!\n");
-	
-	writeb(REC_DATA, 
+
+	writeb(REC_DATA,
 	       ti->asb + offsetof(struct asb_rec, command));
 	writew(readw(ti->arb + offsetof(struct arb_rec_req, station_id)),
 	       ti->asb + offsetof(struct asb_rec, station_id));
 	writew(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr)),
 	       ti->asb + offsetof(struct asb_rec, rec_buf_addr));
-	
+
 	lan_hdr_len=readb(ti->arb + offsetof(struct arb_rec_req, lan_hdr_len));
-	
+
 	llc=(rbuffer+offsetof(struct rec_buf, data) + lan_hdr_len);
-	
+
 #if TR_VERBOSE
 	DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",
 		(unsigned int)offsetof(struct rec_buf,data), (unsigned int)lan_hdr_len);
 	DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %p\n", llc,
-		ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))), 
+		ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))),
 		ti->sram);
 	DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, "
 		"ethertype: %04X\n",
@@ -1327,9 +1327,9 @@
 		(int)readb(llc + offsetof(struct trllc, protid)+2),
 		(int)readw(llc + offsetof(struct trllc, ethertype)));
 #endif
-	
+
 	if (readb(llc + offsetof(struct trllc, llc))!=UI_CMD) {
-#if !TR_FILTERNONUI		
+#if !TR_FILTERNONUI
 		DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",
 			(int)readb(llc + offsetof(struct trllc, llc))
 #endif
@@ -1338,20 +1338,20 @@
 			writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 			return;
 			}
-		
+
 		if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
 		    (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
 			is8022 = 1;
 		}
-			
+
 #if TR_VERBOSE
 		if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
 		    (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
-			
+
 			__u32 trhhdr;
-			
+
 			trhhdr=(rbuffer+offsetof(struct rec_buf,data));
-			
+
 			DPRINTK("Probably non-IP frame received.\n");
 			DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X "
 				"daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
@@ -1371,34 +1371,34 @@
 				(int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+5));
 		}
 #endif
-		
+
 		arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len)));
 		skb_size = arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr);
 		if (is8022) {
 			skb_size += sizeof(struct trllc);
 		}
-		
+
 		if (!(skb=dev_alloc_skb(skb_size))) {
-			DPRINTK("out of memory. frame dropped.\n");	
+			DPRINTK("out of memory. frame dropped.\n");
 			ti->tr_stats.rx_dropped++;
 			writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
 			writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 			return;
 		}
-		
+
 		skb_put(skb, skb_size);
 		skb->dev=dev;
-		
+
 		data=skb->data;
 #if USE_MEMCPY
 		memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, data), lan_hdr_len);
 #else
-		for (i=0; i<lan_hdr_len; i++) 
+		for (i=0; i<lan_hdr_len; i++)
 			data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
-#endif		
+#endif
 		if (lan_hdr_len<sizeof(struct trh_hdr))
 			memset(data+lan_hdr_len, 0, sizeof(struct trh_hdr)-lan_hdr_len);
-		
+
 		data+=sizeof(struct trh_hdr);
 		rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)))
 			-lan_hdr_len;
@@ -1408,7 +1408,7 @@
 			local_llc->ethertype = htons(ETH_P_TR_802_2);
 			data += sizeof(struct trllc);
 		}
-		
+
 #if TR_VERBOSE
 		DPRINTK("rbuffer_len: %d, data: %p\n", rbuffer_len, data);
 #endif
@@ -1419,7 +1419,7 @@
 			data[i]=readb(rbuffer+ offsetof(struct rec_buf, data)+lan_hdr_len+i);
 #endif
 		data+=rbuffer_len;
-		
+
 		while (readw(rbuffer + offsetof(struct rec_buf, buf_ptr))) {
 			rbuffer=(ti->sram
 				 +ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_ptr)))-2);
@@ -1427,58 +1427,58 @@
 			for (i=0; i<rbuffer_len; i++)
 				data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
 			data+=rbuffer_len;
-			
+
 #if TR_VERBOSE
-			DPRINTK("buf_ptr: %d, data =%p\n", 
+			DPRINTK("buf_ptr: %d, data =%p\n",
 				ntohs((rbuffer + offsetof(struct rec_buf, buf_ptr))), data);
 #endif
-		} 
-		
+		}
+
 		writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
-		
+
 		writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-		
+
 		ti->tr_stats.rx_packets++;
-		
+
 		skb->protocol=tr_type_trans(skb,dev);
 		netif_rx(skb);
-		
+
 	}
 
-static int tok_send_packet(struct sk_buff *skb, struct device *dev) 
+static int tok_send_packet(struct sk_buff *skb, struct device *dev)
 {
 	struct tok_info *ti;
 	ti=(struct tok_info *) dev->priv;
-	
+
 	if (dev->tbusy) {
 		int ticks_waited;
-		
+
 		ticks_waited=jiffies - dev->trans_start;
 		if (ticks_waited<TR_BUSY_INTERVAL) return 1;
-		
+
 		DPRINTK("Arrg. Transmitter busy.\n");
 		dev->trans_start+=5; /* we fake the transmission start time... */
 		return 1;
 	}
-	
+
 	/* Donald does this, so we do too. */
 	if (skb==NULL) {
 		dev_tint(dev);
 		return 0;
 	}
-	
+
 	if (set_bit(0,(void *)&dev->tbusy)!=0)
 		DPRINTK("Transmitter access conflict\n");
 	else {
 		/* Save skb; we'll need it when the adapter asks for the data */
-		ti->current_skb=skb; 
+		ti->current_skb=skb;
 		writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
-		writew(ti->exsap_station_id, ti->srb 
+		writew(ti->exsap_station_id, ti->srb
 		       +offsetof(struct srb_xmit, station_id));
 		writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD));
 		dev->trans_start=jiffies;
 	}
-	
+
 	return 0;
 }
 
@@ -1513,6 +1513,10 @@
 static int irq[IBMTR_MAX_ADAPTERS] = {0,0};
 static int mem[IBMTR_MAX_ADAPTERS] = {0,0};
 
+MODULE_PARM(io, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
+
 int init_module(void)
 {
         int i;
@@ -1528,7 +1532,7 @@
 	        dev_ibmtr[i]->irq       = irq[i];
 		dev_ibmtr[i]->mem_start = mem[i];
 		dev_ibmtr[i]->init      = &ibmtr_probe;
-	
+
 	        if (register_trdev(dev_ibmtr[i]) != 0) {
 			kfree_s(dev_ibmtr[i], sizeof(struct dev));
 			dev_ibmtr[i] = NULL;
@@ -1553,7 +1557,7 @@
 			 free_irq(dev_ibmtr[i]->irq, NULL);
 			 irq2dev_map[dev_ibmtr[i]->irq] = NULL;
 			 release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT);
-			 kfree_s(dev_ibmtr[i]->priv, sizeof(struct tok_info)); 
+			 kfree_s(dev_ibmtr[i]->priv, sizeof(struct tok_info));
 			 kfree_s(dev_ibmtr[i], sizeof(struct dev));
 			 dev_ibmtr[i] = NULL;
                 }
diff -u --recursive --new-file v2.1.18/linux/drivers/net/mkiss.c linux/drivers/net/mkiss.c
--- v2.1.18/linux/drivers/net/mkiss.c	Mon Dec 30 15:39:09 1996
+++ linux/drivers/net/mkiss.c	Tue Dec 31 10:30:01 1996
@@ -75,6 +75,7 @@
 
 static ax25_ctrl_t **ax25_ctrls = NULL;
 int ax25_maxdev = AX25_MAXDEV;		/* Can be overridden with insmod! */
+MODULE_PARM(ax25_maxdev, "i");
 
 static struct tty_ldisc	ax_ldisc;
 static struct tty_driver mkiss_driver;
diff -u --recursive --new-file v2.1.18/linux/drivers/net/ne.c linux/drivers/net/ne.c
--- v2.1.18/linux/drivers/net/ne.c	Thu Dec 12 19:37:06 1996
+++ linux/drivers/net/ne.c	Tue Dec 31 10:30:01 1996
@@ -158,10 +158,10 @@
 {"ne", ne_probe1, NE_IO_EXTENT, netcard_portlist};
 #else
 
-/* 
- * Note that at boot, this probe only picks up one card at a time, even for 
- * multiple PCI ne2k cards. Use "ether=0,0,eth1" if you have a second PCI 
- * ne2k card.  This keeps things consistent regardless of the bus type of 
+/*
+ * Note that at boot, this probe only picks up one card at a time, even for
+ * multiple PCI ne2k cards. Use "ether=0,0,eth1" if you have a second PCI
+ * ne2k card.  This keeps things consistent regardless of the bus type of
  * the card.
  */
 
@@ -177,7 +177,7 @@
 
 #ifdef CONFIG_PCI
     /* Then look for any installed PCI clones */
-    if (pcibios_present() && (ne_probe_pci(dev) == 0)) 
+    if (pcibios_present() && (ne_probe_pci(dev) == 0))
 	return 0;
 #endif
 
@@ -205,7 +205,7 @@
 		unsigned char pci_bus, pci_device_fn;
 		unsigned int pci_ioaddr;
 		int pci_index;
-		
+
 		for (pci_index = 0; pci_index < 8; pci_index++) {
 			if (pcibios_find_device (pci_clone_list[i].vendor,
 					pci_clone_list[i].dev_id, pci_index,
@@ -281,7 +281,7 @@
     /* A user with a poor card that fails to ack the reset, or that
        does not have a valid 0x57,0x57 signature can still use this
        without having to recompile. Specifying an i/o address along
-       with an otherwise unused dev->mem_end value of "0xBAD" will 
+       with an otherwise unused dev->mem_end value of "0xBAD" will
        cause the driver to skip these parts of the probe. */
 
     bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad));
@@ -339,13 +339,13 @@
 
     /*	At this point, wordlength *only* tells us if the SA_prom is doubled
 	up or not because some broken PCI cards don't respect the byte-wide
-	request in program_seq above, and hence don't have doubled up values. 
+	request in program_seq above, and hence don't have doubled up values.
 	These broken cards would otherwise be detected as an ne1000.  */
 
     if (wordlength == 2)
 	for (i = 0; i < 16; i++)
 		SA_prom[i] = SA_prom[i+i];
-    
+
     if (pci_irq_line || ioaddr >= 0x400)
 	wordlength = 2;		/* Catch broken PCI cards mentioned above. */
 
@@ -419,7 +419,7 @@
 	printk(" failed to detect IRQ line.\n");
 	return EAGAIN;
     }
-    
+
     /* Snarf the interrupt now.  There's no point in waiting since we cannot
        share and the board will usually be enabled. */
     {
@@ -438,7 +438,7 @@
 	free_irq(dev->irq, NULL);
 	return -ENOMEM;
     }
- 
+
     request_region(ioaddr, NE_IO_EXTENT, name);
 
     for(i = 0; i < ETHER_ADDR_LEN; i++) {
@@ -732,6 +732,10 @@
 static int io[MAX_NE_CARDS] = { 0, };
 static int irq[MAX_NE_CARDS]  = { 0, };
 static int bad[MAX_NE_CARDS]  = { 0, };	/* 0xbad = bad sig or no reset ack */
+
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
 
 /* This is set up so that no ISA autoprobe takes place. We can't guarantee
 that the ne2k probe is the last 8390 based probe to take place (as it
diff -u --recursive --new-file v2.1.18/linux/drivers/net/ni52.c linux/drivers/net/ni52.c
--- v2.1.18/linux/drivers/net/ni52.c	Mon Dec 30 15:39:09 1996
+++ linux/drivers/net/ni52.c	Tue Dec 31 10:30:02 1996
@@ -1,9 +1,9 @@
-/* 
+/*
  * net-3-driver for the NI5210 card (i82586 Ethernet chip)
  *
  * This is an extension to the Linux operating system, and is covered by the
  * same Gnu Public License that covers that work.
- * 
+ *
  * Alphacode 0.82 (96/09/29) for Linux 2.0.0 (or later)
  * Copyrights (c) 1994,1995,1996 by M.Hipp (Michael.Hipp@student.uni-tuebingen.de)
  *    [feel free to mail ....]
@@ -15,11 +15,11 @@
  *       insmod ni52.o io=0x360 irq=9 memstart=0xd0000 memend=0xd4000
  *
  * CAN YOU PLEASE REPORT ME YOUR PERFORMANCE EXPERIENCES !!.
- * 
+ *
  * If you find a bug, please report me:
  *   The kernel panic output and any kmsg from the ni52 driver
- *   the ni5210-driver-version and the linux-kernel version 
- *   how many shared memory (memsize) on the netcard, 
+ *   the ni5210-driver-version and the linux-kernel version
+ *   how many shared memory (memsize) on the netcard,
  *   bootprom: yes/no, base_addr, mem_start
  *   maybe the ni5210-card revision and the i82586 version
  *
@@ -38,52 +38,52 @@
  *
  * Known Problems:
  *   The internal sysbus seems to be slow. So we often lose packets because of
- *   overruns while receiving from a fast remote host. 
+ *   overruns while receiving from a fast remote host.
  *   This can slow down TCP connections. Maybe the newer ni5210 cards are better.
  *   my experience is, that if a machine sends with more then about 500-600K/s
  *   the fifo/sysbus overflows.
- * 
+ *
  * IMPORTANT NOTE:
  *   On fast networks, it's a (very) good idea to have 16K shared memory. With
- *   8K, we can store only 4 receive frames, so it can (easily) happen that a remote 
+ *   8K, we can store only 4 receive frames, so it can (easily) happen that a remote
  *   machine 'overruns' our system.
  *
  * Known i82586/card problems (I'm sure, there are many more!):
  *   Running the NOP-mode, the i82586 sometimes seems to forget to report
  *   every xmit-interrupt until we restart the CU.
- *   Another MAJOR bug is, that the RU sometimes seems to ignore the EL-Bit 
- *   in the RBD-Struct which indicates an end of the RBD queue. 
- *   Instead, the RU fetches another (randomly selected and 
- *   usually used) RBD and begins to fill it. (Maybe, this happens only if 
+ *   Another MAJOR bug is, that the RU sometimes seems to ignore the EL-Bit
+ *   in the RBD-Struct which indicates an end of the RBD queue.
+ *   Instead, the RU fetches another (randomly selected and
+ *   usually used) RBD and begins to fill it. (Maybe, this happens only if
  *   the last buffer from the previous RFD fits exact into the queue and
  *   the next RFD can't fetch an initial RBD. Anyone knows more? )
  *
- * results from ftp performance tests with Linux 1.2.5 
+ * results from ftp performance tests with Linux 1.2.5
  *   send and receive about 350-400 KByte/s (peak up to 460 kbytes/s)
  *   sending in NOP-mode: peak performance up to 530K/s (but better don't run this mode)
  */
 
 /*
- * 29.Sept.96: virt_to_bus changes for new memory scheme 
+ * 29.Sept.96: virt_to_bus changes for new memory scheme
  * 19.Feb.96: more Mcast changes, module support (MH)
  *
  * 18.Nov.95: Mcast changes (AC).
  *
  * 23.April.95: fixed(?) receiving problems by configuring a RFD more
- *              than the number of RBD's. Can maybe cause other problems. 
+ *              than the number of RBD's. Can maybe cause other problems.
  * 18.April.95: Added MODULE support (MH)
  * 17.April.95: MC related changes in init586() and set_multicast_list().
  *              removed use of 'jiffies' in init586() (MH)
  *
  * 19.Sep.94: Added Multicast support (not tested yet) (MH)
- * 
- * 18.Sep.94: Workaround for 'EL-Bug'. Removed flexible RBD-handling. 
+ *
+ * 18.Sep.94: Workaround for 'EL-Bug'. Removed flexible RBD-handling.
  *            Now, every RFD has exact one RBD. (MH)
  *
  * 14.Sep.94: added promiscuous mode, a few cleanups (MH)
  *
  * 19.Aug.94: changed request_irq() parameter (MH)
- * 
+ *
  * 20.July.94: removed cleanup bugs, removed a 16K-mem-probe-bug (MH)
  *
  * 19.July.94: lotsa cleanups .. (MH)
@@ -96,7 +96,7 @@
  *
  * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff, too (MH)
  *
- * < 30.Sep.93: first versions 
+ * < 30.Sep.93: first versions
  */
 
 static int debuglevel = 0; /* debug-printk 0: off 1: a few 2: more */
@@ -143,9 +143,9 @@
 
 sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
 sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
-sizeof(rfd) = 24; sizeof(rbd) = 12; 
+sizeof(rfd) = 24; sizeof(rbd) = 12;
 sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
-sizeof(nop_cmd) = 8; 
+sizeof(nop_cmd) = 8;
 
   * if you don't know the driver, better do not change these values: */
 
@@ -159,7 +159,7 @@
 /**************************************************************************/
 
 /* different DELAYs */
-#define DELAY(x) __delay((loops_per_sec>>5)*(x)); 
+#define DELAY(x) __delay((loops_per_sec>>5)*(x));
 #define DELAY_16(); { __delay( (loops_per_sec>>16)+1 ); }
 #define DELAY_18(); { __delay( (loops_per_sec>>18)+1 ); }
 
@@ -234,7 +234,7 @@
 };
 
 /**********************************************
- * close device 
+ * close device
  */
 static int ni52_close(struct device *dev)
 {
@@ -252,21 +252,21 @@
 }
 
 /**********************************************
- * open device 
+ * open device
  */
 static int ni52_open(struct device *dev)
 {
   ni_disint();
   alloc586(dev);
-  init586(dev);  
+  init586(dev);
   startrecv586(dev);
   ni_enaint();
 
-  if(request_irq(dev->irq, &ni52_interrupt,0,"ni5210",NULL)) 
+  if(request_irq(dev->irq, &ni52_interrupt,0,"ni5210",NULL))
   {
     ni_reset586();
     return -EAGAIN;
-  }  
+  }
   irq2dev_map[dev->irq] = dev;
 
   dev->interrupt = 0;
@@ -279,7 +279,7 @@
 }
 
 /**********************************************
- * Check to see if there's an 82586 out there. 
+ * Check to see if there's an 82586 out there.
  */
 static int check586(struct device *dev,char *where,unsigned size)
 {
@@ -298,7 +298,7 @@
   p->scp->sysbus = SYSBUSVAL;        /* 1 = 8Bit-Bus, 0 = 16 Bit */
   if(p->scp->sysbus != SYSBUSVAL)
     return 0;
-  
+
   iscp_addrs[0] = bus_to_virt((unsigned long)where);
   iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct);
 
@@ -321,11 +321,11 @@
 }
 
 /******************************************************************
- * set iscp at the right place, called by ni52_probe1 and open586. 
+ * set iscp at the right place, called by ni52_probe1 and open586.
  */
 void alloc586(struct device *dev)
 {
-  struct priv *p =  (struct priv *) dev->priv; 
+  struct priv *p =  (struct priv *) dev->priv;
 
   ni_reset586();
   DELAY(1);
@@ -345,7 +345,7 @@
   ni_reset586();
   ni_attn586();
 
-  DELAY(1); 
+  DELAY(1);
 
   if(p->iscp->busy)
     printk("%s: Init-Problems (alloc).\n",dev->name);
@@ -380,7 +380,7 @@
     int ioaddr = *port;
     if (check_region(ioaddr, NI52_TOTAL_SIZE))
       continue;
-    if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || 
+    if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
         !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2))
       continue;
 
@@ -395,11 +395,11 @@
     int ioaddr = dev->base_addr;
     if (check_region(ioaddr, NI52_TOTAL_SIZE))
       continue;
-    if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || 
+    if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
         !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2))
       continue;
     if (ni52_probe1(dev, ioaddr) == 0)
-      return 0;    
+      return 0;
   }
 #endif
 
@@ -424,7 +424,7 @@
 
   request_region(ioaddr,NI52_TOTAL_SIZE,"ni5210");
 
-  /* 
+  /*
    * check (or search) IO-Memory, 8K and 16K
    */
 #ifdef MODULE
@@ -451,7 +451,7 @@
       }
     }
   }
-  else  
+  else
   {
    static long memaddrs[] = { 0xc8000,0xca000,0xcc000,0xce000,0xd0000,0xd2000,
                               0xd4000,0xd6000,0xd8000,0xda000,0xdc000, 0 };
@@ -473,7 +473,7 @@
   dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
 #endif
 
-  dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); 
+  dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
   if(dev->priv == NULL)
   {
     printk("%s: Ooops .. can't allocate private driver memory.\n",dev->name);
@@ -481,7 +481,7 @@
   }
                                   /* warning: we don't free it on errors */
   memset((char *) dev->priv,0,sizeof(struct priv));
-  
+
   ((struct priv *) (dev->priv))->memtop = bus_to_virt(dev->mem_start) + size;
   ((struct priv *) (dev->priv))->base =  (unsigned long) bus_to_virt(dev->mem_start) + size - 0x01000000;
   alloc586(dev);
@@ -501,7 +501,7 @@
     ni_attn586();
     if(!(dev->irq = autoirq_report(2)))
     {
-      printk("?autoirq, Failed to detect IRQ line!\n"); 
+      printk("?autoirq, Failed to detect IRQ line!\n");
       return 1;
     }
     printk("IRQ %d (autodetected).\n",dev->irq);
@@ -525,11 +525,11 @@
   dev->tbusy = 0;
   dev->interrupt = 0;
   dev->start = 0;
-  
+
   return 0;
 }
 
-/********************************************** 
+/**********************************************
  * init the chip (ni52-interrupt should be disabled?!)
  * needs a correct 'allocated' memory
  */
@@ -575,7 +575,7 @@
        dev->flags|=IFF_PROMISC;
   }
   cfg_cmd->carr_coll  = 0x00;
- 
+
   p->scb->cbl_offset = make16(cfg_cmd);
   p->scb->cmd_ruc = 0;
 
@@ -587,7 +587,7 @@
   if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK))
   {
     printk("%s: configure command failed: %x\n",dev->name,cfg_cmd->cmd_status);
-    return 1; 
+    return 1;
   }
 
     /*
@@ -610,11 +610,11 @@
 
   if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
     printk("%s (ni52): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status);
-    return 1; 
+    return 1;
   }
 
-   /* 
-    * TDR, wire check .. e.g. no resistor e.t.c 
+   /*
+    * TDR, wire check .. e.g. no resistor e.t.c
     */
   tdr_cmd = (struct tdr_cmd_struct *)ptr;
 
@@ -641,13 +641,13 @@
     p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
     ni_attn586(); /* ack the interrupts */
 
-    if(result & TDR_LNK_OK) 
+    if(result & TDR_LNK_OK)
       ;
     else if(result & TDR_XCVR_PRB)
       printk("%s: TDR: Transceiver problem. Check the cable(s)!\n",dev->name);
     else if(result & TDR_ET_OPN)
       printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
-    else if(result & TDR_ET_SRT) 
+    else if(result & TDR_ET_SRT)
     {
       if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
         printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
@@ -703,7 +703,7 @@
   }
 #endif
 
-  ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */ 
+  ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */
 
   /*
    * alloc xmit-buffs / init xmit_cmds
@@ -716,11 +716,11 @@
     ptr = (char *) ptr + XMIT_BUFF_SIZE;
     p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */
     ptr = (char *) ptr + sizeof(struct tbd_struct);
-    if((void *)ptr > (void *)p->iscp) 
+    if((void *)ptr > (void *)p->iscp)
     {
       printk("%s: not enough shared-mem for your configuration!\n",dev->name);
       return 1;
-    }   
+    }
     memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
     memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
     p->xmit_cmds[i]->cmd_link = make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]);
@@ -731,7 +731,7 @@
     p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
   }
 
-  p->xmit_count = 0; 
+  p->xmit_count = 0;
   p->xmit_last  = 0;
 #ifndef NO_NOPCOMMANDS
   p->nop_point  = 0;
@@ -763,11 +763,11 @@
 }
 
 /******************************************************
- * This is a helper routine for ni52_rnr_int() and init586(). 
+ * This is a helper routine for ni52_rnr_int() and init586().
  * It sets up the Receive Frame Area (RFA).
  */
 
-static void *alloc_rfa(struct device *dev,void *ptr) 
+static void *alloc_rfa(struct device *dev,void *ptr)
 {
   volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
   volatile struct rbd_struct *rbd;
@@ -854,7 +854,7 @@
       else
       {
         printk("%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->rus);
-        ni52_rnr_int(dev); 
+        ni52_rnr_int(dev);
       }
     }
 
@@ -989,7 +989,7 @@
 
 #ifdef 0
   if(!at_least_one)
-  { 
+  {
     int i;
     volatile struct rfd_struct *rfds=p->rfd_top;
     volatile struct rbd_struct *rbds;
@@ -1001,7 +1001,7 @@
       rfds = (struct rfd_struct *) make32(rfds->next);
     }
     printk("\nerrs: %04x %04x stat: %04x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->status);
-    printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus);  
+    printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus);
   }
   old_at_least = at_least_one;
 #endif
@@ -1022,7 +1022,7 @@
 
   WAIT_4_SCB_CMD();    /* wait for the last cmd, WAIT_4_FULLSTAT?? */
   p->scb->cmd_ruc = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
-  ni_attn586(); 
+  ni_attn586();
   WAIT_4_SCB_CMD_RUC();    /* wait for accept cmd. */
 
   alloc_rfa(dev,(char *)p->rfd_first);
@@ -1054,18 +1054,18 @@
     p->stats.tx_packets++;
     p->stats.collisions += (status & TCMD_MAXCOLLMASK);
   }
-  else 
+  else
   {
     p->stats.tx_errors++;
     if(status & TCMD_LATECOLL) {
       printk("%s: late collision detected.\n",dev->name);
       p->stats.collisions++;
-    } 
+    }
     else if(status & TCMD_NOCARRIER) {
       p->stats.tx_carrier_errors++;
       printk("%s: no carrier detected.\n",dev->name);
-    } 
-    else if(status & TCMD_LOSTCTS) 
+    }
+    else if(status & TCMD_LOSTCTS)
       printk("%s: loss of CTS detected.\n",dev->name);
     else if(status & TCMD_UNDERRUN) {
       p->stats.tx_fifo_errors++;
@@ -1074,11 +1074,11 @@
     else if(status & TCMD_MAXCOLL) {
       printk("%s: Max. collisions exceeded.\n",dev->name);
       p->stats.collisions += 16;
-    } 
+    }
   }
 
 #if (NUM_XMIT_BUFFS > 1)
-  if( (++p->xmit_last) == NUM_XMIT_BUFFS) 
+  if( (++p->xmit_last) == NUM_XMIT_BUFFS)
     p->xmit_last = 0;
 #endif
 
@@ -1088,7 +1088,7 @@
 
 /***********************************************************
  * (re)start the receiver
- */ 
+ */
 
 static void startrecv586(struct device *dev)
 {
@@ -1103,7 +1103,7 @@
 }
 
 /******************************************************
- * send frame 
+ * send frame
  */
 
 static int ni52_send_packet(struct sk_buff *skb, struct device *dev)
@@ -1222,7 +1222,7 @@
     next_nop = (p->nop_point + 1) & 0x1;
     p->xmit_buffs[0]->size = TBD_LAST | len;
 
-    p->xmit_cmds[0]->cmd_link   = p->nop_cmds[next_nop]->cmd_link 
+    p->xmit_cmds[0]->cmd_link   = p->nop_cmds[next_nop]->cmd_link
                                 = make16((p->nop_cmds[next_nop]));
     p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
 
@@ -1233,7 +1233,7 @@
 #  endif
 #else
     p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
-    if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS ) 
+    if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )
       next_nop = 0;
 
     p->xmit_cmds[p->xmit_count]->cmd_status  = 0;
@@ -1244,9 +1244,9 @@
     p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
     dev->trans_start = jiffies;
     p->xmit_count = next_nop;
- 
+
     {
-      long flags; 
+      long flags;
       save_flags(flags);
       cli();
       if(p->xmit_count != p->xmit_last)
@@ -1261,7 +1261,7 @@
 }
 
 /*******************************************
- * Someone wanna have the statistics 
+ * Someone wanna have the statistics
  */
 
 static struct enet_statistics *ni52_get_stats(struct device *dev)
@@ -1287,7 +1287,7 @@
 }
 
 /********************************************************
- * Set MC list ..  
+ * Set MC list ..
  */
 static void set_multicast_list(struct device *dev)
 {
@@ -1301,7 +1301,7 @@
 
   ni_disint();
   alloc586(dev);
-  init586(dev);  
+  init586(dev);
   startrecv586(dev);
   ni_enaint();
 
@@ -1321,6 +1321,11 @@
 long memstart=0; /* e.g 0xd0000 */
 long memend=0;   /* e.g 0xd4000 */
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(memstart, "l");
+MODULE_PARM(memend, "l");
+
 int init_module(void)
 {
   if(io <= 0x0 || !memend || !memstart || irq < 2) {
@@ -1383,7 +1388,5 @@
 #endif
 
 /*
- * END: linux/drivers/net/ni52.c 
+ * END: linux/drivers/net/ni52.c
  */
-
-
diff -u --recursive --new-file v2.1.18/linux/drivers/net/ni65.c linux/drivers/net/ni65.c
--- v2.1.18/linux/drivers/net/ni65.c	Thu Oct 10 19:10:55 1996
+++ linux/drivers/net/ni65.c	Tue Dec 31 10:30:02 1996
@@ -2,9 +2,9 @@
  * ni6510 (am7990 'lance' chip) driver for Linux-net-3
  * BETAcode v0.71 (96/09/29) for 2.0.0 (or later)
  * copyrights (c) 1994,1995,1996 by M.Hipp
- * 
- * This driver can handle the old ni6510 board and the newer ni6510 
- * EtherBlaster. (probably it also works with every full NE2100 
+ *
+ * This driver can handle the old ni6510 board and the newer ni6510
+ * EtherBlaster. (probably it also works with every full NE2100
  * compatible card)
  *
  * To compile as module, type:
@@ -40,7 +40,7 @@
  * simple performance test: (486DX-33/Ni6510-EB receives from 486DX4-100/Ni6510-EB)
  *    average: FTP -> 8384421 bytes received in 8.5 seconds
  *           (no RCV_VIA_SKB,no XMT_VIA_SKB,PARANOIA_CHECK,4 XMIT BUFS, 8 RCV_BUFFS)
- *    peak: FTP -> 8384421 bytes received in 7.5 seconds 
+ *    peak: FTP -> 8384421 bytes received in 7.5 seconds
  *           (RCV_VIA_SKB,XMT_VIA_SKB,no PARANOIA_CHECK,1(!) XMIT BUF, 16 RCV BUFFS)
  */
 
@@ -84,7 +84,7 @@
 
 /*
  * the current setting allows an acceptable performance
- * for 'RCV_PARANOIA_CHECK' read the 'known problems' part in 
+ * for 'RCV_PARANOIA_CHECK' read the 'known problems' part in
  * the header of this file
  * 'invert' the defines for max. performance. This may cause DMA problems
  * on some boards (e.g on my ASUS SP3G)
@@ -120,7 +120,7 @@
  */
 #if 1
 #define RMDNUM 16
-#define RMDNUMMASK 0x80000000 
+#define RMDNUMMASK 0x80000000
 #else
 #define RMDNUM 8
 #define RMDNUMMASK 0x60000000 /* log2(RMDNUM)<<29 */
@@ -147,7 +147,7 @@
 #define L_CONFIG  0x05
 #define L_BUSIF   0x06
 
-/* 
+/*
  * to access the lance/am7990-regs, you have to write
  * reg-number into L_ADDRREG, then you can access it using L_DATAREG
  */
@@ -193,11 +193,11 @@
 };
 #define NUM_CARDS 3
 
-struct priv 
+struct priv
 {
   struct rmd rmdhead[RMDNUM];
   struct tmd tmdhead[TMDNUM];
-  struct init_block ib; 
+  struct init_block ib;
   int rmdnum;
   int tmdnum,tmdlast;
 #ifdef RCV_VIA_SKB
@@ -216,7 +216,7 @@
   int cmdr_addr;
   int cardno;
   int features;
-}; 
+};
 
 static int  ni65_probe1(struct device *dev,int);
 static void ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs);
@@ -246,11 +246,11 @@
 
   if( !(cards[p->cardno].config & 0x02) )
     return;
- 
+
   outw(80,PORT+L_ADDRREG);
   if(inw(PORT+L_ADDRREG) != 80)
     return;
- 
+
   writereg( (csr80 & 0x3fff) ,80); /* FIFO watermarks */
   outw(0,PORT+L_ADDRREG);
   outw((short)isa0,PORT+L_BUSIF); /* write ISA 0: DMA_R : isa0 * 50ns */
@@ -269,7 +269,7 @@
   int irqval = request_irq(dev->irq, &ni65_interrupt,0,
                         cards[p->cardno].cardname,NULL);
   if (irqval) {
-    printk ("%s: unable to get IRQ %d (irqval=%d).\n", 
+    printk ("%s: unable to get IRQ %d (irqval=%d).\n",
               dev->name,dev->irq, irqval);
     return -EAGAIN;
   }
@@ -318,12 +318,12 @@
   dev->tbusy = 1;
   dev->start = 0;
   MOD_DEC_USE_COUNT;
-  return 0; 
+  return 0;
 }
 
-/* 
- * Probe The Card (not the lance-chip) 
- */ 
+/*
+ * Probe The Card (not the lance-chip)
+ */
 #ifdef MODULE
 static
 #endif
@@ -337,7 +337,7 @@
   else if (dev->base_addr > 0)         /* Don't probe at all. */
      return -ENXIO;
 
-  for (port = ports; *port; port++) 
+  for (port = ports; *port; port++)
   {
     if (ni65_probe1(dev, *port) == 0)
        return 0;
@@ -347,12 +347,12 @@
 }
 
 /*
- * this is the real card probe .. 
+ * this is the real card probe ..
  */
 static int ni65_probe1(struct device *dev,int ioaddr)
 {
   int i,j;
-  struct priv *p; 
+  struct priv *p;
 
   for(i=0;i<NUM_CARDS;i++) {
     if(check_region(ioaddr, cards[i].total_size))
@@ -464,8 +464,8 @@
     return -EAGAIN;
   }
 
-  /* 
-   * Grab the region so we can find another board. 
+  /*
+   * Grab the region so we can find another board.
    */
   request_region(ioaddr,cards[p->cardno].total_size,cards[p->cardno].cardname);
 
@@ -487,9 +487,9 @@
 }
 
 /*
- * set lance register and trigger init 
+ * set lance register and trigger init
  */
-static void ni65_init_lance(struct priv *p,unsigned char *daddr,int filter,int mode) 
+static void ni65_init_lance(struct priv *p,unsigned char *daddr,int filter,int mode)
 {
   int i;
   u32 pib;
@@ -566,8 +566,8 @@
   unsigned char *ptr;
   struct priv *p;
   int i;
- 
-  /* 
+
+  /*
    * we need 8-aligned memory ..
    */
   ptr = ni65_alloc_mem(dev,"BUFFER",sizeof(struct priv)+8,0);
@@ -611,7 +611,7 @@
 }
 
 /*
- * free buffers and private struct 
+ * free buffers and private struct
  */
 static void ni65_free_buffer(struct priv *p)
 {
@@ -673,7 +673,7 @@
           break;
       }
     }
-    
+
     for(i=0;i<TMDNUM;i++) {
       struct tmd *tmdp = p->tmdhead + i;
 #ifdef XMT_VIA_SKB
@@ -708,12 +708,12 @@
     if(!p->lock)
       dev->tbusy = (p->tmdnum || !p->xmit_queued) ? 0 : 1;
     dev->trans_start = jiffies;
-  } 
+  }
   else
     writedatareg(CSR0_STRT | csr0);
 }
 
-/* 
+/*
  * init lance (write init-values .. init-buffers) (open-helper)
  */
 static int ni65_lance_reinit(struct device *dev)
@@ -726,7 +726,7 @@
 
    disable_dma(dev->dma); /* I've never worked with dma, but we do it like the packetdriver */
    set_dma_mode(dev->dma,DMA_MODE_CASCADE);
-   enable_dma(dev->dma); 
+   enable_dma(dev->dma);
 
    outw(inw(PORT+L_RESET),PORT+L_RESET); /* first: reset the card */
    if( (i=readreg(CSR0) ) != 0x4)
@@ -764,17 +764,17 @@
      rmdp->mlen = 0;
      rmdp->u.s.status = RCV_OWN;
    }
-   
+
    if(dev->flags & IFF_PROMISC)
      ni65_init_lance(p,dev->dev_addr,0x00,M_PROM);
    else if(dev->mc_count || dev->flags & IFF_ALLMULTI)
      ni65_init_lance(p,dev->dev_addr,0xff,0x0);
-   else 
+   else
      ni65_init_lance(p,dev->dev_addr,0x00,0x00);
 
   /*
    * ni65_set_lance_mem() sets L_ADDRREG to CSR0
-   * NOW, WE WILL NEVER CHANGE THE L_ADDRREG, CSR0 IS ALWAYS SELECTED 
+   * NOW, WE WILL NEVER CHANGE THE L_ADDRREG, CSR0 IS ALWAYS SELECTED
    */
 
    if(inw(PORT+L_DATAREG) & CSR0_IDON)  {
@@ -787,9 +787,9 @@
    disable_dma(dev->dma);
    return 0; /* ->Error */
 }
- 
-/* 
- * interrupt handler  
+
+/*
+ * interrupt handler
  */
 static void ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 {
@@ -975,7 +975,7 @@
  */
 static void ni65_recv_intr(struct device *dev,int csr0)
 {
-  struct rmd *rmdp; 
+  struct rmd *rmdp;
   int rmdstat,len;
   int cnt=0;
   struct priv *p = (struct priv *) dev->priv;
@@ -984,7 +984,7 @@
   while(!( (rmdstat = rmdp->u.s.status) & RCV_OWN))
   {
     cnt++;
-    if( (rmdstat & (RCV_START | RCV_END | RCV_ERR)) != (RCV_START | RCV_END) ) /* error or oversized? */ 
+    if( (rmdstat & (RCV_START | RCV_END | RCV_ERR)) != (RCV_START | RCV_END) ) /* error or oversized? */
     {
       if(!(rmdstat & RCV_ERR)) {
         if(rmdstat & RCV_START)
@@ -1001,7 +1001,7 @@
           p->stats.rx_frame_errors++;
         if(rmdstat & RCV_OFLO)
           p->stats.rx_over_errors++;
-        if(rmdstat & RCV_CRC) 
+        if(rmdstat & RCV_CRC)
           p->stats.rx_crc_errors++;
         if(rmdstat & RCV_BUF_ERR)
           p->stats.rx_fifo_errors++;
@@ -1128,7 +1128,7 @@
     else {
       save_flags(flags);
       cli();
- 
+
       tmdp = p->tmdhead + p->tmdnum;
       tmdp->u.buffer = (u32) virt_to_bus(skb->data);
       p->tmd_skb[p->tmdnum] = skb;
@@ -1187,6 +1187,10 @@
 static int io=0;
 static int dma=0;
 
+MODULE_PARM(irq, "i");
+MODULE_PARM(io, "i");
+MODULE_PARM(dma, "i");
+
 int init_module(void)
 {
 #if 0
@@ -1222,7 +1226,5 @@
 #endif /* MODULE */
 
 /*
- * END of ni65.c 
+ * END of ni65.c
  */
-
-
diff -u --recursive --new-file v2.1.18/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v2.1.18/linux/drivers/net/plip.c	Thu Dec 12 19:37:06 1996
+++ linux/drivers/net/plip.c	Tue Dec 31 10:30:02 1996
@@ -20,7 +20,7 @@
  *		  - added message if driver loaded as a module but no
  *		    interfaces present.
  *		  - release claimed I/O ports if malloc() fails during init.
- *		
+ *
  *		Niibe Yutaka
  *		  - Module initialization.  You can specify I/O addr and IRQ:
  *			# insmod plip.o io=0x3bc irq=7
@@ -44,7 +44,7 @@
  *     Crynwr packet driver, Peter Bauer changed the protocol again
  *     back to original protocol.
  *
- *     This version follows original PLIP protocol. 
+ *     This version follows original PLIP protocol.
  *     So, this PLIP can't communicate the PLIP of Linux v1.0.
  */
 
@@ -187,7 +187,7 @@
 			unsigned char lsb;
 #else
 #error	"Please fix the endianness defines in <asm/byteorder.h>"
-#endif						
+#endif
 		} b;
 		unsigned short h;
 	} length;
@@ -553,7 +553,7 @@
 	case PLIP_PK_DATA:
 		lbuf = rcv->skb->data;
 		do
-			if (plip_receive(nibble_timeout, status_addr, 
+			if (plip_receive(nibble_timeout, status_addr,
 					 &rcv->nibble, &lbuf[rcv->byte]))
 				return TIMEOUT;
 		while (++rcv->byte < rcv->length.h);
@@ -605,7 +605,7 @@
 	return OK;
 }
 
-/* PLIP_SEND --- send a byte (two nibbles) 
+/* PLIP_SEND --- send a byte (two nibbles)
    Returns OK on success, TIMEOUT when timeout    */
 inline static int
 plip_send(unsigned short nibble_timeout, unsigned short data_addr,
@@ -625,7 +625,7 @@
 		data_addr++;
 		while (1) {
 			c0 = inb(data_addr);
-			if ((c0 & 0x80) == 0) 
+			if ((c0 & 0x80) == 0)
 				break;
 			if (--cx == 0)
 				return TIMEOUT;
@@ -1048,7 +1048,7 @@
 {
 	struct net_local *nl = (struct net_local *) dev->priv;
 	struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
-	
+
 	switch(pc->pcmd) {
 	case PLIP_GET_TIMEOUT:
 		pc->trigger = nl->trigger;
@@ -1068,24 +1068,27 @@
 static int io[] = {0, 0, 0};
 static int irq[] = {0, 0, 0};
 
+MODULE_PARM(io, "1-3i");
+MODULE_PARM(irq, "1-3i");
+
 static struct device dev_plip[] = {
 	{
 		"plip0",
 		0, 0, 0, 0,		/* memory */
 		0x3BC, 5,		/* base, irq */
-		0, 0, 0, NULL, plip_init 
+		0, 0, 0, NULL, plip_init
 	},
 	{
 		"plip1",
 		0, 0, 0, 0,		/* memory */
 		0x378, 7,		/* base, irq */
-		0, 0, 0, NULL, plip_init 
+		0, 0, 0, NULL, plip_init
 	},
 	{
 		"plip2",
 		0, 0, 0, 0,		/* memory */
 		0x278, 2,		/* base, irq */
-		0, 0, 0, NULL, plip_init 
+		0, 0, 0, NULL, plip_init
 	}
 };
 
@@ -1120,7 +1123,7 @@
 		return 0;
 
 	/* No parameters.  Default action is probing all interfaces. */
-	for (i=0; i < 3; i++) { 
+	for (i=0; i < 3; i++) {
 		if (register_netdev(&dev_plip[i]) == 0)
 			devices++;
 	}
diff -u --recursive --new-file v2.1.18/linux/drivers/net/ppp.c linux/drivers/net/ppp.c
--- v2.1.18/linux/drivers/net/ppp.c	Mon Dec 30 15:39:09 1996
+++ linux/drivers/net/ppp.c	Tue Dec 31 10:30:02 1996
@@ -165,6 +165,9 @@
 static int  flag_time = OPTIMIZE_FLAG_TIME;
 static int  max_dev   = PPP_MAX_DEV;
 
+MODULE_PARM(flag_time, "i");
+MODULE_PARM(max_dev, "i");
+
 /*
  * The "main" procedure to the ppp device
  */
diff -u --recursive --new-file v2.1.18/linux/drivers/net/slip.c linux/drivers/net/slip.c
--- v2.1.18/linux/drivers/net/slip.c	Thu Dec 12 19:37:06 1996
+++ linux/drivers/net/slip.c	Tue Dec 31 10:30:02 1996
@@ -90,7 +90,9 @@
 	struct device	dev;		/* the device			*/
 } slip_ctrl_t;
 static slip_ctrl_t	**slip_ctrls = NULL;
+
 int slip_maxdev = SL_NRUNIT;		/* Can be overridden with insmod! */
+MODULE_PARM(slip_maxdev, "i");
 
 static struct tty_ldisc	sl_ldisc;
 
@@ -291,7 +293,7 @@
 		}
 	}
 	sl->mtu      = dev->mtu;
-	
+
 	sl->buffsize = len;
 
 	restore_flags(flags);
@@ -571,11 +573,11 @@
 	sl->xbits    = 0;
 #endif
 	sl->flags   &= (1 << SLF_INUSE);      /* Clear ESCAPE & ERROR flags */
-#ifdef CONFIG_SLIP_SMART	
+#ifdef CONFIG_SLIP_SMART
 	sl->keepalive=0;		/* no keepalive by default = VSV */
 	init_timer(&sl->keepalive_timer);	/* initialize timer_list struct */
 	sl->keepalive_timer.data=(unsigned long)sl;
-	sl->keepalive_timer.function=sl_keepalive;	
+	sl->keepalive_timer.function=sl_keepalive;
 	sl->outfill=0;			/* & outfill too */
 	init_timer(&sl->outfill_timer);
 	sl->outfill_timer.data=(unsigned long)sl;
@@ -617,7 +619,7 @@
 	sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
 	dev->tbusy = 1;
 	dev->start = 0;
-	
+
 /*	dev->flags &= ~IFF_UP; */
 
 	return 0;
@@ -709,7 +711,7 @@
 	if ((err = sl_open(sl->dev)))  {
 		return err;
 	}
-	
+
 	MOD_INC_USE_COUNT;
 
 	/* Done.  We have linked the TTY line to a channel. */
@@ -734,7 +736,7 @@
 	}
 
 	(void) dev_close(sl->dev);
-	
+
 	tty->disc_data = 0;
 	sl->tty = NULL;
 	/* VSV = very important to remove timers */
@@ -1016,7 +1018,7 @@
 		}
 		get_user(tmp,(int *)arg);
                 if (tmp > 255) /* max for unchar */
-			return -EINVAL; 
+			return -EINVAL;
 		if ((sl->keepalive = (unchar) tmp) != 0) {
 			sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
 			add_timer(&sl->keepalive_timer);
@@ -1057,7 +1059,7 @@
 		put_user(sl->outfill, (int *)arg);
 		return 0;
 	/* VSV changes end */
-#endif	
+#endif
 
 	/* Allow stty to read, but not set, the serial port */
 	case TCGETS:
@@ -1099,15 +1101,15 @@
 #endif
 #ifdef CONFIG_SLIP_SMART
 	printk(KERN_INFO "SLIP linefill/keepalive option.\n");
-#endif	
+#endif
 
 	slip_ctrls = (slip_ctrl_t **) kmalloc(sizeof(void*)*slip_maxdev, GFP_KERNEL);
-	if (slip_ctrls == NULL) 
+	if (slip_ctrls == NULL)
 	{
 		printk("SLIP: Can't allocate slip_ctrls[] array!  Uaargh! (-> No SLIP available)\n");
 		return -ENOMEM;
 	}
-	
+
 	/* Clear the pointer array, we allocate devices when we need them */
 	memset(slip_ctrls, 0, sizeof(void*)*slip_maxdev); /* Pointers */
 
@@ -1152,11 +1154,11 @@
 	  return -ENODEV;
 
 	/* Set up the "SLIP Control Block". (And clear statistics) */
-	
+
 	memset(sl, 0, sizeof (struct slip));
 	sl->magic  = SLIP_MAGIC;
 	sl->dev	   = dev;
-	
+
 	/* Finish setting up the DEVICE info. */
 	dev->mtu		= SL_MTU;
 	dev->hard_start_xmit	= sl_xmit;
@@ -1195,16 +1197,16 @@
 {
 	int i;
 
-	if (slip_ctrls != NULL) 
+	if (slip_ctrls != NULL)
 	{
-		for (i = 0; i < slip_maxdev; i++)  
+		for (i = 0; i < slip_maxdev; i++)
 		{
 			if (slip_ctrls[i])
 			{
 				/*
 				 * VSV = if dev->start==0, then device
 				 * unregistered while close proc.
-				 */ 
+				 */
 				if (slip_ctrls[i]->dev.start)
 					unregister_netdev(&(slip_ctrls[i]->dev));
 
@@ -1215,7 +1217,7 @@
 		kfree(slip_ctrls);
 		slip_ctrls = NULL;
 	}
-	if ((i = tty_register_ldisc(N_SLIP, NULL)))  
+	if ((i = tty_register_ldisc(N_SLIP, NULL)))
 	{
 		printk("SLIP: can't unregister line discipline (err = %d)\n", i);
 	}
@@ -1227,7 +1229,7 @@
  * This is start of the code for multislip style line checking
  * added by Stanislav Voronyi. All changes before marked VSV
  */
- 
+
 static void sl_outfill(unsigned long sls)
 {
 	struct slip *sl=(struct slip *)sls;
@@ -1247,7 +1249,7 @@
 #endif
 			/* put END into tty queue. Is it right ??? */
 			if (!test_bit(0, (void *) &sl->dev->tbusy))
-			{ 
+			{
 				/* if device busy no outfill */
 				sl->tty->driver.write(sl->tty, 0, &s, 1);
 			}
diff -u --recursive --new-file v2.1.18/linux/drivers/net/smc-mca.c linux/drivers/net/smc-mca.c
--- v2.1.18/linux/drivers/net/smc-mca.c	Thu Dec 12 19:37:06 1996
+++ linux/drivers/net/smc-mca.c	Tue Dec 31 10:30:02 1996
@@ -1,7 +1,7 @@
 /* smc-ultra.c: A SMC Ultra ethernet driver for linux. */
 /*
     Most of this driver, except for ultramca_probe is nearly
-    verbatim from smc-ultra.c by Donald Becker. The rest is 
+    verbatim from smc-ultra.c by Donald Becker. The rest is
     written and copyright 1996 by David Weis, weisd3458@uni.edu
 
     This is a driver for the SMC Ultra and SMC EtherEZ ethercards.
@@ -46,10 +46,10 @@
 static int ultramca_open(struct device *dev);
 static void ultramca_reset_8390(struct device *dev);
 static void ultramca_get_8390_hdr(struct device *dev,
-                                  struct e8390_pkt_hdr *hdr, 
+                                  struct e8390_pkt_hdr *hdr,
                                   int ring_page);
 static void ultramca_block_input(struct device *dev, int count,
-                                 struct sk_buff *skb, 
+                                 struct sk_buff *skb,
                                  int ring_offset);
 static void ultramca_block_output(struct device *dev, int count,
                                   const unsigned char *buf,
@@ -74,18 +74,18 @@
 	unsigned char pos2, pos3, pos4, pos5;
 	int i;
 
-	if( (slot=mca_find_adapter(0x61c8,0)) != MCA_NOTFOUND) 
+	if( (slot=mca_find_adapter(0x61c8,0)) != MCA_NOTFOUND)
 	{
 #ifndef MODULE
 		mca_set_adapter_name( slot, "SMC Elite/A (8013EP/A)" );
 #endif
-	} 
-	else if( (slot=mca_find_adapter(0x61c9,0)) != MCA_NOTFOUND) 
+	}
+	else if( (slot=mca_find_adapter(0x61c9,0)) != MCA_NOTFOUND)
 	{
 #ifndef MODULE
 		mca_set_adapter_name( slot, "SMC Elite10T/A (8013WP/A)" );
 #endif
-	} 
+	}
 	else
 		return -ENODEV;
 
@@ -99,9 +99,9 @@
 
 	dev->mem_start = 0;
 	num_pages = 40;
-	for (i = 0; i < 15; i++) 
+	for (i = 0; i < 15; i++)
 	{
-		if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) 
+		if (mem_table[i].mem_index == (pos3 & ~MEM_MASK))
 		{
 			dev->mem_start = mem_table[i].mem_start;
 			num_pages = mem_table[i].num_pages;
@@ -121,42 +121,42 @@
 
 	/*
 	 *	Switch from the station address to the alternate register set and
-	 *	read the useful registers there. 
+	 *	read the useful registers there.
 	 */
 
 	outb(0x80 | reg4, ioaddr + 4);
 
 	/*
-	 *	Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. 
+	 *	Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot.
 	 */
 
 	outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c);
-  
+
 	/*
 	 *	Switch back to the station address register set so that the MS-DOS driver
-	 *	can find the card after a warm boot. 
+	 *	can find the card after a warm boot.
 	 */
 
 	outb(reg4, ioaddr + 4);
 
 	/*
-	 *	Allocate dev->priv and fill in 8390 specific dev fields. 
+	 *	Allocate dev->priv and fill in 8390 specific dev fields.
 	 */
 
-	if (ethdev_init(dev)) 
+	if (ethdev_init(dev))
 	{
 		printk (", no memory for dev->priv.\n");
 		return -ENOMEM;
 	}
- 
+
 	/*
-	 *	OK, we are certain this is going to work.  Setup the device. 
+	 *	OK, we are certain this is going to work.  Setup the device.
 	 */
 
 	request_region(ioaddr, ULTRA_IO_EXTENT, "smc-mca");
 
 	/*
-	 *	The 8390 isn't at the base address, so fake the offset 
+	 *	The 8390 isn't at the base address, so fake the offset
 	 */
 
 	dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
@@ -168,7 +168,7 @@
 	ei_status.stop_page = num_pages;
 
 	dev->rmem_start = dev->mem_start + TX_PAGES*256;
-	dev->mem_end = dev->rmem_end = 
+	dev->mem_end = dev->rmem_end =
 	dev->mem_start + (ei_status.stop_page - START_PG)*256;
 
 	printk(", IRQ %d memory %#lx-%#lx.\n", dev->irq, dev->mem_start, dev->mem_end-1);
@@ -198,7 +198,7 @@
 
 	/*
 	 *	Set the early receive warning level in window 0 high enough not
-	 *	to receive ERW interrupts. 
+	 *	to receive ERW interrupts.
 	 */
 
 	/*
@@ -250,7 +250,7 @@
 {
 	unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG<<8);
 
-	if (xfer_start + count > dev->rmem_end) 
+	if (xfer_start + count > dev->rmem_end)
 	{
         	/* We must wrap the input move. */
 		int semi_count = dev->rmem_end - xfer_start;
@@ -305,7 +305,7 @@
 #define NAMELEN     8   /* # of chars for storing dev->name */
 static char namelist[NAMELEN * MAX_ULTRA_CARDS] = { 0, };
 
-static struct device dev_ultra[MAX_ULTRA_CARDS] = 
+static struct device dev_ultra[MAX_ULTRA_CARDS] =
 {
 	{
 		NULL,       /* assign a chunk of namelist[] below */
@@ -318,6 +318,9 @@
 static int io[MAX_ULTRA_CARDS] = { 0, };
 static int irq[MAX_ULTRA_CARDS]  = { 0, };
 
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
+
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
 
@@ -325,23 +328,23 @@
 {
 	int this_dev, found = 0;
 
-	for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) 
+	for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++)
 	{
 		struct device *dev = &dev_ultra[this_dev];
 		dev->name = namelist+(NAMELEN*this_dev);
 		dev->irq = irq[this_dev];
 		dev->base_addr = io[this_dev];
 		dev->init = ultra_probe;
-		if (io[this_dev] == 0)  
-		{	
-			if (this_dev != 0) 
+		if (io[this_dev] == 0)
+		{
+			if (this_dev != 0)
 				break; /* only autoprobe 1st one */
 			printk(KERN_NOTICE "smc-mca.c: Presently autoprobing (not recommended) for a single card.\n");
 		}
-		if (register_netdev(dev) != 0) 
+		if (register_netdev(dev) != 0)
 		{
 			printk(KERN_WARNING "smc-mca.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
-			if (found != 0) 
+			if (found != 0)
 				return 0;   /* Got at least one. */
 			return -ENXIO;
 		}
@@ -354,10 +357,10 @@
 {
 	int this_dev;
 
-	for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) 
+	for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++)
 	{
 		struct device *dev = &dev_ultra[this_dev];
-        	if (dev->priv != NULL) 
+        	if (dev->priv != NULL)
         	{
 			/* NB: ultra_close_card() does free_irq + irq2dev */
 			int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
diff -u --recursive --new-file v2.1.18/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
--- v2.1.18/linux/drivers/net/smc-ultra.c	Thu Jun  6 09:54:05 1996
+++ linux/drivers/net/smc-ultra.c	Tue Dec 31 10:30:02 1996
@@ -19,7 +19,7 @@
 	8390.c.  The code in this file is responsible for
 
 		ultra_probe()	 	Detecting and initializing the card.
-		ultra_probe1()	
+		ultra_probe1()
 
 		ultra_open()		The card-specific details of starting, stopping
 		ultra_reset_8390()	and resetting the 8390 NIC core.
@@ -69,13 +69,13 @@
 
 static int ultra_open(struct device *dev);
 static void ultra_reset_8390(struct device *dev);
-static void ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, 
+static void ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
 						int ring_page);
 static void ultra_block_input(struct device *dev, int count,
 						  struct sk_buff *skb, int ring_offset);
 static void ultra_block_output(struct device *dev, int count,
 							const unsigned char *buf, const start_page);
-static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, 
+static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
 						int ring_page);
 static void ultra_pio_input(struct device *dev, int count,
 						  struct sk_buff *skb, int ring_offset);
@@ -201,7 +201,7 @@
 		printk (", no memory for dev->priv.\n");
                 return -ENOMEM;
         }
- 
+
 	/* OK, we are certain this is going to work.  Setup the device. */
 	request_region(ioaddr, ULTRA_IO_EXTENT, model_name);
 
@@ -357,7 +357,7 @@
    must be always be rewritten between each read/write direction change.
    This is no problem for us, as the 8390 code ensures that we are single
    threaded. */
-static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, 
+static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
 						int ring_page)
 {
 	int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
@@ -433,6 +433,9 @@
 
 static int io[MAX_ULTRA_CARDS] = { 0, };
 static int irq[MAX_ULTRA_CARDS]  = { 0, };
+
+MODULE_PARM(io, "1-" __MODULE_PARM(MAX_ULTRA_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_PARM(MAX_ULTRA_CARDS) "i");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.1.18/linux/drivers/net/smc9194.c linux/drivers/net/smc9194.c
--- v2.1.18/linux/drivers/net/smc9194.c	Wed Oct  9 08:55:20 1996
+++ linux/drivers/net/smc9194.c	Tue Dec 31 10:30:02 1996
@@ -1,24 +1,24 @@
 /*------------------------------------------------------------------------
  . smc9194.c
- . This is a driver for SMC's 9000 series of Ethernet cards. 
+ . This is a driver for SMC's 9000 series of Ethernet cards.
  .
  . Copyright (C) 1996 by Erik Stahlman
  . This software may be used and distributed according to the terms
  . of the GNU Public License, incorporated herein by reference.
  .
- . "Features" of the SMC chip:  
- .   4608 byte packet memory. ( for the 91C92.  Others have more ) 
+ . "Features" of the SMC chip:
+ .   4608 byte packet memory. ( for the 91C92.  Others have more )
  .   EEPROM for configuration
  .   AUI/TP selection  ( mine has 10Base2/10BaseT select )
  .
  . Arguments:
  . 	io		 = for the base address
- .	irq	 = for the IRQ 
- .	ifport = 0 for autodetect, 1 for TP, 2 for AUI ( or 10base2 )   
+ .	irq	 = for the IRQ
+ .	ifport = 0 for autodetect, 1 for TP, 2 for AUI ( or 10base2 )
  .
- . author:  
+ . author:
  . 	Erik Stahlman				( erik@vt.edu )
- .   
+ .
  . Hardware multicast code from Peter Cammaert ( pc@denkart.be )
  .
  . Sources:
@@ -27,33 +27,33 @@
  .    o   ( a LOT of advice from Becker as well )
  .
  . History:
- .	12/07/95  Erik Stahlman  written, got receive/xmit handled 
+ .	12/07/95  Erik Stahlman  written, got receive/xmit handled
  . 	01/03/96  Erik Stahlman  worked out some bugs, actually usable!!! :-)
- .	01/06/96  Erik Stahlman	 cleaned up some, better testing, etc 
+ .	01/06/96  Erik Stahlman	 cleaned up some, better testing, etc
  .	01/29/96  Erik Stahlman	 fixed autoirq, added multicast
  . 	02/01/96  Erik Stahlman	 1. disabled all interrupts in smc_reset
- .		   		 2. got rid of post-decrementing bug -- UGH.  
+ .		   		 2. got rid of post-decrementing bug -- UGH.
  .	02/13/96  Erik Stahlman  Tried to fix autoirq failure.  Added more
  .				 descriptive error messages.
  .	02/15/96  Erik Stahlman  Fixed typo that caused detection failure
- . 	02/23/96  Erik Stahlman	 Modified it to fit into kernel tree  
+ . 	02/23/96  Erik Stahlman	 Modified it to fit into kernel tree
  .				 Added support to change hardware address
  .				 Cleared stats on opens
  .	02/26/96  Erik Stahlman	 Trial support for Kernel 1.2.13
  .				 Kludge for automatic IRQ detection
- .	03/04/96  Erik Stahlman	 Fixed kernel 1.3.70 + 
- .				 Fixed bug reported by Gardner Buchanan in 
+ .	03/04/96  Erik Stahlman	 Fixed kernel 1.3.70 +
+ .				 Fixed bug reported by Gardner Buchanan in
  .				   smc_enable, with outw instead of outb
  .	03/06/96  Erik Stahlman  Added hardware multicast from Peter Cammaert
  ----------------------------------------------------------------------------*/
 
 static const char *version =
-	"smc9194.c:v0.12 03/06/96 by Erik Stahlman (erik@vt.edu)\n";  
+	"smc9194.c:v0.12 03/06/96 by Erik Stahlman (erik@vt.edu)\n";
 
 #ifdef MODULE
 #include <linux/module.h>
 #include <linux/version.h>
-#endif 
+#endif
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -76,52 +76,52 @@
 
 #include "smc9194.h"
 /*------------------------------------------------------------------------
- .  
- . Configuration options, for the experienced user to change. 
+ .
+ . Configuration options, for the experienced user to change.
  .
  -------------------------------------------------------------------------*/
 
-/* 
- . this is for kernels > 1.2.70 
+/*
+ . this is for kernels > 1.2.70
 */
-#define REALLY_NEW_KERNEL 
+#define REALLY_NEW_KERNEL
 #ifndef REALLY_NEW_KERNEL
 #define free_irq( x, y ) free_irq( x )
 #define request_irq( x, y, z, u, v ) request_irq( x, y, z, u )
 #endif
 
 /*
- . Do you want to use this with old kernels.  
- . WARNING: this is not well tested.  
+ . Do you want to use this with old kernels.
+ . WARNING: this is not well tested.
 #define SUPPORT_OLD_KERNEL
 */
 
 
 /*
  . Do you want to use 32 bit xfers?  This should work on all chips, as
- . the chipset is designed to accommodate them.   
+ . the chipset is designed to accommodate them.
 */
 #define USE_32_BIT 1
 
-/* 
+/*
  .the SMC9194 can be at any of the following port addresses.  To change,
- .for a slightly different card, you can add it to the array.  Keep in 
+ .for a slightly different card, you can add it to the array.  Keep in
  .mind that the array must end in zero.
 */
 static unsigned int smc_portlist[] =
    { 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
 	  0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0};
 
-/* 
- . Wait time for memory to be free.  This probably shouldn't be 
- . tuned that much, as waiting for this means nothing else happens 
- . in the system 
+/*
+ . Wait time for memory to be free.  This probably shouldn't be
+ . tuned that much, as waiting for this means nothing else happens
+ . in the system
 */
 #define MEMORY_WAIT_TIME 16
 
 /*
  . DEBUGGING LEVELS
- . 
+ .
  . 0 for normal operation
  . 1 for slightly more details
  . >2 for various levels of increasingly useless information
@@ -131,13 +131,13 @@
 #define SMC_DEBUG 0
 
 #if (SMC_DEBUG > 2 )
-#define PRINTK3(x) printk x 
-#else 
-#define PRINTK3(x) 
+#define PRINTK3(x) printk x
+#else
+#define PRINTK3(x)
 #endif
 
-#if SMC_DEBUG > 1 
-#define PRINTK2(x) printk x 
+#if SMC_DEBUG > 1
+#define PRINTK2(x) printk x
 #else
 #define PRINTK2(x)
 #endif
@@ -146,7 +146,7 @@
 #define PRINTK(x) printk x
 #else
 #define PRINTK(x)
-#endif 
+#endif
 
 
 /* the older versions of the kernel cannot support autoprobing */
@@ -157,30 +157,30 @@
 
 /*------------------------------------------------------------------------
  .
- . The internal workings of the driver.  If you are changing anything 
- . here with the SMC stuff, you should have the datasheet and known 
- . what you are doing.  
- .  
+ . The internal workings of the driver.  If you are changing anything
+ . here with the SMC stuff, you should have the datasheet and known
+ . what you are doing.
+ .
  -------------------------------------------------------------------------*/
 #define CARDNAME "SMC9194"
 
 #ifdef SUPPORT_OLD_KERNEL
 char kernel_version[] = UTS_RELEASE;
-#endif 
+#endif
 
-/* store this information for the driver.. */ 
+/* store this information for the driver.. */
 struct smc_local {
 	/*
  	   these are things that the kernel wants me to keep, so users
 	   can find out semi-useless statistics of how well the card is
-	   performing 
+	   performing
  	*/
 	struct enet_statistics stats;
-	
-	/* 
+
+	/*
 	   If I have to wait until memory is available to send
 	   a packet, I will store the skbuff here, until I get the
-	   desired memory.  Then, I'll send it out and free it.    
+	   desired memory.  Then, I'll send it out and free it.
 	*/
 	struct sk_buff * saved_skb;
 
@@ -196,14 +196,14 @@
 /*-----------------------------------------------------------------
  .
  .  The driver can be entered at any of the following entry points.
- . 
+ .
  .------------------------------------------------------------------  */
 
 /*
- . This is called by  register_netdev().  It is responsible for 
- . checking the portlist for the SMC9000 series chipset.  If it finds 
+ . This is called by  register_netdev().  It is responsible for
+ . checking the portlist for the SMC9000 series chipset.  If it finds
  . one, then it will initialize the device, find the hardware information,
- . and sets up the appropriate device parameters.   
+ . and sets up the appropriate device parameters.
  . NOTE: Interrupts are *OFF* when this procedure is called.
  .
  . NB:This shouldn't be static since it is referred to externally.
@@ -212,32 +212,32 @@
 
 /*
  . The kernel calls this function when someone wants to use the device,
- . typically 'ifconfig ethX up'.   
+ . typically 'ifconfig ethX up'.
 */
 static int smc_open(struct device *dev);
 
 /*
  . This is called by the kernel to send a packet out into the net.  it's
  . responsible for doing a best-effort send, but if it's simply not possible
- . to send it, the packet gets dropped. 
-*/  
+ . to send it, the packet gets dropped.
+*/
 static int smc_send_packet(struct sk_buff *skb, struct device *dev);
 
-/* 
+/*
  . This is called by the kernel in response to 'ifconfig ethX down'.  It
- . is responsible for cleaning up everything that the open routine 
- . does, and maybe putting the card into a powerdown state. 
+ . is responsible for cleaning up everything that the open routine
+ . does, and maybe putting the card into a powerdown state.
 */
 static int smc_close(struct device *dev);
 
 /*
- . This routine allows the proc file system to query the driver's 
- . statistics.  
+ . This routine allows the proc file system to query the driver's
+ . statistics.
 */
 static struct enet_statistics * smc_query_statistics( struct device *dev);
 
 /*
- . Finally, a call to set promiscuous mode ( for TCPDUMP and related 
+ . Finally, a call to set promiscuous mode ( for TCPDUMP and related
  . programs ) and multicast modes.
 */
 #ifdef SUPPORT_OLD_KERNEL
@@ -245,43 +245,43 @@
 				 void *addrs);
 #else
 static void smc_set_multicast_list(struct device *dev);
-#endif 
+#endif
 
 /*---------------------------------------------------------------
- . 
- . Interrupt level calls.. 
+ .
+ . Interrupt level calls..
  .
  ----------------------------------------------------------------*/
 
 /*
- . Handles the actual interrupt 
+ . Handles the actual interrupt
 */
 #ifdef REALLY_NEW_KERNEL
 static void smc_interrupt(int irq, void *, struct pt_regs *regs);
 #else
 static void smc_interrupt(int irq, struct pt_regs *regs);
-#endif 
+#endif
 /*
  . This is a separate procedure to handle the receipt of a packet, to
- . leave the interrupt code looking slightly cleaner 
-*/ 
+ . leave the interrupt code looking slightly cleaner
+*/
 inline static void smc_rcv( struct device *dev );
 /*
  . This handles a TX interrupt, which is only called when an error
- . relating to a packet is sent.  
+ . relating to a packet is sent.
 */
 inline static void smc_tx( struct device * dev );
 
 /*
  ------------------------------------------------------------
- . 
+ .
  . Internal routines
  .
  ------------------------------------------------------------
 */
 
 /*
- . Test if a given location contains a chip, trying to cause as 
+ . Test if a given location contains a chip, trying to cause as
  . little damage as possible if it's not a SMC chip.
 */
 static int smc_probe( int ioaddr );
@@ -289,26 +289,26 @@
 /*
  . this routine initializes the cards hardware, prints out the configuration
  . to the system log as well as the vanity message, and handles the setup
- . of a device parameter. 
+ . of a device parameter.
  . It will give an error if it can't initialize the card.
 */
-static int smc_initcard( struct device *, int ioaddr ); 
+static int smc_initcard( struct device *, int ioaddr );
 
 /*
  . A rather simple routine to print out a packet for debugging purposes.
-*/ 
-#if SMC_DEBUG > 2 
+*/
+#if SMC_DEBUG > 2
 static void print_packet( byte *, int );
-#endif  
+#endif
 
 #define tx_done(dev) 1
 
-/* this is called to actually send the packet to the chip */ 
+/* this is called to actually send the packet to the chip */
 static void smc_hardware_send_packet( struct device * dev );
 
 /* Since I am not sure if I will have enough room in the chip's ram
- . to store the packet, I call this routine, which either sends it 
- . now, or generates an interrupt when the card is ready for the 
+ . to store the packet, I call this routine, which either sends it
+ . now, or generates an interrupt when the card is ready for the
  . packet */
 static int  smc_wait_to_send_packet( struct sk_buff * skb, struct device *dev );
 
@@ -328,7 +328,7 @@
 #endif
 
 /*
-  this routine will set the hardware multicast table to the specified 
+  this routine will set the hardware multicast table to the specified
   values given it by the higher level routines
 */
 #ifndef SUPPORT_OLD_KERNEL
@@ -339,66 +339,66 @@
 #ifdef SUPPORT_OLD_KERNEL
 extern struct device *init_etherdev(struct device *dev, int sizeof_private,
  			unsigned long *mem_startp );
-#endif 
+#endif
 
 /*
  . Function: smc_reset( int ioaddr )
  . Purpose:
  .  	This sets the SMC91xx chip to its normal state, hopefully from whatever
- . 	mess that any other DOS driver has put it in.   
- . 
+ . 	mess that any other DOS driver has put it in.
+ .
  . Maybe I should reset more registers to defaults in here?  SOFTRESET  should
- . do that for me.  
- . 
+ . do that for me.
+ .
  . Method:
- .	1.  send a SOFT RESET 
+ .	1.  send a SOFT RESET
  .	2.  wait for it to finish
  .	3.  enable autorelease mode
  .	4.  reset the memory management unit
  .	5.  clear all interrupts
  .
-*/  
-static void smc_reset( int ioaddr ) 
-{ 
+*/
+static void smc_reset( int ioaddr )
+{
 	/* This resets the registers mostly to defaults, but doesn't
 	   affect EEPROM.  That seems unnecessary */
 	SMC_SELECT_BANK( 0 );
-	outw( RCR_SOFTRESET, ioaddr + RCR ); 
-	
+	outw( RCR_SOFTRESET, ioaddr + RCR );
+
 	/* this should pause enough for the chip to be happy */
 	SMC_DELAY( );
 
-	/* Set the transmit and receive configuration registers to 
+	/* Set the transmit and receive configuration registers to
 	   default values */
 	outw( RCR_CLEAR, ioaddr + RCR );
 	outw( TCR_CLEAR, ioaddr + TCR );
 
 	/* set the control register to automatically
-	   release successfully transmitted packets, to make the best 
+	   release successfully transmitted packets, to make the best
 	   use out of our limited memory */
 	SMC_SELECT_BANK( 1 );
-	outw( inw( ioaddr + CONTROL ) | CTL_AUTO_RELEASE , ioaddr + CONTROL );	
+	outw( inw( ioaddr + CONTROL ) | CTL_AUTO_RELEASE , ioaddr + CONTROL );
 
 	/* Reset the MMU */
 	SMC_SELECT_BANK( 2 );
 	outw( MC_RESET, ioaddr + MMU_CMD );
 
-	/* Note:  It doesn't seem that waiting for the MMU busy is needed here, 
+	/* Note:  It doesn't seem that waiting for the MMU busy is needed here,
 	   but this is a place where future chipsets _COULD_ break.  Be wary
  	   of issuing another MMU command right after this */
 
 	outb( 0, ioaddr + INT_MASK );
 }
 
-/* 
+/*
  . Function: smc_enable
  . Purpose: let the chip talk to the outside work
- . Method: 
+ . Method:
  .	1.  Enable the transmitter
  .	2.  Enable the receiver
  .	3.  Enable interrupts
 */
-static void smc_enable( int ioaddr ) 
+static void smc_enable( int ioaddr )
 {
 	SMC_SELECT_BANK( 0 );
 	/* see the header file for options in TCR/RCR NORMAL*/
@@ -408,23 +408,23 @@
 	/* now, enable interrupts */
 	SMC_SELECT_BANK( 2 );
 	outb( SMC_INTERRUPT_MASK, ioaddr + INT_MASK );
-} 	
-	
+}
+
 /*
  . Function: smc_shutdown
  . Purpose:  closes down the SMC91xxx chip.
- . Method:   
+ . Method:
  .	1. zero the interrupt mask
  .	2. clear the enable receive flag
  .	3. clear the enable xmit flags
  .
- . TODO: 
+ . TODO:
  .   (1) maybe utilize power down mode.
  .	Why not yet?  Because while the chip will go into power down mode,
  .	the manual says that it will wake up in response to any I/O requests
  .	in the register space.   Empirical results do not show this working.
 */
-static void smc_shutdown( int ioaddr ) 
+static void smc_shutdown( int ioaddr )
 {
 	/* no more interrupts for me */
 	SMC_SELECT_BANK( 2 );
@@ -434,30 +434,30 @@
 	SMC_SELECT_BANK( 0 );
 	outb( RCR_CLEAR, ioaddr + RCR );
 	outb( TCR_CLEAR, ioaddr + TCR );
-#if 0 
+#if 0
 	/* finally, shut the chip down */
-	SMC_SELECT_BANK( 1 ); 
+	SMC_SELECT_BANK( 1 );
 	outw( inw( ioaddr + CONTROL ), CTL_POWERDOWN, ioaddr + CONTROL  );
-#endif 
+#endif
 }
 
 
-#ifndef SUPPORT_OLD_KERNEL 
-/* 
+#ifndef SUPPORT_OLD_KERNEL
+/*
  . Function: smc_setmulticast( int ioaddr, int count, dev_mc_list * adds )
  . Purpose:
  .    This sets the internal hardware table to filter out unwanted multicast
- .    packets before they take up memory.  
- .    
+ .    packets before they take up memory.
+ .
  .    The SMC chip uses a hash table where the high 6 bits of the CRC of
- .    address are the offset into the table.  If that bit is 1, then the 
+ .    address are the offset into the table.  If that bit is 1, then the
  .    multicast packet is accepted.  Otherwise, it's dropped silently.
- .  
+ .
  .    To use the 6 bits as an offset into the table, the high 3 bits are the
  .    number of the 8 bit register, while the low 3 bits are the bit within
  .    that register.
  .
- . This routine is based very heavily on the one provided by Peter Cammaert. 
+ . This routine is based very heavily on the one provided by Peter Cammaert.
 */
 
 
@@ -465,35 +465,35 @@
 	int			i;
 	unsigned char		multicast_table[ 8 ];
 	struct dev_mc_list	* cur_addr;
-	/* table for flipping the order of 3 bits */  
+	/* table for flipping the order of 3 bits */
 	unsigned char invert3[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
 
-	/* start with a table of all zeros: reject all */	
+	/* start with a table of all zeros: reject all */
 	memset( multicast_table, 0, sizeof( multicast_table ) );
 
 	cur_addr = addrs;
 	for ( i = 0; i < count ; i ++, cur_addr = cur_addr->next  ) {
 		int position;
-		
+
 		/* do we have a pointer here? */
-		if ( !cur_addr ) 
+		if ( !cur_addr )
 			break;
 		/* make sure this is a multicast address - shouldn't this
-		   be a given if we have it here ? */	
-		if ( !( *cur_addr->dmi_addr & 1 ) ) 	
-			continue;	
+		   be a given if we have it here ? */
+		if ( !( *cur_addr->dmi_addr & 1 ) )
+			continue;
 
-		/* only use the low order bits */	
+		/* only use the low order bits */
 		position = crc32( cur_addr->dmi_addr, 6 ) & 0x3f;
-				
+
 		/* do some messy swapping to put the bit in the right spot */
-		multicast_table[invert3[position&7]] |= 
+		multicast_table[invert3[position&7]] |=
 					(1<<invert3[(position>>3)&7]);
 
 	}
 	/* now, the table can be loaded into the chipset */
 	SMC_SELECT_BANK( 3 );
-	
+
 	for ( i = 0; i < 8 ; i++ ) {
 		outb( multicast_table[i], ioaddr + MULTICAST1 + i );
 	}
@@ -501,20 +501,20 @@
 
 /*
   Finds the CRC32 of a set of bytes.
-  Again, from Peter Cammaert's code. 
+  Again, from Peter Cammaert's code.
 */
-static int crc32( char * s, int length ) { 
+static int crc32( char * s, int length ) {
 	/* indices */
 	int perByte;
 	int perBit;
 	/* crc polynomial for Ethernet */
 	const unsigned long poly = 0xedb88320;
 	/* crc value - preinitialized to all 1's */
-	unsigned long crc_value = 0xffffffff; 
+	unsigned long crc_value = 0xffffffff;
 
 	for ( perByte = 0; perByte < length; perByte ++ ) {
 		unsigned char	c;
-	
+
 		c = *(s++);
 		for ( perBit = 0; perBit < 8; perBit++ ) {
 			crc_value = (crc_value>>1)^
@@ -523,16 +523,16 @@
 		}
 	}
 	return	crc_value;
-} 
+}
 
-#endif 
+#endif
 
 
-/* 
- . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct device * ) 
- . Purpose: 
+/*
+ . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct device * )
+ . Purpose:
  .    Attempt to allocate memory for a packet, if chip-memory is not
- .    available, then tell the card to generate an interrupt when it 
+ .    available, then tell the card to generate an interrupt when it
  .    is available.
  .
  . Algorithm:
@@ -540,18 +540,18 @@
  . o	if the saved_skb is not currently null, then drop this packet
  .	on the floor.  This should never happen, because of TBUSY.
  . o	if the saved_skb is null, then replace it with the current packet,
- . o	See if I can sending it now. 
+ . o	See if I can sending it now.
  . o 	(NO): Enable interrupts and let the interrupt handler deal with it.
  . o	(YES):Send it now.
 */
 static int smc_wait_to_send_packet( struct sk_buff * skb, struct device * dev )
-{ 
+{
 	struct smc_local *lp 	= (struct smc_local *)dev->priv;
 	unsigned short ioaddr 	= dev->base_addr;
 	word 			length;
 	unsigned short 		numPages;
-	word			time_out;	
-	
+	word			time_out;
+
 	if ( lp->saved_skb) {
 		/* THIS SHOULD NEVER HAPPEN. */
 		lp->stats.tx_aborted_errors++;
@@ -561,54 +561,54 @@
 	lp->saved_skb = skb;
 
 	length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-		
+
 	/*
-	. the MMU wants the number of pages to be the number of 256 bytes 
-    	. 'pages', minus 1 ( since a packet can't ever have 0 pages :) ) 
+	. the MMU wants the number of pages to be the number of 256 bytes
+    	. 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
 	*/
 	numPages = length / 256;
 
 	if (numPages > 7 ) {
 		printk(CARDNAME": Far too big packet error. \n");
-		/* freeing the packet is a good thing here... but should 		
+		/* freeing the packet is a good thing here... but should
 		 . any packets of this size get down here?   */
 		dev_kfree_skb (skb, FREE_WRITE);
 		lp->saved_skb = NULL;
 		/* this IS an error, but, i don't want the skb saved */
-		return 0; 
+		return 0;
 	}
 	/* either way, a packet is waiting now */
 	lp->packets_waiting++;
-	 
+
 	/* now, try to allocate the memory */
 	SMC_SELECT_BANK( 2 );
 	outw( MC_ALLOC | numPages, ioaddr + MMU_CMD );
 	/*
  	. Performance Hack
-	.  
+	.
  	. wait a short amount of time.. if I can send a packet now, I send
 	. it now.  Otherwise, I enable an interrupt and wait for one to be
-	. available. 
+	. available.
 	.
 	. I could have handled this a slightly different way, by checking to
 	. see if any memory was available in the FREE MEMORY register.  However,
 	. either way, I need to generate an allocation, and the allocation works
-	. no matter what, so I saw no point in checking free memory.   
-	*/ 
+	. no matter what, so I saw no point in checking free memory.
+	*/
 	time_out = MEMORY_WAIT_TIME;
-	do { 
+	do {
 		word	status;
 
 		status = inb( ioaddr + INTERRUPT );
-		if ( status & IM_ALLOC_INT ) { 
+		if ( status & IM_ALLOC_INT ) {
 			/* acknowledge the interrupt */
 			outb( IM_ALLOC_INT, ioaddr + INTERRUPT );
-  			break;	
+  			break;
 		}
    	} while ( -- time_out );
 
    	if ( !time_out ) {
-		/* oh well, wait until the chip finds memory later */ 
+		/* oh well, wait until the chip finds memory later */
 		SMC_ENABLE_INT( IM_ALLOC_INT );
       		PRINTK2((CARDNAME": memory allocation deferred. \n"));
 		/* it's deferred, but I'll handle it later */
@@ -616,38 +616,38 @@
    	}
 	/* or YES! I can send the packet now.. */
 	smc_hardware_send_packet(dev);
-	
+
 	return 0;
-}	
+}
 
 /*
  . Function:  smc_hardware_send_packet(struct device * )
- . Purpose:	
- .	This sends the actual packet to the SMC9xxx chip.   
- . 
+ . Purpose:
+ .	This sends the actual packet to the SMC9xxx chip.
+ .
  . Algorithm:
- . 	First, see if a saved_skb is available.    
+ . 	First, see if a saved_skb is available.
  .		( this should NOT be called if there is no 'saved_skb'
  .	Now, find the packet number that the chip allocated
- .	Point the data pointers at it in memory 
+ .	Point the data pointers at it in memory
  .	Set the length word in the chip's memory
  .	Dump the packet to chip memory
  .	Check if a last byte is needed ( odd length packet )
- .		if so, set the control flag right 
- . 	Tell the card to send it 
+ .		if so, set the control flag right
+ . 	Tell the card to send it
  .	Enable the transmit interrupt, so I know if it failed
  . 	Free the kernel data if I actually sent it.
 */
-static void smc_hardware_send_packet( struct device * dev ) 
+static void smc_hardware_send_packet( struct device * dev )
 {
 	struct smc_local *lp = (struct smc_local *)dev->priv;
 	byte	 		packet_no;
 	struct sk_buff * 	skb = lp->saved_skb;
-	word			length;	
+	word			length;
 	unsigned short		ioaddr;
 	byte			* buf;
 
-	ioaddr = dev->base_addr;	
+	ioaddr = dev->base_addr;
 
 	if ( !skb ) {
 		PRINTK((CARDNAME": In XMIT with no packet to send \n"));
@@ -657,8 +657,8 @@
 	buf = skb->data;
 
 	/* If I get here, I _know_ there is a packet slot waiting for me */
-	packet_no = inb( ioaddr + PNR_ARR + 1 ); 
-	if ( packet_no & 0x80 ) { 
+	packet_no = inb( ioaddr + PNR_ARR + 1 );
+	if ( packet_no & 0x80 ) {
 		/* or isn't there?  BAD CHIP! */
 		printk(KERN_DEBUG CARDNAME": Memory allocation failed. \n");
 		kfree(skb);
@@ -670,7 +670,7 @@
 	/* we have a packet address, so tell the card to use it */
 	outb( packet_no, ioaddr + PNR_ARR );
 
-	/* point to the beginning of the packet */	
+	/* point to the beginning of the packet */
 	outw( PTR_AUTOINC , ioaddr + POINTER );
 
    	PRINTK3((CARDNAME": Trying to xmit packet of length %x\n", length ));
@@ -678,36 +678,36 @@
 	print_packet( buf, length );
 #endif
 
-	/* send the packet length ( +6 for status, length and ctl byte ) 
- 	   and the status word ( set to zeros ) */ 
+	/* send the packet length ( +6 for status, length and ctl byte )
+ 	   and the status word ( set to zeros ) */
 #ifdef USE_32_BIT
 	outl(  (length +6 ) << 16 , ioaddr + DATA_1 );
 #else
-	outw( 0, ioaddr + DATA_1 );	 
-	/* send the packet length ( +6 for status words, length, and ctl*/		
+	outw( 0, ioaddr + DATA_1 );
+	/* send the packet length ( +6 for status words, length, and ctl*/
 	outb( (length+6) & 0xFF,ioaddr + DATA_1 );
 	outb( (length+6) >> 8 , ioaddr + DATA_1 );
-#endif 
+#endif
 
-	/* send the actual data 
-	 . I _think_ it's faster to send the longs first, and then 
-	 . mop up by sending the last word.  It depends heavily 
- 	 . on alignment, at least on the 486.  Maybe it would be 
+	/* send the actual data
+	 . I _think_ it's faster to send the longs first, and then
+	 . mop up by sending the last word.  It depends heavily
+ 	 . on alignment, at least on the 486.  Maybe it would be
  	 . a good idea to check which is optimal?  But that could take
-	 . almost as much time as is saved? 
-	*/	
-#ifdef USE_32_BIT 
-	if ( length & 0x2  ) {	
-		outsl(ioaddr + DATA_1, buf,  length >> 2 ); 
+	 . almost as much time as is saved?
+	*/
+#ifdef USE_32_BIT
+	if ( length & 0x2  ) {
+		outsl(ioaddr + DATA_1, buf,  length >> 2 );
 		outw( *((word *)(buf + (length & 0xFFFFFFFC))),ioaddr +DATA_1);
 	}
 	else
-		outsl(ioaddr + DATA_1, buf,  length >> 2 ); 
+		outsl(ioaddr + DATA_1, buf,  length >> 2 );
 #else
 	outsw(ioaddr + DATA_1 , buf, (length ) >> 1);
 #endif
 	/* Send the last byte, if there is one.   */
-	
+
 	if ( (length & 1) == 0 ) {
 		outw( 0, ioaddr + DATA_1 );
 	} else {
@@ -721,7 +721,7 @@
 	/* and let the chipset deal with it */
 	outw( MC_ENQUEUE , ioaddr + MMU_CMD );
 
-	PRINTK2((CARDNAME": Sent packet of length %d \n",length)); 
+	PRINTK2((CARDNAME": Sent packet of length %d \n",length));
 
 	lp->saved_skb = NULL;
 	dev_kfree_skb (skb, FREE_WRITE);
@@ -737,38 +737,38 @@
 
 /*-------------------------------------------------------------------------
  |
- | smc_init( struct device * dev )  
- |   Input parameters: 
+ | smc_init( struct device * dev )
+ |   Input parameters:
  |	dev->base_addr == 0, try to find all possible locations
  |	dev->base_addr == 1, return failure code
  |	dev->base_addr == 2, always allocate space,  and return success
- |	dev->base_addr == <anything else>   this is the address to check 
+ |	dev->base_addr == <anything else>   this is the address to check
  |
- |   Output: 
+ |   Output:
  |	0 --> there is a device
- |	anything else, error 
- | 
+ |	anything else, error
+ |
  ---------------------------------------------------------------------------
-*/ 
+*/
 int smc_init(struct device *dev)
 {
 	int i;
 	int base_addr = dev ? dev->base_addr : 0;
 
 	/*  try a specific location */
-	if (base_addr > 0x1ff)	{		 
-		int	error; 
+	if (base_addr > 0x1ff)	{
+		int	error;
 		error = smc_probe(base_addr);
 		if ( 0 == error ) {
 			return smc_initcard( dev, base_addr );
 		}
-		return error; 
+		return error;
 	} else {
 		if ( 0 != base_addr ) {
 			return -ENXIO;
 		}
 	}
-	
+
 	/* check every ethernet address */
 	for (i = 0; smc_portlist[i]; i++) {
 		int ioaddr = smc_portlist[i];
@@ -778,8 +778,8 @@
 			continue;
 
 		/* check this specific address */
-		if ( smc_probe( ioaddr ) == 0)  {  
-			return smc_initcard( dev, ioaddr  ); 
+		if ( smc_probe( ioaddr ) == 0)  {
+			return smc_initcard( dev, ioaddr  );
 		}
 	}
 
@@ -789,19 +789,19 @@
 
 #ifndef NO_AUTOPROBE
 /*----------------------------------------------------------------------
- . smc_findirq 
- . 
- . This routine has a simple purpose -- make the SMC chip generate an 
+ . smc_findirq
+ .
+ . This routine has a simple purpose -- make the SMC chip generate an
  . interrupt, so an auto-detect routine can detect it, and find the IRQ,
  ------------------------------------------------------------------------
 */
-int smc_findirq( int ioaddr ) 
+int smc_findirq( int ioaddr )
 {
 	int	timeout = 20;
 
 
 	/* I have to do a STI() here, because this is called from
-	   a routine that does an CLI during this process, making it 
+	   a routine that does an CLI during this process, making it
 	   rather difficult to get interrupts for auto detection */
 	sti();
 
@@ -813,16 +813,16 @@
 	 * when done.
 	 */
 
-	  
-	SMC_SELECT_BANK(2);	
+
+	SMC_SELECT_BANK(2);
 	/* enable ALLOCation interrupts ONLY */
-	outb( IM_ALLOC_INT, ioaddr + INT_MASK );	
+	outb( IM_ALLOC_INT, ioaddr + INT_MASK );
 
 	/*
- 	 . Allocate 512 bytes of memory.  Note that the chip was just 
+ 	 . Allocate 512 bytes of memory.  Note that the chip was just
 	 . reset so all the memory is available
 	*/
-	outw( MC_ALLOC | 1, ioaddr + MMU_CMD );		
+	outw( MC_ALLOC | 1, ioaddr + MMU_CMD );
 
 	/*
 	 . Wait until positive that the interrupt has been generated
@@ -832,7 +832,7 @@
 
 		int_status = inb( ioaddr + INTERRUPT );
 
-		if ( int_status & IM_ALLOC_INT ) 	
+		if ( int_status & IM_ALLOC_INT )
 			break;		/* got the interrupt */
 		timeout--;
 	}
@@ -843,13 +843,13 @@
 
 	/* DELAY HERE!
 	   On a fast machine, the status might change before the interrupt
-	   is given to the processor.  This means that the interrupt was 
-	   never detected, and autoirq_report fails to report anything.  
-	   This should fix autoirq_* problems. 
+	   is given to the processor.  This means that the interrupt was
+	   never detected, and autoirq_report fails to report anything.
+	   This should fix autoirq_* problems.
 	*/
 	SMC_DELAY();
-	SMC_DELAY();		
-	
+	SMC_DELAY();
+
 	/* and disable all interrupts again */
 	outb( 0, ioaddr + INT_MASK );
 
@@ -858,29 +858,29 @@
 	cli();
 
 	/* and return what I found */
-	return autoirq_report( 0 );	
+	return autoirq_report( 0 );
 }
 #endif
- 
+
 /*----------------------------------------------------------------------
  . Function: smc_probe( int ioaddr )
- . 
- . Purpose:  
+ .
+ . Purpose:
  .	Tests to see if a given ioaddr points to an SMC9xxx chip.
- .	Returns a 0 on success 	
- . 
+ .	Returns a 0 on success
+ .
  . Algorithm:
  .	(1) see if the high byte of BANK_SELECT is 0x33
  . 	(2) compare the ioaddr with the base register's address
  .	(3) see if I recognize the chip ID in the appropriate register
- . 
+ .
  .---------------------------------------------------------------------
- */ 
+ */
 
-static int smc_probe( int ioaddr ) 
+static int smc_probe( int ioaddr )
 {
 	unsigned int	bank;
-	word	revision_register;	
+	word	revision_register;
 	word  base_address_register;
 
 	/* First, see if the high byte is 0x33 */
@@ -896,12 +896,12 @@
 		return -ENODEV;
 	}
 	/* well, we've already written once, so hopefully another time won't
- 	   hurt.  This time, I need to switch the bank register to bank 1, 
+ 	   hurt.  This time, I need to switch the bank register to bank 1,
 	   so I can access the base address register */
 	SMC_SELECT_BANK(1);
 	base_address_register = inw( ioaddr + BASE );
 	if ( ioaddr != ( base_address_register >> 3 & 0x3E0 ) )  {
-		printk(CARDNAME ": IOADDR %x doesn't match configuration (%x)." 
+		printk(CARDNAME ": IOADDR %x doesn't match configuration (%x)."
 			"Probably not a SMC chip\n",
 			ioaddr, base_address_register >> 3 & 0x3E0 );
 		/* well, the base address register didn't match.  Must not have
@@ -909,12 +909,12 @@
 		return -ENODEV;
 	}
 
-	/*  check if the revision register is something that I recognize.  
-	    These might need to be added to later, as future revisions 
+	/*  check if the revision register is something that I recognize.
+	    These might need to be added to later, as future revisions
 	    could be added.  */
 	SMC_SELECT_BANK(3);
 	revision_register  = inw( ioaddr + REVISION );
-	if ( !chip_ids[ ( revision_register  >> 4 ) & 0xF  ] ) { 
+	if ( !chip_ids[ ( revision_register  >> 4 ) & 0xF  ] ) {
 		/* I don't recognize this chip, so... */
 		printk(CARDNAME ": IO %x: Unrecognized revision register:"
 			" %x, Contact author. \n", ioaddr, revision_register );
@@ -922,24 +922,24 @@
 		return -ENODEV;
 	}
 
-	/* at this point I'll assume that the chip is an SMC9xxx.   
-	   It might be prudent to check a listing of MAC addresses 
-	   against the hardware address, or do some other tests. */ 	
+	/* at this point I'll assume that the chip is an SMC9xxx.
+	   It might be prudent to check a listing of MAC addresses
+	   against the hardware address, or do some other tests. */
 	return 0;
 }
 
 /*---------------------------------------------------------------
- . Here I do typical initialization tasks. 
- . 
+ . Here I do typical initialization tasks.
+ .
  . o  Initialize the structure if needed
  . o  print out my vanity message if not done so already
  . o  print out what type of hardware is detected
  . o  print out the ethernet address
- . o  find the IRQ 
- . o  set up my private data 
+ . o  find the IRQ
+ . o  set up my private data
  . o  configure the dev structure with my subroutines
  . o  actually GRAB the irq.
- . o  GRAB the region 
+ . o  GRAB the region
  .-----------------------------------------------------------------
 */
 static int  smc_initcard(struct device *dev, int ioaddr)
@@ -949,8 +949,8 @@
 	static unsigned version_printed = 0;
 
 	/* registers */
-	word	revision_register;	
-	word	configuration_register;	
+	word	revision_register;
+	word	configuration_register;
 	word  	memory_info_register;
 	word 	memory_cfg_register;
 
@@ -966,10 +966,10 @@
 #ifndef MODULE
 /* note: the old module interface does not support this call */
 		dev = init_etherdev( 0, sizeof( struct smc_local ), 0 );
-#endif 
+#endif
 #else
 		dev = init_etherdev(0, 0);
-#endif 
+#endif
 		if (dev == NULL)
 			return -ENOMEM;
 	}
@@ -984,12 +984,12 @@
  	 . Get the MAC address ( bank 1, regs 4 - 9 )
 	*/
 	SMC_SELECT_BANK( 1 );
-	for ( i = 0; i < 6; i += 2 ) { 
+	for ( i = 0; i < 6; i += 2 ) {
 		word	address;
 
 		address = inw( ioaddr + ADDR0 + i  );
 		dev->dev_addr[ i + 1] = address >> 8;
-		dev->dev_addr[ i ] = address & 0xFF;	
+		dev->dev_addr[ i ] = address & 0xFF;
 	}
 
 	/* get the memory information */
@@ -1000,16 +1000,16 @@
 	memory = ( memory_cfg_register >> 9 )  & 0x7;  /* multiplier */
 	memory *= 256 * ( memory_info_register & 0xFF );
 
-	/* 
+	/*
 	 Now, I want to find out more about the chip.  This is sort of
  	 redundant, but it's cleaner to have it in both, rather than having
  	 one VERY long probe procedure.
-	*/	
+	*/
 	SMC_SELECT_BANK(3);
 	revision_register  = inw( ioaddr + REVISION );
 	version_string = chip_ids[ ( revision_register  >> 4 ) & 0xF  ];
 	if ( !version_string ) {
-		/* I shouldn't get here because this call was done before.... */ 
+		/* I shouldn't get here because this call was done before.... */
 		return -ENODEV;
 	}
 
@@ -1017,7 +1017,7 @@
 	if ( dev->if_port == 0 ) {
 		SMC_SELECT_BANK(1);
 		configuration_register = inw( ioaddr + CONFIG );
-		if ( configuration_register & CFG_AUI_SELECT )  
+		if ( configuration_register & CFG_AUI_SELECT )
 			dev->if_port = 2;
 		else
 			dev->if_port = 1;
@@ -1029,17 +1029,17 @@
 
 	/*
 	 . If dev->irq is 0, then the device has to be banged on to see
-	 . what the IRQ is. 
- 	 . 
+	 . what the IRQ is.
+ 	 .
 	 . This banging doesn't always detect the IRQ, for unknown reasons.
-	 . a workaround is to reset the chip and try again.  
-	 .    
+	 . a workaround is to reset the chip and try again.
+	 .
 	 . Interestingly, the DOS packet driver *SETS* the IRQ on the card to
 	 . be what is requested on the command line.   I don't do that, mostly
 	 . because the card that I have uses a non-standard method of accessing
 	 . the IRQs, and because this _should_ work in most configurations.
 	 .
-	 . Specifying an IRQ is done with the assumption that the user knows 
+	 . Specifying an IRQ is done with the assumption that the user knows
 	 . what (s)he is doing.  No checking is done!!!!
  	 .
 	*/
@@ -1048,14 +1048,14 @@
 		int	trials;
 
 		trials = 3;
-		while ( trials-- ) { 
+		while ( trials-- ) {
 			dev->irq = smc_findirq( ioaddr );
-			if ( dev->irq ) 
+			if ( dev->irq )
 				break;
 			/* kick the card and try again */
 			smc_reset( ioaddr );
 		}
-	} 
+	}
 	if (dev->irq == 0 ) {
 		printk(CARDNAME": Couldn't autodetect your IRQ. Use irq=xx.\n");
 		return -ENODEV;
@@ -1075,12 +1075,12 @@
 	}
 
 	/* now, print out the card info, in a short format.. */
-	
+
 	printk(CARDNAME ": %s(r:%d) at %#3x IRQ:%d INTF:%s MEM:%db ",
-		version_string, revision_register & 0xF, ioaddr, dev->irq, 
+		version_string, revision_register & 0xF, ioaddr, dev->irq,
 		if_string, memory );
 	/*
-	 . Print the Ethernet address 
+	 . Print the Ethernet address
 	*/
 	printk("ADDR: ");
 	for (i = 0; i < 5; i++)
@@ -1124,21 +1124,21 @@
 }
 
 #if SMC_DEBUG > 2
-static void print_packet( byte * buf, int length ) 
-{ 
+static void print_packet( byte * buf, int length )
+{
 #if 0
 	int i;
 	int remainder;
 	int lines;
-	
+
 	printk("Packet of length %d \n", length );
 	lines = length / 16;
 	remainder = length % 16;
 
-	for ( i = 0; i < lines ; i ++ ) { 
+	for ( i = 0; i < lines ; i ++ ) {
 		int cur;
 
-		for ( cur = 0; cur < 8; cur ++ ) { 
+		for ( cur = 0; cur < 8; cur ++ ) {
 			byte a, b;
 
 			a = *(buf ++ );
@@ -1157,12 +1157,12 @@
 	printk("\n");
 #endif
 }
-#endif	
+#endif
 
 
 /*
  * Open and Initialize the board
- * 
+ *
  * Set up everything, reset the card, etc ..
  *
  */
@@ -1170,7 +1170,7 @@
 {
 	int	ioaddr = dev->base_addr;
 
-	int	i;	/* used to set hw ethernet address */ 
+	int	i;	/* used to set hw ethernet address */
 
 	/* clear out all the junk that was put here before... */
 	memset(dev->priv, 0, sizeof(struct smc_local));
@@ -1188,26 +1188,26 @@
 	smc_enable( ioaddr );
 
 	/* Select which interface to use */
- 	 
+
 	SMC_SELECT_BANK( 1 );
-	if ( dev->if_port == 1 ) { 	
-		outw( inw( ioaddr + CONFIG ) & ~CFG_AUI_SELECT, 
-			ioaddr + CONFIG );							
-	} 
-	else if ( dev->if_port == 2 ) { 
-		outw( inw( ioaddr + CONFIG ) | CFG_AUI_SELECT, 
-			ioaddr + CONFIG );							
+	if ( dev->if_port == 1 ) {
+		outw( inw( ioaddr + CONFIG ) & ~CFG_AUI_SELECT,
+			ioaddr + CONFIG );
+	}
+	else if ( dev->if_port == 2 ) {
+		outw( inw( ioaddr + CONFIG ) | CFG_AUI_SELECT,
+			ioaddr + CONFIG );
 	}
 
 	/*
   		According to Becker, I have to set the hardware address
 		at this point, because the (l)user can set it with an
-		ioctl.  Easily done... 
+		ioctl.  Easily done...
 	*/
 	SMC_SELECT_BANK( 1 );
-	for ( i = 0; i < 6; i += 2 ) { 
+	for ( i = 0; i < 6; i += 2 ) {
 		word	address;
-		
+
 		address = dev->dev_addr[ i + 1 ] << 8 ;
 		address  |= dev->dev_addr[ i ];
 		outw( address, ioaddr + ADDR0 + i );
@@ -1217,8 +1217,8 @@
 
 /*--------------------------------------------------------
  . Called by the kernel to send a packet out into the void
- . of the net.  This routine is largely based on 
- . skeleton.c, from Becker.   
+ . of the net.  This routine is largely based on
+ . skeleton.c, from Becker.
  .--------------------------------------------------------
 */
 static int smc_send_packet(struct sk_buff *skb, struct device *dev)
@@ -1230,7 +1230,7 @@
 		if (tickssofar < 5)
 			return 1;
 		printk(KERN_WARNING CARDNAME": transmit timed out, %s?\n",
-			tx_done(dev) ? "IRQ conflict" : 
+			tx_done(dev) ? "IRQ conflict" :
 			"network cable problem");
 		/* "kick" the adaptor */
 		smc_reset( dev->base_addr );
@@ -1256,8 +1256,8 @@
 		printk(KERN_WARNING CARDNAME": Transmitter access conflict.\n");
 		dev_kfree_skb (skb, FREE_WRITE);
 	} else {
-		/* Well, I want to send the packet.. but I don't know 
-		   if I can send it right now...  */	
+		/* Well, I want to send the packet.. but I don't know
+		   if I can send it right now...  */
 		return smc_wait_to_send_packet( skb, dev );
 	}
 	return 0;
@@ -1270,16 +1270,16 @@
  .
  . So:
  .   first, save state of the chipset
- .   branch off into routines to handle each case, and acknowledge 
+ .   branch off into routines to handle each case, and acknowledge
  .	    each to the interrupt register
- .   and finally restore state. 
- .  
+ .   and finally restore state.
+ .
  ---------------------------------------------------------------------*/
 #ifdef REALLY_NEW_KERNEL
 static void smc_interrupt(int irq, void * dev_id,  struct pt_regs * regs)
-#else 
+#else
 static void smc_interrupt(int irq, struct pt_regs * regs)
-#endif 
+#endif
 {
 	struct device *dev 	= (struct device *)(irq2dev_map[irq]);
 	int ioaddr 		= dev->base_addr;
@@ -1294,21 +1294,21 @@
 	word	saved_pointer;
 
 
-	
+
 	PRINTK3((CARDNAME": SMC interrupt started \n"));
 
 	if (dev == NULL) {
-		printk(KERN_WARNING  CARDNAME": irq %d for unknown device.\n", 
+		printk(KERN_WARNING  CARDNAME": irq %d for unknown device.\n",
 			irq);
 		return;
 	}
 
 /* will Linux let this happen ??  If not, this costs some speed */
-	if ( dev->interrupt ) { 
+	if ( dev->interrupt ) {
 		printk(KERN_WARNING CARDNAME": interrupt inside interrupt.\n");
 		return;
 	}
-		
+
 	dev->interrupt = 1;
 
 	saved_bank = inw( ioaddr + BANK_SELECT );
@@ -1325,14 +1325,14 @@
 	timeout = 4;
 
 	PRINTK2((KERN_WARNING CARDNAME ": MASK IS %x \n", mask ));
-	do { 	
+	do {
 		/* read the status flag, and mask it */
 		status = inb( ioaddr + INTERRUPT ) & mask;
 		if (!status )
 			break;
 
 		PRINTK3((KERN_WARNING CARDNAME
-			": Handling interrupt status %x \n", status )); 
+			": Handling interrupt status %x \n", status ));
 
 		if (status & IM_RCV_INT) {
 			/* Got a packet(s). */
@@ -1343,7 +1343,7 @@
 			PRINTK2((KERN_WARNING CARDNAME
 				": TX ERROR handled\n"));
 			smc_tx(dev);
-			outb(IM_TX_INT, ioaddr + INTERRUPT ); 
+			outb(IM_TX_INT, ioaddr + INTERRUPT );
 		} else if (status & IM_TX_EMPTY_INT ) {
 			/* update stats */
 			SMC_SELECT_BANK( 0 );
@@ -1355,14 +1355,14 @@
 			lp->stats.collisions += card_stats & 0xF;
 
 			/* these are for when linux supports these statistics */
-#if 0 
+#if 0
 			card_stats >>= 4;
 			/* deferred */
 			card_stats >>= 4;
 			/* excess deferred */
-#endif 
+#endif
 			SMC_SELECT_BANK( 2 );
-			PRINTK2((KERN_WARNING CARDNAME 
+			PRINTK2((KERN_WARNING CARDNAME
 				": TX_BUFFER_EMPTY handled\n"));
 			outb( IM_TX_EMPTY_INT, ioaddr + INTERRUPT );
 			mask &= ~IM_TX_EMPTY_INT;
@@ -1374,19 +1374,19 @@
 				": Allocation interrupt \n"));
 			/* clear this interrupt so it doesn't happen again */
 			mask &= ~IM_ALLOC_INT;
-		
+
 			smc_hardware_send_packet( dev );
-			
+
 			/* enable xmit interrupts based on this */
 			mask |= ( IM_TX_EMPTY_INT | IM_TX_INT );
 
 			/* and let the card send more packets to me */
 			mark_bh( NET_BH );
 
-			PRINTK2((CARDNAME": Handoff done successfully.\n"));	
+			PRINTK2((CARDNAME": Handoff done successfully.\n"));
 		} else if (status & IM_RX_OVRN_INT ) {
 			lp->stats.rx_errors++;
-			lp->stats.rx_fifo_errors++;			
+			lp->stats.rx_fifo_errors++;
 			outb( IM_RX_OVRN_INT, ioaddr + INTERRUPT );
 		} else if (status & IM_EPH_INT ) {
 			PRINTK((CARDNAME ": UNSUPPORTED: EPH INTERRUPT \n"));
@@ -1394,13 +1394,13 @@
 			PRINTK((CARDNAME ": UNSUPPORTED: ERCV INTERRUPT \n"));
 			outb( IM_ERCV_INT, ioaddr + INTERRUPT );
 		}
-	} while ( timeout -- ); 
+	} while ( timeout -- );
+
 
-	
 	/* restore state register */
 	SMC_SELECT_BANK( 2 );
 	outb( mask, ioaddr + INT_MASK );
-	
+
 	PRINTK3(( KERN_WARNING CARDNAME ": MASK is now %x \n", mask ));
 	outw( saved_pointer, ioaddr + POINTER );
 
@@ -1417,10 +1417,10 @@
  .
  . There is ( at least ) a packet waiting to be read from
  . chip-memory.
- . 
- . o Read the status 
- . o If an error, record it  
- . o otherwise, read in the packet 
+ .
+ . o Read the status
+ . o If an error, record it
+ . o otherwise, read in the packet
  --------------------------------------------------------------
 */
 static void smc_rcv(struct device *dev)
@@ -1429,8 +1429,8 @@
 	int 	ioaddr = dev->base_addr;
 	int 	packet_number;
 	word	status;
-	word	packet_length; 
-	
+	word	packet_length;
+
 	/* assume bank 2 */
 
 	packet_number = inw( ioaddr + FIFO_PORTS );
@@ -1441,51 +1441,51 @@
 		/* don't need to restore anything */
 		return;
 	}
-		
+
 	/*  start reading from the start of the packet */
 	outw( PTR_READ | PTR_RCV | PTR_AUTOINC, ioaddr + POINTER );
 
-	/* First two words are status and packet_length */	
+	/* First two words are status and packet_length */
 	status 		= inw( ioaddr + DATA_1 );
 	packet_length 	= inw( ioaddr + DATA_1 );
-	
+
 	packet_length &= 0x07ff;  /* mask off top bits */
 
 	PRINTK2(("RCV: STATUS %4x LENGTH %4x\n", status, packet_length ));
-	/* 
-	 . the packet length contains 3 extra words : 
+	/*
+	 . the packet length contains 3 extra words :
 	 . status, length, and an extra word with an odd byte .
 	*/
-	packet_length -= 6; 
-	
-	if ( !(status & RS_ERRORS ) ){			
+	packet_length -= 6;
+
+	if ( !(status & RS_ERRORS ) ){
 		/* do stuff to make a new packet */
 		struct sk_buff  * skb;
 		byte		* data;
 
 		/* read one extra byte */
-		if ( status & RS_ODDFRAME ) 	
-			packet_length++; 	
+		if ( status & RS_ODDFRAME )
+			packet_length++;
 
-		/* set multicast stats */ 
+		/* set multicast stats */
 		if ( status & RS_MULTICAST )
 			lp->stats.multicast++;
 
 #ifdef SUPPORT_OLD_KERNEL
 		skb = alloc_skb( packet_length + 5, GFP_ATOMIC );
-#else	
-		skb = dev_alloc_skb( packet_length + 5); 
+#else
+		skb = dev_alloc_skb( packet_length + 5);
 #endif
 
-		if ( skb == NULL ) {	
+		if ( skb == NULL ) {
 			printk(KERN_NOTICE CARDNAME
 			": Low memory, packet dropped.\n");
 			lp->stats.rx_dropped++;
 		}
 
-		/* 
+		/*
 		 ! This should work without alignment, but it could be
-		 ! in the worse case 
+		 ! in the worse case
 		*/
 #ifndef SUPPORT_OLD_KERNEL
 		/* TODO: Should I use 32bit alignment here ? */
@@ -1500,42 +1500,42 @@
 		data = skb_put( skb, packet_length);
 #endif
 #ifdef USE_32_BIT
-		/* QUESTION:  Like in the TX routine, do I want 		
+		/* QUESTION:  Like in the TX routine, do I want
 		   to send the DWORDs or the bytes first, or some
 		   mixture.  A mixture might improve already slow PIO
 		   performance  */
-		PRINTK3((" Reading %d dwords (and %d bytes) \n", 
+		PRINTK3((" Reading %d dwords (and %d bytes) \n",
 			packet_length >> 2, packet_length & 3 ));
-		insl(ioaddr + DATA_1 , data, packet_length >> 2 ); 
+		insl(ioaddr + DATA_1 , data, packet_length >> 2 );
 		/* read the left over bytes */
-		insb( ioaddr + DATA_1, data + (packet_length & 0xFFFFFC), 
+		insb( ioaddr + DATA_1, data + (packet_length & 0xFFFFFC),
 			packet_length & 0x3  );
 #else
-		PRINTK3((" Reading %d words and %d byte(s) \n", 
+		PRINTK3((" Reading %d words and %d byte(s) \n",
 			(packet_length >> 1 ), packet_length & 1 );
-		if ( packet_length & 1 ) 
-			*(data++) = inb( ioaddr + DATA_1 ); 
+		if ( packet_length & 1 )
+			*(data++) = inb( ioaddr + DATA_1 );
 		insw(ioaddr + DATA_1 , data, (packet_length + 1 ) >> 1);
 		if ( packet_length & 1 ) {
 			data += packet_length & ~1;
-			*((data++) = inb( ioaddr + DATA_1 ); 
+			*((data++) = inb( ioaddr + DATA_1 );
 		}
-#endif 		
-#if	SMC_DEBUG > 2 	
+#endif
+#if	SMC_DEBUG > 2
 			print_packet( data, packet_length );
 #endif
 
 #ifndef SUPPORT_OLD_KERNEL
-		skb->protocol = eth_type_trans(skb, dev ); 
+		skb->protocol = eth_type_trans(skb, dev );
 #endif
 		netif_rx(skb);
 		lp->stats.rx_packets++;
 	} else {
 		/* error ... */
 		lp->stats.rx_errors++;
-			
-		if ( status & RS_ALGNERR )  lp->stats.rx_frame_errors++;  
-		if ( status & (RS_TOOSHORT | RS_TOOLONG ) )  
+
+		if ( status & RS_ALGNERR )  lp->stats.rx_frame_errors++;
+		if ( status & (RS_TOOSHORT | RS_TOOLONG ) )
 			lp->stats.rx_length_errors++;
 		if ( status & RS_BADCRC)	lp->stats.rx_crc_errors++;
 	}
@@ -1547,22 +1547,22 @@
 }
 
 
-/************************************************************************* 
+/*************************************************************************
  . smc_tx
- . 
+ .
  . Purpose:  Handle a transmit error message.   This will only be called
- .   when an error, because of the AUTO_RELEASE mode. 
- . 
+ .   when an error, because of the AUTO_RELEASE mode.
+ .
  . Algorithm:
  .	Save pointer and packet no
  .	Get the packet no from the top of the queue
  .	check if it's valid ( if not, is this an error??? )
- .	read the status word 
+ .	read the status word
  .	record the error
  .	( resend?  Not really, since we don't want old packets around )
- .	Restore saved values 
- ************************************************************************/ 
-static void smc_tx( struct device * dev ) 
+ .	Restore saved values
+ ************************************************************************/
+static void smc_tx( struct device * dev )
 {
 	int	ioaddr = dev->base_addr;
 	struct smc_local *lp = (struct smc_local *)dev->priv;
@@ -1578,46 +1578,46 @@
 	packet_no &= 0x7F;
 
 	/* select this as the packet to read from */
-	outb( packet_no, ioaddr + PNR_ARR ); 
-	
-	/* read the first word from this packet */	
+	outb( packet_no, ioaddr + PNR_ARR );
+
+	/* read the first word from this packet */
 	outw( PTR_AUTOINC | PTR_READ, ioaddr + POINTER );
 
 	tx_status = inw( ioaddr + DATA_1 );
 	PRINTK3((CARDNAME": TX DONE STATUS: %4x \n", tx_status ));
-	
+
 	lp->stats.tx_errors++;
 	if ( tx_status & TS_LOSTCAR ) lp->stats.tx_carrier_errors++;
 	if ( tx_status & TS_LATCOL  ) {
-		printk(KERN_DEBUG CARDNAME 
+		printk(KERN_DEBUG CARDNAME
 			": Late collision occurred on last xmit.\n");
 		lp->stats.tx_window_errors++;
 	}
 #if 0
 		if ( tx_status & TS_16COL ) { ... }
-#endif 
+#endif
 
-	if ( tx_status & TS_SUCCESS ) {  
+	if ( tx_status & TS_SUCCESS ) {
 		printk(CARDNAME": Successful packet caused interrupt \n");
-	} 
+	}
 	/* re-enable transmit */
 	SMC_SELECT_BANK( 0 );
 	outw( inw( ioaddr + TCR ) | TCR_ENABLE, ioaddr + TCR );
 
-	/* kill the packet */			
+	/* kill the packet */
 	SMC_SELECT_BANK( 2 );
 	outw( MC_FREEPKT, ioaddr + MMU_CMD );
 
 	/* one less packet waiting for me */
 	lp->packets_waiting--;
-		
+
 	outb( saved_packet, ioaddr + PNR_ARR );
 	return;
 }
 
 /*----------------------------------------------------
  . smc_close
- . 
+ .
  . this makes the board clean up everything that it can
  . and not talk to the outside world.   Caused by
  . an 'ifconfig ethX down'
@@ -1640,8 +1640,8 @@
 }
 
 /*------------------------------------------------------------
- . Get the current statistics.	
- . This may be called with the card open or closed. 
+ . Get the current statistics.
+ . This may be called with the card open or closed.
  .-------------------------------------------------------------*/
 static struct enet_statistics * smc_query_statistics(struct device *dev) {
 	struct smc_local *lp = (struct smc_local *)dev->priv;
@@ -1651,52 +1651,52 @@
 
 /*-----------------------------------------------------------
  . smc_set_multicast_list
- .  
+ .
  . This routine will, depending on the values passed to it,
- . either make it accept multicast packets, go into 
+ . either make it accept multicast packets, go into
  . promiscuous mode ( for TCPDUMP and cousins ) or accept
- . a select set of multicast packets  
+ . a select set of multicast packets
 */
 #ifdef SUPPORT_OLD_KERNEL
-static void smc_set_multicast_list( struct device * dev, 
-			int num_addrs, void * addrs ) 	
+static void smc_set_multicast_list( struct device * dev,
+			int num_addrs, void * addrs )
 #else
-static void smc_set_multicast_list(struct device *dev) 
-#endif 
+static void smc_set_multicast_list(struct device *dev)
+#endif
 {
 	short ioaddr = dev->base_addr;
 
 	SMC_SELECT_BANK(0);
 #ifdef  SUPPORT_OLD_KERNEL
-	if ( num_addrs < 0 )  
+	if ( num_addrs < 0 )
 #else
-	if ( dev->flags & IFF_PROMISC ) 
-#endif 
+	if ( dev->flags & IFF_PROMISC )
+#endif
 		outw( inw(ioaddr + RCR ) | RCR_PROMISC, ioaddr + RCR );
 
-/* BUG?  I never disable promiscuous mode if multicasting was turned on. 
+/* BUG?  I never disable promiscuous mode if multicasting was turned on.
    Now, I turn off promiscuous mode, but I don't do anything to multicasting
-   when promiscuous mode is turned on. 
+   when promiscuous mode is turned on.
 */
 
-	/* Here, I am setting this to accept all multicast packets.  
+	/* Here, I am setting this to accept all multicast packets.
 	   I don't need to zero the multicast table, because the flag is
-	   checked before the table is 
+	   checked before the table is
 	*/
-#ifdef  SUPPORT_OLD_KERNEL 
+#ifdef  SUPPORT_OLD_KERNEL
 	else if ( num_addrs > 20 )	/* arbitrary constant */
 #else
-	else if (dev->flags & IFF_ALLMULTI)  
-#endif 
-		outw( inw(ioaddr + RCR ) | RCR_ALMUL, ioaddr + RCR ); 
+	else if (dev->flags & IFF_ALLMULTI)
+#endif
+		outw( inw(ioaddr + RCR ) | RCR_ALMUL, ioaddr + RCR );
 
 	/* We just get all multicast packets even if we only want them
 	 . from one source.  This will be changed at some future
 	 . point. */
 #ifdef  SUPPORT_OLD_KERNEL
-	else if (num_addrs > 0 ) { 
+	else if (num_addrs > 0 ) {
 /* the old kernel support will not have hardware multicast support. It would
-   involve more kludges, and make the multicast setting code even worse.  
+   involve more kludges, and make the multicast setting code even worse.
    Instead, just use the ALMUL method.   This is reasonable, considering that
    it is seldom used
 */
@@ -1704,11 +1704,11 @@
 		outw( inw( ioadddr + RCR ) | RCR_ALMUL, ioadddr + RCR );
 	}
 #else
-	else if (dev->mc_count )  { 
+	else if (dev->mc_count )  {
 		/* support hardware multicasting */
-		
-		/* be sure I get rid of flags I might have set */	
-		outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL), 
+
+		/* be sure I get rid of flags I might have set */
+		outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL),
 			ioaddr + RCR );
 		/* NOTE: this has to set the bank, so make sure it is the
 		   last thing called.  The bank is set to zero at the top */
@@ -1716,18 +1716,18 @@
 	}
 #endif
 	else  {
-		outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL), 
+		outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL),
 			ioaddr + RCR );
 
-		/* 
-		  since I'm disabling all multicast entirely, I need to 
-		  clear the multicast list 
+		/*
+		  since I'm disabling all multicast entirely, I need to
+		  clear the multicast list
 		*/
 		SMC_SELECT_BANK( 3 );
-		outw( 0, ioaddr + MULTICAST1 ); 
-		outw( 0, ioaddr + MULTICAST2 ); 
-		outw( 0, ioaddr + MULTICAST3 ); 
-		outw( 0, ioaddr + MULTICAST4 ); 
+		outw( 0, ioaddr + MULTICAST1 );
+		outw( 0, ioaddr + MULTICAST2 );
+		outw( 0, ioaddr + MULTICAST3 );
+		outw( 0, ioaddr + MULTICAST4 );
 	}
 }
 
@@ -1744,12 +1744,16 @@
 int irq = 0;
 int ifport = 0;
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(ifport, "i");
+
 int init_module(void)
 {
 	int result;
 
 	if (io == 0)
-		printk(KERN_WARNING 
+		printk(KERN_WARNING
 		CARDNAME": You shouldn't use auto-probing with insmod!\n" );
 
 	/* copy the parameters from insmod into the device structure */
@@ -1776,4 +1780,3 @@
 }
 
 #endif /* MODULE */
-
diff -u --recursive --new-file v2.1.18/linux/drivers/net/soundmodem.c linux/drivers/net/soundmodem.c
--- v2.1.18/linux/drivers/net/soundmodem.c	Sun Dec 22 16:37:35 1996
+++ linux/drivers/net/soundmodem.c	Tue Dec 31 10:30:04 1996
@@ -25,7 +25,7 @@
  *
  *
  *  Command line options (insmod command line)
- * 
+ *
  *  hardware hardware type; 0=sbc, 1=wss, any other value invalid
  *  mode     mode type; 0=1200 baud AFSK, 1=9600 baud FSK, any other
  *           value invalid
@@ -33,7 +33,7 @@
  *           0x530 for wss
  *  irq      interrupt number; common values are 7 or 5 for sbc, 11 for wss
  *  dma      dma number; common values are 0 or 1
- * 
+ *
  *
  *  History:
  *   0.1  21.09.96  Started
@@ -83,8 +83,8 @@
 static struct {
 	char *mode;
 	int iobase, irq, dma, dma2, seriobase, pariobase, midiiobase;
-} sm_ports[NR_PORTS] = { 
-	{ NULL, -1, 0, 0, 0, -1, -1, -1 }, 
+} sm_ports[NR_PORTS] = {
+	{ NULL, -1, 0, 0, 0, -1, -1, -1 },
 };
 
 /* --------------------------------------------------------------------- */
@@ -138,7 +138,7 @@
 
 /* ---------------------------------------------------------------------- */
 /*
- * Information that need to be kept for each board. 
+ * Information that need to be kept for each board.
  */
 
 struct sm_state {
@@ -155,7 +155,7 @@
 	union {
 		long hw[32/sizeof(long)];
 	} hw;
-	
+
 	/*
 	 * state of the modem code
 	 */
@@ -165,7 +165,7 @@
 	union {
 		long d[256/sizeof(long)];
 	} d;
-	
+
 #define DIAGDATALEN 64
 	struct diag_data {
 		unsigned int mode;
@@ -174,7 +174,7 @@
 		short data[DIAGDATALEN];
 	} diag;
 
-	
+
 #ifdef SM_DEBUG
 	struct debug_vals {
 		unsigned long last_jiffies;
@@ -235,7 +235,7 @@
 	 */
 	int (*open)(struct device *, struct sm_state *);
 	int (*close)(struct device *, struct sm_state *);
-	int (*ioctl)(struct device *, struct sm_state *, struct ifreq *, 
+	int (*ioctl)(struct device *, struct sm_state *, struct ifreq *,
 		     struct hdlcdrv_ioctl *, int);
 	int (*sethw)(struct device *, struct sm_state *, char *);
 };
@@ -254,7 +254,7 @@
 {
 #ifdef SM_DEBUG
 	unsigned long cur_jiffies = jiffies;
-	/* 
+	/*
 	 * measure the interrupt frequency
 	 */
 	sm->debug_vals.cur_intcnt++;
@@ -320,7 +320,7 @@
 	b3 = inb(UART_MSR(iobase)) & 0xf0;
 	outb(b1, UART_MCR(iobase));	   /* restore old values */
 	outb(b2, UART_MSR(iobase));
-	if (b3 != 0x90) 
+	if (b3 != 0x90)
 		return c_uart_unknown;
 	inb(UART_RBR(iobase));
 	inb(UART_RBR(iobase));
@@ -331,7 +331,7 @@
 		b1 = inb(UART_SCR(iobase));
 		outb(0xa5, UART_SCR(iobase));
 		b2 = inb(UART_SCR(iobase));
-		if ((b1 != 0x5a) || (b2 != 0xa5)) 
+		if ((b1 != 0x5a) || (b2 != 0xa5))
 			u = c_uart_8250;
 	}
 	return u;
@@ -395,29 +395,29 @@
 	enum uart u = c_uart_unknown;
 
 	sm->hdrv.ptt_out.flags = 0;
-	if (sm->hdrv.ptt_out.seriobase > 0 && 
+	if (sm->hdrv.ptt_out.seriobase > 0 &&
 	    sm->hdrv.ptt_out.seriobase <= 0x1000-SER_EXTENT &&
 	    ((u = check_uart(sm->hdrv.ptt_out.seriobase))) != c_uart_unknown) {
 		sm->hdrv.ptt_out.flags |= SP_SER;
 		request_region(sm->hdrv.ptt_out.seriobase, SER_EXTENT, "sm ser ptt");
 		outb(0, UART_IER(sm->hdrv.ptt_out.seriobase));
 		/* 5 bits, 1 stop, no parity, no break, Div latch access */
-		outb(0x80, UART_LCR(sm->hdrv.ptt_out.seriobase)); 
+		outb(0x80, UART_LCR(sm->hdrv.ptt_out.seriobase));
 		outb(0, UART_DLM(sm->hdrv.ptt_out.seriobase));
 		outb(1, UART_DLL(sm->hdrv.ptt_out.seriobase)); /* as fast as possible */
 		/* LCR and MCR set by output_status */
 	}
-	if (sm->hdrv.ptt_out.pariobase > 0 && 
+	if (sm->hdrv.ptt_out.pariobase > 0 &&
 	    sm->hdrv.ptt_out.pariobase <= 0x1000-LPT_EXTENT &&
 	    check_lpt(sm->hdrv.ptt_out.pariobase)) {
 		sm->hdrv.ptt_out.flags |= SP_PAR;
 		request_region(sm->hdrv.ptt_out.pariobase, LPT_EXTENT, "sm par ptt");
 	}
-	if (sm->hdrv.ptt_out.midiiobase > 0 && 
+	if (sm->hdrv.ptt_out.midiiobase > 0 &&
 	    sm->hdrv.ptt_out.midiiobase <= 0x1000-MIDI_EXTENT &&
 	    check_midi(sm->hdrv.ptt_out.midiiobase)) {
 		sm->hdrv.ptt_out.flags |= SP_MIDI;
-		request_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT, 
+		request_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT,
 			       "sm midi ptt");
 	}
 	output_status(sm);
@@ -444,9 +444,9 @@
 	output_status(sm);
 	if (sm->hdrv.ptt_out.flags & SP_SER)
 		release_region(sm->hdrv.ptt_out.seriobase, SER_EXTENT);
-       	if (sm->hdrv.ptt_out.flags & SP_PAR) 
+       	if (sm->hdrv.ptt_out.flags & SP_PAR)
 		release_region(sm->hdrv.ptt_out.pariobase, LPT_EXTENT);
-       	if (sm->hdrv.ptt_out.flags & SP_MIDI) 
+       	if (sm->hdrv.ptt_out.flags & SP_MIDI)
 		release_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT);
 	sm->hdrv.ptt_out.flags = 0;
 }
@@ -458,7 +458,7 @@
 
 extern inline void diag_trigger(struct sm_state *sm)
 {
-	if (sm->diag.ptr < 0) 
+	if (sm->diag.ptr < 0)
 		if (!(sm->diag.flags & SM_DIAGFLAG_DCDGATE) || sm->hdrv.hdlcrx.dcd)
 			sm->diag.ptr = 0;
 }
@@ -469,8 +469,8 @@
 {
 	int val;
 
-	if ((sm->diag.mode != SM_DIAGMODE_INPUT && 
-	     sm->diag.mode != SM_DIAGMODE_DEMOD) || 
+	if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
+	     sm->diag.mode != SM_DIAGMODE_DEMOD) ||
 	    sm->diag.ptr >= DIAGDATALEN || sm->diag.ptr < 0)
 		return;
 	val = (sm->diag.mode == SM_DIAGMODE_DEMOD) ? valdemod : valinp;
@@ -486,8 +486,8 @@
 
 extern inline void diag_add_one(struct sm_state *sm, int val)
 {
-	if ((sm->diag.mode != SM_DIAGMODE_INPUT && 
-	     sm->diag.mode != SM_DIAGMODE_DEMOD) || 
+	if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
+	     sm->diag.mode != SM_DIAGMODE_DEMOD) ||
 	    sm->diag.ptr >= DIAGDATALEN || sm->diag.ptr < 0)
 		return;
 	/* clip */
@@ -502,7 +502,7 @@
 
 static inline void diag_add_constellation(struct sm_state *sm, int vali, int valq)
 {
-	if ((sm->diag.mode != SM_DIAGMODE_CONSTELLATION) || 
+	if ((sm->diag.mode != SM_DIAGMODE_CONSTELLATION) ||
 	    sm->diag.ptr >= DIAGDATALEN-1 || sm->diag.ptr < 0)
 		return;
 	/* clip */
@@ -530,7 +530,7 @@
 extern inline unsigned int hweight8(unsigned char w)
         __attribute__ ((unused));
 
-extern inline unsigned int hweight32(unsigned int w) 
+extern inline unsigned int hweight32(unsigned int w)
 {
         unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
         res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
@@ -564,7 +564,7 @@
 	for (;;) {
 		if (!x)
 			return y;
-		if (!y) 
+		if (!y)
 			return x;
 		if (x > y)
 			x %= y;
@@ -631,7 +631,7 @@
 
 static int sm_open(struct device *dev);
 static int sm_close(struct device *dev);
-static int sm_ioctl(struct device *dev, struct ifreq *ifr, 
+static int sm_ioctl(struct device *dev, struct ifreq *ifr,
 		    struct hdlcdrv_ioctl *hi, int cmd);
 
 /* --------------------------------------------------------------------- */
@@ -651,7 +651,7 @@
 	struct sm_state *sm;
 	int err;
 
-	if (!dev || !dev->priv || 
+	if (!dev || !dev->priv ||
 	    ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
 		printk(KERN_ERR "sm_open: invalid device struct\n");
 		return -EINVAL;
@@ -666,8 +666,8 @@
 		return err;
 	output_open(sm);
 	MOD_INC_USE_COUNT;
-	printk(KERN_INFO "%s: %s mode %s.%s at iobase 0x%lx irq %u dma %u\n", 
-	       sm_drvname, sm->hwdrv->hw_name, sm->mode_tx->name, 
+	printk(KERN_INFO "%s: %s mode %s.%s at iobase 0x%lx irq %u dma %u\n",
+	       sm_drvname, sm->hwdrv->hw_name, sm->mode_tx->name,
 	       sm->mode_rx->name, dev->base_addr, dev->irq, dev->dma);
 	return 0;
 }
@@ -679,19 +679,19 @@
 	struct sm_state *sm;
 	int err = -ENODEV;
 
-	if (!dev || !dev->priv || 
+	if (!dev || !dev->priv ||
 	    ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
 		printk(KERN_ERR "sm_close: invalid device struct\n");
 		return -EINVAL;
 	}
 	sm = (struct sm_state *)dev->priv;
 
-	
+
 	if (sm->hwdrv && sm->hwdrv->close)
 		err = sm->hwdrv && sm->hwdrv->close(dev, sm);
 	output_close(sm);
 	MOD_DEC_USE_COUNT;
-	printk(KERN_INFO "%s: close %s at iobase 0x%lx irq %u dma %u\n", 
+	printk(KERN_INFO "%s: close %s at iobase 0x%lx irq %u dma %u\n",
 	       sm_drvname, sm->hwdrv->hw_name, dev->base_addr, dev->irq, dev->dma);
 	return err;
 }
@@ -702,7 +702,7 @@
 {
 	char *cp = strchr(mode, ':');
 	const struct hardware_info *hwp = hardware_base;
-	
+
 	if (!cp)
 		cp = mode;
 	else {
@@ -718,7 +718,7 @@
 		}
 		sm->hwdrv = hwp;
 	}
-	if (!*cp) 
+	if (!*cp)
 		return 0;
 	if (sm->hwdrv && sm->hwdrv->sethw)
 		return sm->hwdrv->sethw(dev, sm, cp);
@@ -727,7 +727,7 @@
 
 /* --------------------------------------------------------------------- */
 
-static int sm_ioctl(struct device *dev, struct ifreq *ifr, 
+static int sm_ioctl(struct device *dev, struct ifreq *ifr,
 		    struct hdlcdrv_ioctl *hi, int cmd)
 {
 	struct sm_state *sm;
@@ -740,7 +740,7 @@
 	const struct modem_rx_info *mrp = modem_rx_base;
 	const struct hardware_info *hwp = hardware_base;
 
-	if (!dev || !dev->priv || 
+	if (!dev || !dev->priv ||
 	    ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
 		printk(KERN_ERR "sm_ioctl: invalid device struct\n");
 		return -EINVAL;
@@ -757,34 +757,34 @@
 		if (sm->hwdrv && sm->hwdrv->ioctl)
 			return sm->hwdrv->ioctl(dev, sm, ifr, hi, cmd);
 		return -ENOIOCTLCMD;
-		
+
 	case HDLCDRVCTL_GETMODE:
 		cp = hi->data.modename;
 		if (sm->hwdrv && sm->hwdrv->hw_name)
 			cp += sprintf(cp, "%s:", sm->hwdrv->hw_name);
-		else 
+		else
 			cp += sprintf(cp, "<unspec>:");
 		if (sm->mode_tx && sm->mode_tx->name)
 			cp += sprintf(cp, "%s", sm->mode_tx->name);
-		else 
+		else
 			cp += sprintf(cp, "<unspec>");
-		if (!sm->mode_rx || !sm->mode_rx || 
+		if (!sm->mode_rx || !sm->mode_rx ||
 		    strcmp(sm->mode_rx->name, sm->mode_tx->name)) {
 			if (sm->mode_rx && sm->mode_rx->name)
 				cp += sprintf(cp, ",%s", sm->mode_rx->name);
-			else 
+			else
 				cp += sprintf(cp, ",<unspec>");
 		}
 		if (copy_to_user(ifr->ifr_data, hi, sizeof(*hi)))
 			return -EFAULT;
 		return 0;
-		
+
 	case HDLCDRVCTL_SETMODE:
 		if (!suser() || dev->start)
 			return -EACCES;
 		hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
 		return sethw(dev, sm, hi->data.modename);
-		
+
 	case HDLCDRVCTL_MODELIST:
 		cp = hi->data.modename;
 		while (hwp) {
@@ -806,7 +806,7 @@
 		if (copy_to_user(ifr->ifr_data, hi, sizeof(*hi)))
 			return -EFAULT;
 		return 0;
-		
+
 #ifdef SM_DEBUG
 	case SMCTL_GETDEBUG:
 		if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
@@ -815,7 +815,7 @@
 		bi.data.dbg.mod_cycles = sm->debug_vals.mod_cyc;
 		bi.data.dbg.demod_cycles = sm->debug_vals.demod_cyc;
 		bi.data.dbg.dma_residue = sm->debug_vals.dma_residue;
-		sm->debug_vals.mod_cyc = sm->debug_vals.demod_cyc = 
+		sm->debug_vals.mod_cyc = sm->debug_vals.demod_cyc =
 			sm->debug_vals.dma_residue = 0;
 		if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
 			return -EFAULT;
@@ -855,7 +855,7 @@
 				return -EFAULT;
 			return 0;
 		}
-		if (copy_to_user(bi.data.diag.data, sm->diag.data, 
+		if (copy_to_user(bi.data.diag.data, sm->diag.data,
 				 bi.data.diag.datalen * sizeof(short)))
 			return -EFAULT;
 		bi.data.diag.flags |= SM_DIAGFLAG_VALID;
@@ -882,7 +882,7 @@
 	char set_hw = 1;
 	struct sm_state *sm;
 	char ifname[HDLCDRV_IFNAMELEN];
-	
+
 	printk(sm_drvinfo);
 	/*
 	 * register net devices
@@ -895,7 +895,7 @@
 			set_hw = 0;
 		if (!set_hw)
 			sm_ports[i].iobase = sm_ports[i].irq = 0;
-		j = hdlcdrv_register_hdlcdrv(dev, &sm_ops, sizeof(struct sm_state), 
+		j = hdlcdrv_register_hdlcdrv(dev, &sm_ops, sizeof(struct sm_state),
 					     ifname, sm_ports[i].iobase,
 					     sm_ports[i].irq, sm_ports[i].dma);
 		if (!j) {
@@ -933,6 +933,15 @@
 int pario = 0;
 int midiio = 0;
 
+MODULE_PARM(mode, "s");
+MODULE_PARM(iobase, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(dma, "i");
+MODULE_PARM(dma2, "i");
+MODULE_PARM(serio, "i");
+MODULE_PARM(pario, "i");
+MODULE_PARM(midiio, "i");
+
 int init_module(void)
 {
 	if (mode) {
@@ -972,7 +981,7 @@
 			if (sm->hdrv.magic != HDLCDRV_MAGIC)
 				printk(KERN_ERR "sm: invalid magic in "
 				       "cleanup_module\n");
-			else 
+			else
 				hdlcdrv_unregister_hdlcdrv(dev);
 		}
 	}
diff -u --recursive --new-file v2.1.18/linux/drivers/net/sunlance.c linux/drivers/net/sunlance.c
--- v2.1.18/linux/drivers/net/sunlance.c	Mon Dec 30 15:39:10 1996
+++ linux/drivers/net/sunlance.c	Mon Dec 30 12:00:04 1996
@@ -770,7 +770,7 @@
 	}
 
 	if (skb->len <= 0) {
-		printk ("skb len is %ld\n", skb->len);
+		printk ("skb len is %d\n", skb->len);
 		return 0;
 	}
 
diff -u --recursive --new-file v2.1.18/linux/drivers/net/wd.c linux/drivers/net/wd.c
--- v2.1.18/linux/drivers/net/wd.c	Fri Mar  1 07:50:49 1996
+++ linux/drivers/net/wd.c	Tue Dec 31 10:30:05 1996
@@ -20,7 +20,7 @@
 
 	Paul Gortmaker	: multiple card support for module users, support
 			  for non-standard memory sizes.
-			 
+
 
 */
 
@@ -259,7 +259,7 @@
 	}
 
 	/* Allocate dev->priv and fill in 8390 specific dev fields. */
-	if (ethdev_init(dev)) {	
+	if (ethdev_init(dev)) {
 		printk (" unable to get memory for dev->priv.\n");
 		free_irq(dev->irq, NULL);
 		return -ENOMEM;
@@ -451,6 +451,11 @@
 static int irq[MAX_WD_CARDS]  = { 0, };
 static int mem[MAX_WD_CARDS] = { 0, };
 static int mem_end[MAX_WD_CARDS] = { 0, };	/* for non std. mem size */
+
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
+MODULE_PARM(mem_end, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.1.18/linux/drivers/sbus/char/bwtwo.c linux/drivers/sbus/char/bwtwo.c
--- v2.1.18/linux/drivers/sbus/char/bwtwo.c	Wed Dec 18 15:58:48 1996
+++ linux/drivers/sbus/char/bwtwo.c	Mon Dec 30 12:00:04 1996
@@ -1,4 +1,4 @@
-/* $Id: bwtwo.c,v 1.8 1996/11/23 19:54:05 ecd Exp $
+/* $Id: bwtwo.c,v 1.9 1996/12/23 10:15:57 ecd Exp $
  * bwtwo.c: bwtwo console driver
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -7,6 +7,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
diff -u --recursive --new-file v2.1.18/linux/drivers/sbus/char/cgfourteen.c linux/drivers/sbus/char/cgfourteen.c
--- v2.1.18/linux/drivers/sbus/char/cgfourteen.c	Wed Dec 18 15:58:48 1996
+++ linux/drivers/sbus/char/cgfourteen.c	Mon Dec 30 12:00:04 1996
@@ -1,4 +1,4 @@
-/* $Id: cgfourteen.c,v 1.16 1996/11/22 11:57:06 ecd Exp $
+/* $Id: cgfourteen.c,v 1.17 1996/12/23 10:16:00 ecd Exp $
  * cgfourteen.c: Sun SparcStation console support.
  *
  * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -15,6 +15,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
diff -u --recursive --new-file v2.1.18/linux/drivers/sbus/char/cgsix.c linux/drivers/sbus/char/cgsix.c
--- v2.1.18/linux/drivers/sbus/char/cgsix.c	Sun Dec 22 16:37:36 1996
+++ linux/drivers/sbus/char/cgsix.c	Mon Dec 30 12:00:04 1996
@@ -1,4 +1,4 @@
-/* $Id: cgsix.c,v 1.19 1996/12/19 08:07:35 davem Exp $
+/* $Id: cgsix.c,v 1.21 1996/12/23 10:16:05 ecd Exp $
  * cgsix.c: cgsix frame buffer driver
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -8,6 +8,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
diff -u --recursive --new-file v2.1.18/linux/drivers/sbus/char/cgthree.c linux/drivers/sbus/char/cgthree.c
--- v2.1.18/linux/drivers/sbus/char/cgthree.c	Wed Dec 18 15:58:48 1996
+++ linux/drivers/sbus/char/cgthree.c	Mon Dec 30 12:00:04 1996
@@ -1,4 +1,4 @@
-/* $Id: cgthree.c,v 1.9 1996/11/13 05:10:21 davem Exp $
+/* $Id: cgthree.c,v 1.10 1996/12/23 10:16:07 ecd Exp $
  * cgtree.c: cg3 frame buffer driver
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -9,6 +9,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
diff -u --recursive --new-file v2.1.18/linux/drivers/sbus/char/fb.h linux/drivers/sbus/char/fb.h
--- v2.1.18/linux/drivers/sbus/char/fb.h	Wed Dec 18 15:58:48 1996
+++ linux/drivers/sbus/char/fb.h	Mon Dec 30 12:00:05 1996
@@ -1,4 +1,4 @@
-/* $Id: fb.h,v 1.19 1996/11/13 05:10:23 davem Exp $
+/* $Id: fb.h,v 1.20 1996/12/23 10:16:08 ecd Exp $
  * fb.h: contains the definitions of the structures that various sun
  *       frame buffer can use to do console driver stuff.
  *
@@ -13,7 +13,6 @@
 #ifndef __SPARC_FB_H_
 #define __SPARC_FB_H_
 
-#include <linux/proc_fs.h>
 #include <linux/init.h>
 
 #define FRAME_BUFFERS    8
diff -u --recursive --new-file v2.1.18/linux/drivers/sbus/char/leo.c linux/drivers/sbus/char/leo.c
--- v2.1.18/linux/drivers/sbus/char/leo.c	Wed Dec 18 15:58:48 1996
+++ linux/drivers/sbus/char/leo.c	Mon Dec 30 12:00:05 1996
@@ -1,4 +1,4 @@
-/* $Id: leo.c,v 1.9 1996/11/27 20:09:59 jj Exp $
+/* $Id: leo.c,v 1.10 1996/12/23 10:16:09 ecd Exp $
  * leo.c: SUNW,leo 24/8bit frame buffer driver
  *
  * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -7,6 +7,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
diff -u --recursive --new-file v2.1.18/linux/drivers/sbus/char/suncons.c linux/drivers/sbus/char/suncons.c
--- v2.1.18/linux/drivers/sbus/char/suncons.c	Wed Dec 18 15:58:48 1996
+++ linux/drivers/sbus/char/suncons.c	Mon Dec 30 12:00:05 1996
@@ -1,4 +1,4 @@
-/* $Id: suncons.c,v 1.42 1996/11/27 20:10:06 jj Exp $
+/* $Id: suncons.c,v 1.43 1996/12/23 10:16:12 ecd Exp $
  *
  * suncons.c: Sun SparcStation console support.
  *
@@ -63,6 +63,7 @@
 #include <linux/mm.h>
 #include <linux/types.h>
 #include <linux/version.h>
+#include <linux/proc_fs.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.1.18/linux/drivers/sbus/char/sunfb.c linux/drivers/sbus/char/sunfb.c
--- v2.1.18/linux/drivers/sbus/char/sunfb.c	Wed Dec 18 15:58:48 1996
+++ linux/drivers/sbus/char/sunfb.c	Mon Dec 30 12:00:05 1996
@@ -1,4 +1,4 @@
-/* $Id: sunfb.c,v 1.18 1996/11/22 11:57:07 ecd Exp $
+/* $Id: sunfb.c,v 1.19 1996/12/23 10:16:15 ecd Exp $
  * sunfb.c: Sun generic frame buffer support.
  *
  * Copyright (C) 1995, 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -21,6 +21,7 @@
 #include <linux/major.h>
 #include <linux/mm.h>
 #include <linux/types.h>
+#include <linux/proc_fs.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.1.18/linux/drivers/sbus/char/tcx.c linux/drivers/sbus/char/tcx.c
--- v2.1.18/linux/drivers/sbus/char/tcx.c	Wed Dec 18 15:58:50 1996
+++ linux/drivers/sbus/char/tcx.c	Mon Dec 30 12:00:05 1996
@@ -1,4 +1,4 @@
-/* $Id: tcx.c,v 1.8 1996/11/21 16:57:57 jj Exp $
+/* $Id: tcx.c,v 1.9 1996/12/23 10:16:17 ecd Exp $
  * tcx.c: SUNW,tcx 24/8bit frame buffer driver
  *
  * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -9,6 +9,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
diff -u --recursive --new-file v2.1.18/linux/drivers/sbus/char/weitek.c linux/drivers/sbus/char/weitek.c
--- v2.1.18/linux/drivers/sbus/char/weitek.c	Wed Dec 18 15:58:50 1996
+++ linux/drivers/sbus/char/weitek.c	Mon Dec 30 12:00:05 1996
@@ -1,4 +1,4 @@
-/* $Id: weitek.c,v 1.6 1996/11/13 05:10:51 davem Exp $
+/* $Id: weitek.c,v 1.7 1996/12/23 10:16:18 ecd Exp $
  * weitek.c: Tadpole P9100/P9000 console driver
  *
  * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk)
@@ -7,6 +7,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/openprom.h>
 #include <asm/sbus.h>
diff -u --recursive --new-file v2.1.18/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v2.1.18/linux/drivers/scsi/scsi.h	Sun Dec 22 16:37:37 1996
+++ linux/drivers/scsi/scsi.h	Mon Dec 30 13:01:10 1996
@@ -214,18 +214,8 @@
 
 extern int scsi_dev_init (void);
 
-struct scatterlist {
-    char *  address;    /* Location data is to be transferred to */
-    char * alt_address; /* Location of actual if address is a 
-			 * dma indirect buffer.  NULL otherwise */
-    unsigned int length;
-};
+#include <asm/scatterlist.h>
 
-#ifdef __alpha__
-# define ISA_DMA_THRESHOLD (~0UL)
-#else
-# define ISA_DMA_THRESHOLD (0x00ffffff)
-#endif
 #define CONTIGUOUS_BUFFERS(X,Y) ((X->b_data+X->b_size) == Y->b_data)
 
 
diff -u --recursive --new-file v2.1.18/linux/fs/exec.c linux/fs/exec.c
--- v2.1.18/linux/fs/exec.c	Fri Nov 22 18:28:20 1996
+++ linux/fs/exec.c	Mon Dec 30 13:03:12 1996
@@ -42,6 +42,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
+#include <asm/mmu_context.h>
 
 #include <linux/config.h>
 #ifdef CONFIG_KERNELD
@@ -373,6 +374,7 @@
 			return;
 		}
 		*mm = *current->mm;
+		init_new_context(mm);
 		mm->def_flags = 0;	/* should future lockings be kept? */
 		mm->count = 1;
 		mm->mmap = NULL;
diff -u --recursive --new-file v2.1.18/linux/fs/fat/inode.c linux/fs/fat/inode.c
--- v2.1.18/linux/fs/fat/inode.c	Thu Dec 12 17:02:45 1996
+++ linux/fs/fat/inode.c	Mon Dec 30 16:45:36 1996
@@ -294,12 +294,12 @@
 		       opts.conversion,opts.fs_uid,opts.fs_gid,opts.fs_umask,
 		       MSDOS_CAN_BMAP(MSDOS_SB(sb)) ? ",bmap" : "");
 		printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,"
-		       "se=%d,ts=%ld,ls=%d]\n",b->media,MSDOS_SB(sb)->cluster_size,
+		       "se=%d,ts=%d,ls=%d]\n",b->media,MSDOS_SB(sb)->cluster_size,
 		       MSDOS_SB(sb)->fats,MSDOS_SB(sb)->fat_start,MSDOS_SB(sb)->fat_length,
 		       MSDOS_SB(sb)->dir_start,MSDOS_SB(sb)->dir_entries,
 		       MSDOS_SB(sb)->data_start,
-		       CF_LE_W(*(unsigned short *) &b->sectors),
-		       (unsigned long)b->total_sect,logical_sector_size);
+		       CF_LE_W(get_unaligned((unsigned short *) &b->sectors)),
+		       CF_LE_L(b->total_sect),logical_sector_size);
 		printk ("Transaction block size = %d\n",blksize);
 	}
 	if (MSDOS_SB(sb)->clusters+2 > fat_clusters)
diff -u --recursive --new-file v2.1.18/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
--- v2.1.18/linux/fs/ncpfs/dir.c	Tue Oct 29 19:58:43 1996
+++ linux/fs/ncpfs/dir.c	Mon Dec 30 12:03:22 1996
@@ -2,6 +2,7 @@
  *  dir.c
  *
  *  Copyright (C) 1995, 1996 by Volker Lendecke
+ *  Modified for big endian by J.F. Chadima and David S. Miller
  *
  */
 
@@ -14,10 +15,12 @@
 #include <linux/mm.h>
 #include <linux/ncp_fs.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 #include <linux/errno.h>
 #include <linux/locks.h>
 #include "ncplib_kernel.h"
 
+
 struct ncp_dirent {
 	struct nw_info_struct i;
 	struct nw_search_sequence s; /* given back for i */
@@ -672,6 +675,11 @@
 	ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate));
 	ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate));
 	ncp_date_unix2dos(0, &dummy, &(i->lastAccessDate));
+	i->creationTime = le16_to_cpu(i->creationTime);
+	i->creationDate = le16_to_cpu(i->creationDate);
+	i->modifyTime = le16_to_cpu(i->modifyTime);
+	i->modifyDate = le16_to_cpu(i->modifyDate);
+	i->lastAccessDate = le16_to_cpu(i->lastAccessDate);
 	i->nameLen = 0;
 	i->entryName[0] = '\0';
 
diff -u --recursive --new-file v2.1.18/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- v2.1.18/linux/fs/ncpfs/inode.c	Mon Dec 30 15:39:14 1996
+++ linux/fs/ncpfs/inode.c	Mon Dec 30 12:03:22 1996
@@ -2,6 +2,7 @@
  *  inode.c
  *
  *  Copyright (C) 1995, 1996 by Volker Lendecke
+ *  Modified for big endian by J.F. Chadima and David S. Miller
  *
  */
 
@@ -10,6 +11,7 @@
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 
 #include <linux/sched.h>
 #include <linux/ncp_fs.h>
@@ -83,7 +85,7 @@
 	else
 	{
                 inode->i_mode = NCP_SERVER(inode)->m.file_mode;
-		inode->i_size = NCP_ISTRUCT(inode)->dataStreamSize;
+		inode->i_size = le32_to_cpu(NCP_ISTRUCT(inode)->dataStreamSize);
 	}
 
         DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
@@ -104,12 +106,12 @@
                 inode->i_blocks = 0;
 	}
 
-	inode->i_mtime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->modifyTime,
-					   NCP_ISTRUCT(inode)->modifyDate);
-	inode->i_ctime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->creationTime,
-					   NCP_ISTRUCT(inode)->creationDate);
+	inode->i_mtime = ncp_date_dos2unix(le16_to_cpu(NCP_ISTRUCT(inode)->modifyTime),
+					   le16_to_cpu(NCP_ISTRUCT(inode)->modifyDate));
+	inode->i_ctime = ncp_date_dos2unix(le16_to_cpu(NCP_ISTRUCT(inode)->creationTime),
+					   le16_to_cpu(NCP_ISTRUCT(inode)->creationDate));
 	inode->i_atime = ncp_date_dos2unix(0,
-					   NCP_ISTRUCT(inode)->lastAccessDate);
+					   le16_to_cpu(NCP_ISTRUCT(inode)->lastAccessDate));
 
         if (S_ISREG(inode->i_mode))
 	{
@@ -460,6 +462,8 @@
 		info_mask |= (DM_CREATE_TIME|DM_CREATE_DATE);
 		ncp_date_unix2dos(attr->ia_ctime,
 				  &(info.creationTime), &(info.creationDate));
+		info.creationTime = le16_to_cpu(info.creationTime);
+		info.creationDate = le16_to_cpu(info.creationDate);
 	}
 
 	if ((attr->ia_valid & ATTR_MTIME) != 0)
@@ -467,6 +471,8 @@
 		info_mask |= (DM_MODIFY_TIME|DM_MODIFY_DATE);
 		ncp_date_unix2dos(attr->ia_mtime,
 				  &(info.modifyTime), &(info.modifyDate));
+		info.modifyTime = le16_to_cpu(info.modifyTime);
+		info.modifyDate = le16_to_cpu(info.modifyDate);
 	}
 
 	if ((attr->ia_valid & ATTR_ATIME) != 0)
@@ -475,6 +481,7 @@
 		info_mask |= (DM_LAST_ACCESS_DATE);
 		ncp_date_unix2dos(attr->ia_ctime,
 				  &(dummy), &(info.lastAccessDate));
+		info.lastAccessDate = le16_to_cpu(info.lastAccessDate);
 	}
 
 	if (info_mask != 0)
diff -u --recursive --new-file v2.1.18/linux/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c
--- v2.1.18/linux/fs/ncpfs/ncplib_kernel.c	Wed Oct 16 10:48:28 1996
+++ linux/fs/ncpfs/ncplib_kernel.c	Mon Dec 30 12:03:22 1996
@@ -2,6 +2,7 @@
  *  ncplib_kernel.c
  *
  *  Copyright (C) 1995, 1996 by Volker Lendecke
+ *  Modified for big endian by J.F. Chadima and David S. Miller
  *
  */
 
@@ -38,7 +39,7 @@
 ncp_add_word(struct ncp_server *server, word x)
 {
 	assert_server_locked(server);
-	*(word *)(&(server->packet[server->current_size])) = x;
+	put_unaligned(x, (word *)(&(server->packet[server->current_size])));
 	server->current_size += 2;
 	return;
 }
@@ -47,7 +48,7 @@
 ncp_add_dword(struct ncp_server *server, dword x)
 {
 	assert_server_locked(server);
-	*(dword *)(&(server->packet[server->current_size])) = x;
+	put_unaligned(x, (dword *)(&(server->packet[server->current_size])));
 	server->current_size += 4;
 	return;
 }
@@ -261,7 +262,7 @@
 	ncp_add_byte(server, 6); /* subfunction */
 	ncp_add_byte(server, server->name_space[vol_num]);
 	ncp_add_byte(server, server->name_space[vol_num]);
-	ncp_add_word(server, 0xff); /* get all */
+	ncp_add_word(server, htons(0xff00)); /* get all */
 	ncp_add_dword(server, RIM_ALL);
 	ncp_add_handle_path(server, vol_num, dir_base, 1, path);
 
@@ -371,7 +372,7 @@
 	ncp_add_byte(server, 7); /* subfunction */
 	ncp_add_byte(server, server->name_space[file->volNumber]);
 	ncp_add_byte(server, 0); /* reserved */
-	ncp_add_word(server, 0x8006); /* search attribs: all */
+	ncp_add_word(server, htons(0x0680)); /* search attribs: all */
 
 	ncp_add_dword(server, info_mask);
 	ncp_add_mem(server, info, sizeof(*info));
@@ -393,7 +394,7 @@
 	ncp_add_byte(server, 8); /* subfunction */
 	ncp_add_byte(server, server->name_space[dir->volNumber]);
 	ncp_add_byte(server, 0); /* reserved */
-	ncp_add_word(server, 0x8006); /* search attribs: all */
+	ncp_add_word(server, ntohs(0x0680)); /* search attribs: all */
 	ncp_add_handle_path(server, dir->volNumber,
 			    dir->dirEntNum, 1, name);
 	
@@ -406,8 +407,8 @@
 ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] )
 {
     __u16 *dest = (__u16 *) ret;
-    memcpy(&(dest[1]), &sfd, 4);
-    dest[0] = dest[1] + 1;
+    memcpy (ret + 2, &sfd, 4);
+    dest[0] = cpu_to_le16((le16_to_cpu(dest[1]) + le16_to_cpu(1)));
     return;
 }
 
@@ -422,13 +423,13 @@
 			       struct nw_file_info *target)
 {
 	int result;
-	__u16 search_attribs = 0x0006;
+	__u16 search_attribs = ntohs(0x0600);
 	__u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
 
 	if ((create_attributes & aDIR) != 0)
 	{
-		search_attribs |= 0x8000;	
-}
+		search_attribs |= ntohs(0x0080);	
+	}
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 1); /* subfunction */
@@ -546,7 +547,7 @@
 	ncp_add_byte(server, 4); /* subfunction */
 	ncp_add_byte(server, server->name_space[old_dir->volNumber]);
 	ncp_add_byte(server, 1); /* rename flag */
-	ncp_add_word(server, 0x8006); /* search attributes */
+	ncp_add_word(server, ntohs (0x0680)); /* search attributes */
 
 	/* source Handle Path */
 	ncp_add_byte(server, old_dir->volNumber);
diff -u --recursive --new-file v2.1.18/linux/fs/ncpfs/ncplib_kernel.h linux/fs/ncpfs/ncplib_kernel.h
--- v2.1.18/linux/fs/ncpfs/ncplib_kernel.h	Fri Nov  1 17:13:19 1996
+++ linux/fs/ncpfs/ncplib_kernel.h	Mon Dec 30 12:03:22 1996
@@ -2,6 +2,7 @@
  *  ncplib_kernel.h
  *
  *  Copyright (C) 1995, 1996 by Volker Lendecke
+ *  Modified for big endian by J.F. Chadima and David S. Miller
  *
  */
 
@@ -18,6 +19,8 @@
 #include <linux/stat.h>
 #include <linux/fcntl.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
 #include <asm/string.h>
 
 #include <linux/ncp.h>
diff -u --recursive --new-file v2.1.18/linux/fs/proc/openpromfs.c linux/fs/proc/openpromfs.c
--- v2.1.18/linux/fs/proc/openpromfs.c	Wed Dec 18 15:58:51 1996
+++ linux/fs/proc/openpromfs.c	Mon Dec 30 12:00:05 1996
@@ -1,4 +1,4 @@
-/* $Id: openpromfs.c,v 1.8 1996/12/02 16:04:42 ecd Exp $
+/* $Id: openpromfs.c,v 1.9 1996/12/23 05:54:21 davem Exp $
  * openpromfs.c: /proc/openprom handling routines
  *
  * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
diff -u --recursive --new-file v2.1.18/linux/fs/select.c linux/fs/select.c
--- v2.1.18/linux/fs/select.c	Tue Oct 29 19:58:44 1996
+++ linux/fs/select.c	Mon Dec 30 16:05:00 1996
@@ -178,17 +178,21 @@
 		for (i = 0 ; i < n ; i++,fd++) {
 			unsigned long bit = BIT(i);
 			unsigned long *in = MEM(i,fds->in);
-			if (ISSET(bit,__IN(in)) && check(SEL_IN,wait,*fd)) {
+			struct file * file = *fd;
+
+			if (!file)
+				continue;
+			if (ISSET(bit,__IN(in)) && check(SEL_IN,wait,file)) {
 				SET(bit, __RES_IN(in));
 				retval++;
 				wait = NULL;
 			}
-			if (ISSET(bit,__OUT(in)) && check(SEL_OUT,wait,*fd)) {
+			if (ISSET(bit,__OUT(in)) && check(SEL_OUT,wait,file)) {
 				SET(bit, __RES_OUT(in));
 				retval++;
 				wait = NULL;
 			}
-			if (ISSET(bit,__EX(in)) && check(SEL_EX,wait,*fd)) {
+			if (ISSET(bit,__EX(in)) && check(SEL_EX,wait,file)) {
 				SET(bit, __RES_EX(in));
 				retval++;
 				wait = NULL;
diff -u --recursive --new-file v2.1.18/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c
--- v2.1.18/linux/fs/smbfs/proc.c	Thu Dec 12 17:02:46 1996
+++ linux/fs/smbfs/proc.c	Mon Dec 30 11:54:12 1996
@@ -128,7 +128,10 @@
 		const char *name, const int len)
 {
 	byte *start = p;
-	p = smb_encode_parents(p, dir);
+	if (dir != NULL)
+	{
+		p = smb_encode_parents(p, dir);
+	}
 	p = smb_encode_this_name(p, name, len);
 	*p++ = 0;
 	if (server->protocol <= PROTOCOL_COREPLUS)
@@ -573,7 +576,6 @@
 	DPRINTK("smb_proc_open: name=%s\n", name);
 
 	smb_lock_server(server);
-	buf = server->packet;
 
 	if (entry->opened != 0)
 	{
@@ -582,6 +584,7 @@
 		return 0;
 	}
       retry:
+	buf = server->packet;
 	p = smb_setup_header(server, SMBopen, 2, 0);
 	WSET(buf, smb_vwv0, 0x42);	/* read/write */
 	WSET(buf, smb_vwv1, o_attr);
@@ -732,8 +735,8 @@
 	__u16 fileid;
 
 	smb_lock_server(server);
-	buf = server->packet;
       retry:
+	buf = server->packet;
 	p = smb_setup_header(server, SMBcreate, 3, 0);
 	WSET(buf, smb_vwv0, attr);
 	DSET(buf, smb_vwv1, utc2local(ctime));
@@ -764,15 +767,13 @@
 {
 	char *p;
 	struct smb_server *server = SMB_SERVER(odir);
-	char *buf;
 	int result;
 
 	smb_lock_server(server);
-	buf = server->packet;
 
       retry:
 	p = smb_setup_header(server, SMBmv, 1, 0);
-	WSET(buf, smb_vwv0, aSYSTEM | aHIDDEN);
+	WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
 	*p++ = 4;
 	p = smb_encode_path(server, p, SMB_INOP(odir), oname, olen);
 	*p++ = 4;
@@ -825,7 +826,6 @@
 
 	smb_lock_server(server);
 
-
       retry:
 	p = smb_setup_header(server, SMBrmdir, 0, 0);
 	*p++ = 4;
@@ -848,15 +848,13 @@
 {
 	char *p;
 	struct smb_server *server = SMB_SERVER(dir);
-	char *buf;
 	int result;
 
 	smb_lock_server(server);
-	buf = server->packet;
 
       retry:
 	p = smb_setup_header(server, SMBunlink, 1, 0);
-	WSET(buf, smb_vwv0, aSYSTEM | aHIDDEN);
+	WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
 	*p++ = 4;
 	p = smb_encode_path(server, p, SMB_INOP(dir), name, len);
 	smb_setup_bcc(server, p);
@@ -880,9 +878,9 @@
 	int result;
 
 	smb_lock_server(server);
-	buf = server->packet;
 
       retry:
+	buf = server->packet;
 	p = smb_setup_header(server, SMBwrite, 5, 0);
 	WSET(buf, smb_vwv0, fid);
 	WSET(buf, smb_vwv1, 0);
@@ -1011,9 +1009,9 @@
 	DPRINTK("SMB call  readdir %d @ %d\n", cache_size, fpos);
 
 	smb_lock_server(server);
-	buf = server->packet;
 
       retry:
+	buf = server->packet;
 	first = 1;
 	total_count = 0;
 	current_entry = entry;
@@ -1389,11 +1387,11 @@
 	char *buf;
 
 	smb_lock_server(server);
-	buf = server->packet;
 
 	DDPRINTK("smb_proc_getattr: %s\n", name);
 
       retry:
+	buf = server->packet;
 	p = smb_setup_header(server, SMBgetatr, 0, 0);
 	*p++ = 4;
 	p = smb_encode_path(server, p, SMB_INOP(dir), name, len);
@@ -1512,9 +1510,9 @@
 	int result;
 
 	smb_lock_server(server);
-	buf = server->packet;
 
       retry:
+	buf = server->packet;
 	p = smb_setup_header(server, SMBsetatr, 8, 0);
 	WSET(buf, smb_vwv0, new_finfo->attr);
 	DSET(buf, smb_vwv1, utc2local(new_finfo->f_mtime));
diff -u --recursive --new-file v2.1.18/linux/fs/ufs/ufs_super.c linux/fs/ufs/ufs_super.c
--- v2.1.18/linux/fs/ufs/ufs_super.c	Mon Dec 30 15:39:14 1996
+++ linux/fs/ufs/ufs_super.c	Mon Dec 30 12:00:05 1996
@@ -8,7 +8,7 @@
  *
  * Copyright (C) 1996  Eddie C. Dost  (ecd@skynet.be)
  *
- * $Id: ufs_super.c,v 1.20 1996/11/02 18:10:12 ecd Exp $
+ * $Id: ufs_super.c,v 1.21 1996/12/29 20:48:55 davem Exp $
  *
  */
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-alpha/current.h linux/include/asm-alpha/current.h
--- v2.1.18/linux/include/asm-alpha/current.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-alpha/current.h	Mon Dec 30 11:58:34 1996
@@ -0,0 +1,12 @@
+#ifndef _ALPHA_CURRENT_H
+#define _ALPHA_CURRENT_H
+
+/* 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.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+#define current (current_set[smp_processor_id()])	/* Current on this processor */
+
+#endif /* !(_ALPHA_CURRENT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-alpha/mmu_context.h linux/include/asm-alpha/mmu_context.h
--- v2.1.18/linux/include/asm-alpha/mmu_context.h	Wed Oct  9 08:55:22 1996
+++ linux/include/asm-alpha/mmu_context.h	Mon Dec 30 13:03:12 1996
@@ -87,4 +87,7 @@
 #endif
 }
 
+#define init_new_context(mm)	do { } while(0)
+#define destroy_context(mm)	do { } while(0)
+
 #endif
diff -u --recursive --new-file v2.1.18/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h
--- v2.1.18/linux/include/asm-alpha/processor.h	Fri Nov  1 17:13:19 1996
+++ linux/include/asm-alpha/processor.h	Mon Dec 30 11:56:18 1996
@@ -12,6 +12,11 @@
  */
 #define TASK_SIZE (0x40000000000UL)
 
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
+
 /*
  * Bus types
  */
diff -u --recursive --new-file v2.1.18/linux/include/asm-alpha/scatterlist.h linux/include/asm-alpha/scatterlist.h
--- v2.1.18/linux/include/asm-alpha/scatterlist.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-alpha/scatterlist.h	Mon Dec 30 13:01:10 1996
@@ -0,0 +1,13 @@
+#ifndef _ALPHA_SCATTERLIST_H
+#define _ALPHA_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+			 * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#endif /* !(_ALPHA_SCATTERLIST_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-alpha/termios.h linux/include/asm-alpha/termios.h
--- v2.1.18/linux/include/asm-alpha/termios.h	Tue Nov 12 15:56:12 1996
+++ linux/include/asm-alpha/termios.h	Mon Dec 30 12:48:07 1996
@@ -85,53 +85,58 @@
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern inline void trans_from_termio(struct termio * termio,
-	struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)	((x) = (0xffff0000 & (x)) | (y))
-	SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-	SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-	SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-	SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-	termios->c_cc[VINTR] = termio->c_cc[_VINTR];
-	termios->c_cc[VQUIT] = termio->c_cc[_VQUIT];
-	termios->c_cc[VERASE]= termio->c_cc[_VERASE];
-	termios->c_cc[VKILL] = termio->c_cc[_VKILL];
-	termios->c_cc[VEOF]  = termio->c_cc[_VEOF];
-	termios->c_cc[VMIN]  = termio->c_cc[_VMIN];
-	termios->c_cc[VEOL]  = termio->c_cc[_VEOL];
-	termios->c_cc[VTIME] = termio->c_cc[_VTIME];
-	termios->c_cc[VEOL2] = termio->c_cc[_VEOL2];
-	termios->c_cc[VSWTC] = termio->c_cc[_VSWTC];
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp,&(termio)->x); \
+	*(unsigned short *) &(termios)->x = __tmp; \
 }
 
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	get_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
+	get_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
+	get_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
+	get_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
+	get_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
+	get_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+	get_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
+	get_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+	get_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
+	get_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
+} while(0)
+
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  *
  * Note the "fun" _VMIN overloading.
  */
-extern inline void trans_to_termio(struct termios * termios,
-	struct termio * termio)
-{
-	termio->c_iflag = termios->c_iflag;
-	termio->c_oflag = termios->c_oflag;
-	termio->c_cflag = termios->c_cflag;
-	termio->c_lflag = termios->c_lflag;
-	termio->c_line	= termios->c_line;
-	termio->c_cc[_VINTR] = termios->c_cc[VINTR];
-	termio->c_cc[_VQUIT] = termios->c_cc[VQUIT];
-	termio->c_cc[_VERASE]= termios->c_cc[VERASE];
-	termio->c_cc[_VKILL] = termios->c_cc[VKILL];
-	termio->c_cc[_VEOF]  = termios->c_cc[VEOF];
-	termio->c_cc[_VEOL]  = termios->c_cc[VEOL];
-	termio->c_cc[_VEOL2] = termios->c_cc[VEOL2];
-	termio->c_cc[_VSWTC] = termios->c_cc[VSWTC];
-	if (!(termios->c_lflag & ICANON)) {
-		termio->c_cc[_VMIN]  = termios->c_cc[VMIN];
-		termio->c_cc[_VTIME] = termios->c_cc[VTIME];
-	}
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line, &(termio)->c_line); \
+	put_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
+	put_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
+	put_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
+	put_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
+	put_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
+	put_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
+	put_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
+	put_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
+	if (!((termios)->c_lflag & ICANON)) { \
+		put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+		put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+	} \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif	/* __KERNEL__ */
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-i386/current.h linux/include/asm-i386/current.h
--- v2.1.18/linux/include/asm-i386/current.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-i386/current.h	Mon Dec 30 11:58:34 1996
@@ -0,0 +1,12 @@
+#ifndef _I386_CURRENT_H
+#define _I386_CURRENT_H
+
+/* 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.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+#define current (current_set[smp_processor_id()])	/* Current on this processor */
+
+#endif /* !(_I386_CURRENT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-i386/mmu_context.h linux/include/asm-i386/mmu_context.h
--- v2.1.18/linux/include/asm-i386/mmu_context.h	Thu Apr 25 15:42:03 1996
+++ linux/include/asm-i386/mmu_context.h	Mon Dec 30 13:03:12 1996
@@ -6,4 +6,7 @@
  */
 #define get_mmu_context(x) do { } while (0)
 
+#define init_new_context(mm)	do { } while(0)
+#define destroy_context(mm)	do { } while(0)
+
 #endif
diff -u --recursive --new-file v2.1.18/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h
--- v2.1.18/linux/include/asm-i386/processor.h	Thu Dec 12 19:37:18 1996
+++ linux/include/asm-i386/processor.h	Mon Dec 30 11:56:18 1996
@@ -45,6 +45,11 @@
  */
 #define TASK_SIZE	(0xC0000000UL)
 
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
+
 /*
  * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
  */
diff -u --recursive --new-file v2.1.18/linux/include/asm-i386/scatterlist.h linux/include/asm-i386/scatterlist.h
--- v2.1.18/linux/include/asm-i386/scatterlist.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-i386/scatterlist.h	Mon Dec 30 13:01:10 1996
@@ -0,0 +1,13 @@
+#ifndef _I386_SCATTERLIST_H
+#define _I386_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+			 * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#endif /* !(_I386_SCATTERLIST_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-i386/termios.h linux/include/asm-i386/termios.h
--- v2.1.18/linux/include/asm-i386/termios.h	Tue Nov 12 15:56:12 1996
+++ linux/include/asm-i386/termios.h	Mon Dec 30 12:49:04 1996
@@ -21,16 +21,6 @@
 	unsigned char c_cc[NCC];	/* control characters */
 };
 
-#ifdef __KERNEL__
-/*	intr=^C		quit=^\		erase=del	kill=^U
-	eof=^D		vtime=\0	vmin=\1		sxtc=\0
-	start=^Q	stop=^S		susp=^Z		eol=\0
-	reprint=^R	discard=^U	werase=^W	lnext=^V
-	eol2=\0
-*/
-#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-#endif
-
 /* modem lines */
 #define TIOCM_LE	0x001
 #define TIOCM_DTR	0x002
@@ -56,36 +46,47 @@
 
 #ifdef __KERNEL__
 
-#include <linux/string.h>
+/*	intr=^C		quit=^\		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
 
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern inline void trans_from_termio(struct termio * termio,
-	struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)	(*(unsigned short *)(&x) = (y))
-	SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-	SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-	SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-	SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-	memcpy(termios->c_cc, termio->c_cc, NCC);
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp,&(termio)->x); \
+	*(unsigned short *) &(termios)->x = __tmp; \
 }
 
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+} while(0)
+
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  */
-extern inline void trans_to_termio(struct termios * termios,
-	struct termio * termio)
-{
-	termio->c_iflag = termios->c_iflag;
-	termio->c_oflag = termios->c_oflag;
-	termio->c_cflag = termios->c_cflag;
-	termio->c_lflag = termios->c_lflag;
-	termio->c_line	= termios->c_line;
-	memcpy(termio->c_cc, termios->c_cc, NCC);
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif	/* __KERNEL__ */
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v2.1.18/linux/include/asm-i386/unistd.h	Mon Dec 30 15:39:14 1996
+++ linux/include/asm-i386/unistd.h	Tue Dec 31 13:16:02 1996
@@ -118,7 +118,7 @@
 #define __NR_iopl		110
 #define __NR_vhangup		111
 #define __NR_idle		112
-#define __NR_vm86		113
+#define __NR_vm86old		113
 #define __NR_wait4		114
 #define __NR_swapoff		115
 #define __NR_sysinfo		116
@@ -171,7 +171,8 @@
 #define __NR_mremap		163
 #define __NR_setresuid		164
 #define __NR_getresuid		165
-#define __NR_query_module	166
+#define __NR_vm86		166
+#define __NR_query_module	167
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-m68k/current.h linux/include/asm-m68k/current.h
--- v2.1.18/linux/include/asm-m68k/current.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-m68k/current.h	Mon Dec 30 11:58:35 1996
@@ -0,0 +1,12 @@
+#ifndef _M68K_CURRENT_H
+#define _M68K_CURRENT_H
+
+/* 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.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+#define current (current_set[smp_processor_id()])	/* Current on this processor */
+
+#endif /* !(_M68K_CURRENT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-m68k/mmu_context.h linux/include/asm-m68k/mmu_context.h
--- v2.1.18/linux/include/asm-m68k/mmu_context.h	Wed Mar 27 22:45:37 1996
+++ linux/include/asm-m68k/mmu_context.h	Mon Dec 30 13:03:13 1996
@@ -6,4 +6,7 @@
  */
 #define get_mmu_context(x) do { } while (0)
 
+#define init_new_context(mm)	do { } while(0)
+#define destroy_context(mm)	do { } while(0)
+
 #endif
diff -u --recursive --new-file v2.1.18/linux/include/asm-m68k/processor.h linux/include/asm-m68k/processor.h
--- v2.1.18/linux/include/asm-m68k/processor.h	Sun Dec 22 16:37:39 1996
+++ linux/include/asm-m68k/processor.h	Mon Dec 30 11:56:18 1996
@@ -15,6 +15,11 @@
  */
 #define TASK_SIZE	(0xF0000000UL)
 
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
+
 /*
  * Bus types
  */
diff -u --recursive --new-file v2.1.18/linux/include/asm-m68k/scatterlist.h linux/include/asm-m68k/scatterlist.h
--- v2.1.18/linux/include/asm-m68k/scatterlist.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-m68k/scatterlist.h	Mon Dec 30 13:01:10 1996
@@ -0,0 +1,17 @@
+#ifndef _M68K_SCATTERLIST_H
+#define _M68K_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+			 * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+
+#ifdef __sparc__
+    char * dvma_address; /* A place to hang host-specific addresses at. */
+#endif
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#endif /* !(_M68K_SCATTERLIST_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-m68k/termios.h linux/include/asm-m68k/termios.h
--- v2.1.18/linux/include/asm-m68k/termios.h	Tue Nov 12 15:56:12 1996
+++ linux/include/asm-m68k/termios.h	Mon Dec 30 12:55:48 1996
@@ -59,31 +59,36 @@
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern inline void trans_from_termio(struct termio * termio,
-	struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)	((x) = (0xffff0000 & (x)) | (y))
-	SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-	SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-	SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-	SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-	memcpy(termios->c_cc, termio->c_cc, NCC);
-}
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+	unsigned short tmp; \
+	get_user(tmp, &(termio)->c_iflag); \
+	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	get_user(tmp, &(termio)->c_oflag); \
+	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	get_user(tmp, &(termio)->c_cflag); \
+	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	get_user(tmp, &(termio)->c_lflag); \
+	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	get_user((termios)->c_line, &(termio)->c_line); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+} while(0)
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  */
-extern inline void trans_to_termio(struct termios * termios,
-	struct termio * termio)
-{
-	termio->c_iflag = termios->c_iflag;
-	termio->c_oflag = termios->c_oflag;
-	termio->c_cflag = termios->c_cflag;
-	termio->c_lflag = termios->c_lflag;
-	termio->c_line	= termios->c_line;
-	memcpy(termio->c_cc, termios->c_cc, NCC);
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif	/* __KERNEL__ */
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-mips/current.h linux/include/asm-mips/current.h
--- v2.1.18/linux/include/asm-mips/current.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-mips/current.h	Mon Dec 30 11:58:35 1996
@@ -0,0 +1,12 @@
+#ifndef _MIPS_CURRENT_H
+#define _MIPS_CURRENT_H
+
+/* 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.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+#define current (current_set[smp_processor_id()])	/* Current on this processor */
+
+#endif /* !(_MIPS_CURRENT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-mips/processor.h linux/include/asm-mips/processor.h
--- v2.1.18/linux/include/asm-mips/processor.h	Fri Apr 12 09:49:44 1996
+++ linux/include/asm-mips/processor.h	Mon Dec 30 11:56:18 1996
@@ -45,6 +45,11 @@
  */
 #define TASK_SIZE	(0x80000000UL)
 
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
+
 /*
  * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
  */
diff -u --recursive --new-file v2.1.18/linux/include/asm-mips/scatterlist.h linux/include/asm-mips/scatterlist.h
--- v2.1.18/linux/include/asm-mips/scatterlist.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-mips/scatterlist.h	Mon Dec 30 13:01:10 1996
@@ -0,0 +1,13 @@
+#ifndef _MIPS_SCATTERLIST_H
+#define _MIPS_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+			 * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#endif /* !(_MIPS_SCATTERLIST_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-mips/termios.h linux/include/asm-mips/termios.h
--- v2.1.18/linux/include/asm-mips/termios.h	Wed Dec 13 12:39:47 1995
+++ linux/include/asm-mips/termios.h	Mon Dec 30 12:56:38 1996
@@ -18,31 +18,36 @@
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern inline void trans_from_termio(struct termio * termio,
-	struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)	((x) = (0xffff0000 & (x)) | (y))
-	SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-	SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-	SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-	SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-	memcpy(termios->c_cc, termio->c_cc, NCC);
-}
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+	unsigned short tmp; \
+	get_user(tmp, &(termio)->c_iflag); \
+	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	get_user(tmp, &(termio)->c_oflag); \
+	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	get_user(tmp, &(termio)->c_cflag); \
+	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	get_user(tmp, &(termio)->c_lflag); \
+	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	get_user((termios)->c_line, &(termio)->c_line); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+} while(0)
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  */
-extern inline void trans_to_termio(struct termios * termios,
-	struct termio * termio)
-{
-	termio->c_iflag = termios->c_iflag;
-	termio->c_oflag = termios->c_oflag;
-	termio->c_cflag = termios->c_cflag;
-	termio->c_lflag = termios->c_lflag;
-	termio->c_line	= termios->c_line;
-	memcpy(termio->c_cc, termios->c_cc, NCC);
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line, &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif	/* __KERNEL__ */
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-ppc/current.h linux/include/asm-ppc/current.h
--- v2.1.18/linux/include/asm-ppc/current.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/current.h	Mon Dec 30 11:58:35 1996
@@ -0,0 +1,12 @@
+#ifndef _PPC_CURRENT_H
+#define _PPC_CURRENT_H
+
+/* 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.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+#define current (current_set[smp_processor_id()])	/* Current on this processor */
+
+#endif /* !(_PPC_CURRENT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-ppc/mmu_context.h linux/include/asm-ppc/mmu_context.h
--- v2.1.18/linux/include/asm-ppc/mmu_context.h	Mon May 27 12:00:59 1996
+++ linux/include/asm-ppc/mmu_context.h	Mon Dec 30 13:03:13 1996
@@ -6,5 +6,8 @@
  */
 #define get_mmu_context(x) do { } while (0)
 
+#define init_new_context(mm)	do { } while(0)
+#define destroy_context(mm)	do { } while(0)
+
 #endif
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
--- v2.1.18/linux/include/asm-ppc/processor.h	Wed Dec 18 15:58:52 1996
+++ linux/include/asm-ppc/processor.h	Mon Dec 30 11:56:19 1996
@@ -85,6 +85,11 @@
  */
 #define TASK_SIZE	(0x80000000UL)
 
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
+
 struct thread_struct 
 {
   unsigned long	ksp;		/* Kernel stack pointer */
diff -u --recursive --new-file v2.1.18/linux/include/asm-ppc/scatterlist.h linux/include/asm-ppc/scatterlist.h
--- v2.1.18/linux/include/asm-ppc/scatterlist.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/scatterlist.h	Mon Dec 30 13:01:10 1996
@@ -0,0 +1,13 @@
+#ifndef _PPC_SCATTERLIST_H
+#define _PPC_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+			 * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#endif /* !(_PPC_SCATTERLIST_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-ppc/termios.h linux/include/asm-ppc/termios.h
--- v2.1.18/linux/include/asm-ppc/termios.h	Wed Dec 18 15:58:52 1996
+++ linux/include/asm-ppc/termios.h	Mon Dec 30 12:53:48 1996
@@ -349,53 +349,58 @@
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern inline void trans_from_termio(struct termio * termio,
-	struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)	((x) = (0xffff0000 & (x)) | (y))
-	SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-	SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-	SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-	SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-	termios->c_cc[VINTR] = termio->c_cc[_VINTR];
-	termios->c_cc[VQUIT] = termio->c_cc[_VQUIT];
-	termios->c_cc[VERASE]= termio->c_cc[_VERASE];
-	termios->c_cc[VKILL] = termio->c_cc[_VKILL];
-	termios->c_cc[VEOF]  = termio->c_cc[_VEOF];
-	termios->c_cc[VMIN]  = termio->c_cc[_VMIN];
-	termios->c_cc[VEOL]  = termio->c_cc[_VEOL];
-	termios->c_cc[VTIME] = termio->c_cc[_VTIME];
-	termios->c_cc[VEOL2] = termio->c_cc[_VEOL2];
-	termios->c_cc[VSWTC] = termio->c_cc[_VSWTC];
-}
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+	unsigned short tmp; \
+	get_user(tmp, &(termio)->c_iflag); \
+	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	get_user(tmp, &(termio)->c_oflag); \
+	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	get_user(tmp, &(termio)->c_cflag); \
+	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	get_user(tmp, &(termio)->c_lflag); \
+	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	get_user((termios)->c_line, &(termio)->c_line); \
+	get_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
+	get_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
+	get_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
+	get_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
+	get_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
+	get_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+	get_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
+	get_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+	get_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
+	get_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
+} while(0)
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  *
  * Note the "fun" _VMIN overloading.
  */
-extern inline void trans_to_termio(struct termios * termios,
-	struct termio * termio)
-{
-	termio->c_iflag = termios->c_iflag;
-	termio->c_oflag = termios->c_oflag;
-	termio->c_cflag = termios->c_cflag;
-	termio->c_lflag = termios->c_lflag;
-	termio->c_line	= termios->c_line;
-	termio->c_cc[_VINTR] = termios->c_cc[VINTR];
-	termio->c_cc[_VQUIT] = termios->c_cc[VQUIT];
-	termio->c_cc[_VERASE]= termios->c_cc[VERASE];
-	termio->c_cc[_VKILL] = termios->c_cc[VKILL];
-	termio->c_cc[_VEOF]  = termios->c_cc[VEOF];
-	termio->c_cc[_VEOL]  = termios->c_cc[VEOL];
-	termio->c_cc[_VEOL2] = termios->c_cc[VEOL2];
-	termio->c_cc[_VSWTC] = termios->c_cc[VSWTC];
-	if (1/*!(termios->c_lflag & ICANON)*/) {
-		termio->c_cc[_VMIN]  = termios->c_cc[VMIN];
-		termio->c_cc[_VTIME] = termios->c_cc[VTIME];
-	}
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	put_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
+	put_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
+	put_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
+	put_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
+	put_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
+	put_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
+	put_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
+	put_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
+	if (1/*!((termios)->c_lflag & ICANON)*/) { \
+		put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+		put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+	} \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif	/* __KERNEL__ */
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/atomic.h linux/include/asm-sparc/atomic.h
--- v2.1.18/linux/include/asm-sparc/atomic.h	Wed Dec 18 15:59:01 1996
+++ linux/include/asm-sparc/atomic.h	Mon Dec 30 11:59:59 1996
@@ -23,9 +23,6 @@
 {
 	__asm__ __volatile__("
 	rd	%%psr, %%g2
-	nop
-	nop
-	nop
 	andcc	%%g2, %2, %%g0
 	bne	1f
 	 nop
@@ -54,9 +51,6 @@
 {
 	__asm__ __volatile__("
 	rd	%%psr, %%g2
-	nop
-	nop
-	nop
 	andcc	%%g2, %2, %%g0
 	bne	1f
 	 nop
@@ -85,9 +79,6 @@
 {
 	__asm__ __volatile__("
 	rd	%%psr, %%g2
-	nop
-	nop
-	nop
 	andcc	%%g2, %3, %%g0
 	bne	1f
 	 nop
@@ -118,9 +109,6 @@
 {
 	__asm__ __volatile__("
 	rd	%%psr, %%g2
-	nop
-	nop
-	nop
 	andcc	%%g2, %3, %%g0
 	bne	1f
 	 nop
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/bitops.h linux/include/asm-sparc/bitops.h
--- v2.1.18/linux/include/asm-sparc/bitops.h	Mon Dec 30 15:39:15 1996
+++ linux/include/asm-sparc/bitops.h	Mon Dec 30 11:59:59 1996
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.40 1996/12/23 05:28:49 davem Exp $
+/* $Id: bitops.h,v 1.41 1996/12/28 18:14:25 davem Exp $
  * bitops.h: Bit string operations on the Sparc.
  *
  * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -104,9 +104,6 @@
 	mask = 1 << (nr & 31);
 	__asm__ __volatile__("
 	rd	%%psr, %%g3
-	nop
-	nop
-	nop
 	andcc	%%g3, %3, %%g0
 	bne	1f
 	 nop
@@ -143,9 +140,6 @@
 	mask = 1 << (nr & 31);
 	__asm__ __volatile__("
 	rd	%%psr, %%g3
-	nop
-	nop
-	nop
 	andcc	%%g3, %3, %%g0
 	bne	1f
 	 nop
@@ -182,9 +176,6 @@
 	mask = 1 << (nr & 31);
 	__asm__ __volatile__("
 	rd	%%psr, %%g3
-	nop
-	nop
-	nop
 	andcc	%%g3, %3, %%g0
 	bne	1f
 	 nop
@@ -335,9 +326,6 @@
 	mask = 1 << (nr & 0x07);
 	__asm__ __volatile__("
 	rd	%%psr, %%g3
-	nop
-	nop
-	nop
 	andcc	%%g3, %3, %%g0
 	bne	1f
 	 nop
@@ -374,9 +362,6 @@
 	mask = 1 << (nr & 0x07);
 	__asm__ __volatile__("
 	rd	%%psr, %%g3
-	nop
-	nop
-	nop
 	andcc	%%g3, %3, %%g0
 	bne	1f
 	 nop
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/cache.h linux/include/asm-sparc/cache.h
--- v2.1.18/linux/include/asm-sparc/cache.h	Tue Nov 12 15:56:12 1996
+++ linux/include/asm-sparc/cache.h	Mon Dec 30 11:59:59 1996
@@ -1,4 +1,4 @@
-/* $Id: cache.h,v 1.5 1996/08/29 09:48:06 davem Exp $
+/* $Id: cache.h,v 1.6 1996/12/28 19:55:12 davem Exp $
  * cache.h:  Cache specific code for the Sparc.  These include flushing
  *           and direct tag/data line access.
  *
@@ -9,6 +9,8 @@
 #define _SPARC_CACHE_H
 
 #include <asm/asi.h>
+
+#define L1_CACHE_BYTES 32
 
 /* Direct access to the instruction cache is provided through and
  * alternate address space.  The IDC bit must be off in the ICCR on
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/current.h linux/include/asm-sparc/current.h
--- v2.1.18/linux/include/asm-sparc/current.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc/current.h	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,13 @@
+#ifndef _SPARC_CURRENT_H
+#define _SPARC_CURRENT_H
+
+/* Some architectures may want to do something "clever" here since
+ * this is the most frequently accessed piece of data in the entire
+ * kernel.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+
+/* Sparc rules... */
+register struct task_struct *current asm("g6");
+
+#endif /* !(_SPARC_CURRENT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/mmu_context.h linux/include/asm-sparc/mmu_context.h
--- v2.1.18/linux/include/asm-sparc/mmu_context.h	Mon Mar  4 08:50:01 1996
+++ linux/include/asm-sparc/mmu_context.h	Mon Dec 30 11:59:59 1996
@@ -9,6 +9,11 @@
 /* Initialize the context related info for a new mm_struct
  * instance.
  */
-#define init_new_context(mm) ((mm)->context = NO_CONTEXT)
+extern void (*init_new_context)(struct mm_struct *mm);
+
+/* Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+extern void (*destroy_context)(struct mm_struct *mm);
 
 #endif /* !(__SPARC_MMU_CONTEXT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/pgtable.h linux/include/asm-sparc/pgtable.h
--- v2.1.18/linux/include/asm-sparc/pgtable.h	Mon Dec 30 15:39:15 1996
+++ linux/include/asm-sparc/pgtable.h	Mon Dec 30 11:59:59 1996
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.56 1996/12/23 05:28:50 davem Exp $ */
+/* $Id: pgtable.h,v 1.58 1996/12/30 06:17:03 davem Exp $ */
 #ifndef _SPARC_PGTABLE_H
 #define _SPARC_PGTABLE_H
 
@@ -26,10 +26,6 @@
    This procedure can be used until the call to mem_init(). */
 extern void *sparc_init_alloc(unsigned long *kbrk, unsigned long size);
 
-/* mmu-specific process creation/cloning/etc hooks. */
-extern void (*mmu_exit_hook)(void);
-extern void (*mmu_flush_hook)(void);
-
 /* translate between physical and virtual addresses */
 extern unsigned long (*mmu_v2p)(unsigned long);
 extern unsigned long (*mmu_p2v)(unsigned long);
@@ -260,8 +256,6 @@
 extern void (*pgd_free)(pgd_t *);
 
 extern pgd_t * (*pgd_alloc)(void);
-
-extern void (*pgd_flush)(pgd_t *);
 
 /* Fine grained cache/tlb flushing. */
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h
--- v2.1.18/linux/include/asm-sparc/processor.h	Wed Dec 18 15:59:01 1996
+++ linux/include/asm-sparc/processor.h	Mon Dec 30 11:59:59 1996
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.52 1996/12/03 08:44:56 jj Exp $
+/* $Id: processor.h,v 1.54 1996/12/24 09:19:49 davem Exp $
  * include/asm-sparc/processor.h
  *
  * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
@@ -149,9 +149,11 @@
 			     "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])));
 }
 
+/* Free all resources held by a thread. */
 #define release_thread(tsk)		do { } while(0)
 
 #ifdef __KERNEL__
+/* Allocation and freeing of basic task resources. */
 extern unsigned long (*alloc_kernel_stack)(struct task_struct *tsk);
 extern void (*free_kernel_stack)(unsigned long stack);
 extern struct task_struct *(*alloc_task_struct)(void);
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/scatterlist.h linux/include/asm-sparc/scatterlist.h
--- v2.1.18/linux/include/asm-sparc/scatterlist.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc/scatterlist.h	Mon Dec 30 11:59:59 1996
@@ -0,0 +1,16 @@
+/* $Id: scatterlist.h,v 1.1 1996/12/24 07:38:48 davem Exp $ */
+#ifndef _SPARC_SCATTERLIST_H
+#define _SPARC_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+			 * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+
+    char * dvma_address; /* A place to hang host-specific addresses at. */
+};
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#endif /* !(_SPARC_SCATTERLIST_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/signal.h linux/include/asm-sparc/signal.h
--- v2.1.18/linux/include/asm-sparc/signal.h	Tue Nov 12 15:56:13 1996
+++ linux/include/asm-sparc/signal.h	Mon Dec 30 12:00:00 1996
@@ -1,4 +1,4 @@
-/* $Id: signal.h,v 1.29 1996/10/27 08:55:45 davem Exp $ */
+/* $Id: signal.h,v 1.30 1996/12/24 08:59:36 davem Exp $ */
 #ifndef _ASMSPARC_SIGNAL_H
 #define _ASMSPARC_SIGNAL_H
 
@@ -160,17 +160,6 @@
 	unsigned long   sa_flags;
 	void (*sa_restorer) (void);     /* not used by Linux/SPARC yet */
 };
-
-#ifdef __KERNEL__
-
-/* use the following macro to get the size of a sigaction struct
-   when copying to/from userland */
-#define SIGACTION_SIZE(personality) (((personality) & PER_BSD)?\
-				     sizeof(struct sigaction)-sizeof(void *):\
-				     sizeof(struct sigaction))
-
-#endif /* __KERNEL__ */
-
 
 #endif /* !(__ASSEMBLY__) */
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/system.h linux/include/asm-sparc/system.h
--- v2.1.18/linux/include/asm-sparc/system.h	Sun Dec 22 16:37:41 1996
+++ linux/include/asm-sparc/system.h	Mon Dec 30 12:00:01 1996
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.44 1996/12/18 06:56:08 tridge Exp $ */
+/* $Id: system.h,v 1.47 1996/12/30 00:31:12 davem Exp $ */
 #ifndef __SPARC_SYSTEM_H
 #define __SPARC_SYSTEM_H
 
@@ -46,6 +46,7 @@
  * frames are up to date.
  */
 extern void flush_user_windows(void);
+extern void kill_user_windows(void);
 extern void synchronize_user_stack(void);
 extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
 		   void *fpqueue, unsigned long *fpqdepth);
@@ -88,43 +89,32 @@
 		switch_to_context(next);						\
 	task_pc = ((unsigned long) &&here) - 0x8;					\
 	__asm__ __volatile__(								\
-	"rd\t%%psr, %%g4\n\t"								\
+	"rd	%%psr, %%g4\n\t"							\
+	"std	%%sp, [%%g6 + %3]\n\t"							\
+	"rd	%%wim, %%g5\n\t"							\
+	"wr	%%g4, 0x20, %%psr\n\t"							\
+	"nop\n\t"									\
+	"std	%%g4, [%%g6 + %2]\n\t"							\
+	"ldd	[%1 + %2], %%g4\n\t"							\
+	"mov	%1, %%g6\n\t"								\
+	"st	%1, [%0]\n\t"								\
+	"wr	%%g4, 0x20, %%psr\n\t"							\
+	"nop\n\t"									\
+	"nop\n\t"									\
+	"ldd	[%%g6 + %3], %%sp\n\t"							\
+	"wr	%%g5, 0x0, %%wim\n\t"							\
+	"ldd	[%%sp + 0x00], %%l0\n\t"						\
+	"ldd	[%%sp + 0x38], %%i6\n\t"						\
+	"wr	%%g4, 0x0, %%psr\n\t"							\
 	"nop\n\t"									\
 	"nop\n\t"									\
-	"nop\n\t"									\
-	"std\t%%sp, [%%g6 + %3]\n\t"							\
-	"rd\t%%wim, %%g5\n\t"								\
-	"wr\t%%g4, 0x20, %%psr\n\t"							\
-	"nop\n\t"									\
-	"nop\n\t"									\
-	"nop\n\t"									\
-	"std\t%%g4, [%%g6 + %2]\n\t"							\
-	"mov\t%1, %%g6\n\t"								\
-	"ldd\t[%%g6 + %2], %%g4\n\t"							\
-	"st\t%1, [%0]\n\t"								\
-	"wr\t%%g4, 0x20, %%psr\n\t"							\
-	"nop\n\t"									\
-	"nop\n\t"									\
-	"nop\n\t"									\
-	"ldd\t[%%g6 + %3], %%sp\n\t"							\
-	"wr\t%%g5, 0x0, %%wim\n\t"							\
-	"ldd\t[%%sp + 0x00], %%l0\n\t"							\
-	"ldd\t[%%sp + 0x08], %%l2\n\t"							\
-	"ldd\t[%%sp + 0x10], %%l4\n\t"							\
-	"ldd\t[%%sp + 0x18], %%l6\n\t"							\
-	"ldd\t[%%sp + 0x20], %%i0\n\t"							\
-	"ldd\t[%%sp + 0x28], %%i2\n\t"							\
-	"ldd\t[%%sp + 0x30], %%i4\n\t"							\
-	"ldd\t[%%sp + 0x38], %%i6\n\t"							\
-	"wr\t%%g4, 0x0, %%psr\n\t"							\
-	"nop\n\t"									\
-	"nop\n\t"									\
-	"nop\n\t"									\
-	"jmpl\t%%o7 + 0x8, %%g0\n\t"							\
+	"jmpl	%%o7 + 0x8, %%g0\n\t"							\
 	" nop\n\t" : : "r" (&(current_set[smp_processor_id()])), "r" (next),		\
 	"i" ((const unsigned long)(&((struct task_struct *)0)->tss.kpsr)),		\
 	"i" ((const unsigned long)(&((struct task_struct *)0)->tss.ksp)),		\
-	"r" (task_pc) : "g4", "g5");							\
+	"r" (task_pc) : "g1", "g2", "g3", "g4", "g5", "g7", "l2", "l3",			\
+	"l4", "l5", "l6", "l7", "i0", "i1", "i2", "i3", "i4", "i5", "o0", "o1", "o2",	\
+	"o3");										\
 here: SWITCH_EXIT } while(0)
 
 /* Changing the IRQ level on the Sparc.   We now avoid writing the psr
@@ -148,9 +138,6 @@
 
 	__asm__ __volatile__("
 		rd	%%psr, %0
-		nop
-		nop
-		nop
 		andcc	%0, %1, %%g0
 		bne	1f
 		 nop
@@ -170,9 +157,6 @@
 
 	__asm__ __volatile__("
 		rd	%%psr, %0
-		nop
-		nop
-		nop
 		andcc	%0, %1, %%g0
 		be	1f
 		 nop
@@ -190,12 +174,7 @@
 {
 	unsigned long retval;
 
-	__asm__ __volatile__("
-		rd	%%psr, %0
-		nop
-		nop
-		nop
-"	: "=r" (retval));
+	__asm__ __volatile__("rd	%%psr, %0" : "=r" (retval));
 	return retval;
 }
 
@@ -205,9 +184,6 @@
 
 	__asm__ __volatile__("
 		rd	%%psr, %0
-		nop
-		nop
-		nop
 		and	%0, %4, %1
 		and	%3, %4, %2
 		xorcc	%1, %2, %%g0
@@ -231,9 +207,6 @@
 
 	__asm__ __volatile__("
 		rd	%%psr, %0
-		nop
-		nop
-		nop
 		andcc	%0, %1, %%g0
 		bne	1f
 		 nop
@@ -264,9 +237,6 @@
 {
 	__asm__ __volatile__("
 	rd	%%psr, %%g3
-	nop
-	nop
-	nop
 	andcc	%%g3, %3, %%g0
 	bne	1f
 	 nop
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/termios.h linux/include/asm-sparc/termios.h
--- v2.1.18/linux/include/asm-sparc/termios.h	Wed Dec 18 15:59:02 1996
+++ linux/include/asm-sparc/termios.h	Mon Dec 30 12:52:52 1996
@@ -1,4 +1,4 @@
-/* $Id: termios.h,v 1.21 1996/11/13 02:30:40 davem Exp $ */
+/* $Id: termios.h,v 1.23 1996/12/30 06:17:03 davem Exp $ */
 #ifndef _SPARC_TERMIOS_H
 #define _SPARC_TERMIOS_H
 
@@ -76,8 +76,6 @@
 #define _VTIME	5
 
 
-#include <linux/string.h>
-
 /*	intr=^C		quit=^\		erase=del	kill=^U
 	eof=^D		eol=\0		eol2=\0		sxtc=\0
 	start=^Q	stop=^S		susp=^Z		dsusp=^Y
@@ -89,81 +87,72 @@
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern __inline__ void trans_from_termio(struct termio * termio,
-					 struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)	((x) = (0xffff0000 & (x)) | (y))
-	SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-	SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-	SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-	SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-	memcpy (termios->c_cc, termio->c_cc, NCC);
-}
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+	unsigned short tmp; \
+	get_user(tmp, &(termio)->c_iflag); \
+	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	get_user(tmp, &(termio)->c_oflag); \
+	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	get_user(tmp, &(termio)->c_cflag); \
+	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	get_user(tmp, &(termio)->c_lflag); \
+	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+} while(0)
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  *
  * Note the "fun" _VMIN overloading.
  */
-extern __inline__ void trans_to_termio(struct termios * termios,
-				       struct termio * termio)
-{
-	termio->c_iflag = termios->c_iflag;
-	termio->c_oflag = termios->c_oflag;
-	termio->c_cflag = termios->c_cflag;
-	termio->c_lflag = termios->c_lflag;
-	termio->c_line	= termios->c_line;
-	memcpy(termio->c_cc, termios->c_cc, NCC);
-	if (!(termios->c_lflag & ICANON)) {
-		termio->c_cc[_VMIN]  = termios->c_cc[VMIN];
-		termio->c_cc[_VTIME] = termios->c_cc[VTIME];
-	}
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+	if (!((termios)->c_lflag & ICANON)) { \
+		put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+		put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+	} \
+} while(0)
 
-/* Note that in this case DEST is a user buffer and thus the checking
- * and this ugly macro to avoid header file problems.
- */
-#define termios_to_userland(d, s) \
+#define user_termios_to_kernel_termios(k, u) \
 do { \
-	struct termios *dest = (d); \
-	struct termios *source = (s); \
-	put_user(source->c_iflag, &dest->c_iflag); \
-	put_user(source->c_oflag, &dest->c_oflag); \
-	put_user(source->c_cflag, &dest->c_cflag); \
-	put_user(source->c_lflag, &dest->c_lflag); \
-	put_user(source->c_line, &dest->c_line); \
-	copy_to_user(dest->c_cc, source->c_cc, NCCS); \
-	if (!(source->c_lflag & ICANON)){ \
-		put_user(source->c_cc[VMIN], &dest->c_cc[_VMIN]); \
-		put_user(source->c_cc[VTIME], &dest->c_cc[_VTIME]); \
+	get_user((k)->c_iflag, &(u)->c_iflag); \
+	get_user((k)->c_oflag, &(u)->c_oflag); \
+	get_user((k)->c_cflag, &(u)->c_cflag); \
+	get_user((k)->c_lflag, &(u)->c_lflag); \
+	get_user((k)->c_line,  &(u)->c_line); \
+	copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+	if((k)->c_lflag & ICANON) { \
+		get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+		get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
 	} else { \
-		put_user(source->c_cc[VEOF], &dest->c_cc[VEOF]); \
-		put_user(source->c_cc[VEOL], &dest->c_cc[VEOL]); \
+		get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+		get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
 	} \
 } while(0)
 
-/* termios to termios handling SunOS overloading of eof,eol/vmin,vtime
- * In this case we are only working with kernel buffers so direct
- * accesses are ok.
- */
-extern __inline__ void termios_from_userland(struct termios * source,
-					     struct termios * dest)
-{
-	dest->c_iflag = source->c_iflag;
-	dest->c_oflag = source->c_oflag;
-	dest->c_cflag = source->c_cflag;
-	dest->c_lflag = source->c_lflag;
-	dest->c_line  = source->c_line;
-	memcpy(dest->c_cc, source->c_cc, NCCS);
-	if (dest->c_lflag & ICANON){
-		dest->c_cc [VEOF] = source->c_cc [VEOF];
-		dest->c_cc [VEOL] = source->c_cc [VEOL];
-	} else {
-		dest->c_cc[VMIN]  = source->c_cc[_VMIN];
-		dest->c_cc[VTIME] = source->c_cc[_VTIME];
-	}
-}
+#define kernel_termios_to_user_termios(u, k) \
+do { \
+	put_user((k)->c_iflag, &(u)->c_iflag); \
+	put_user((k)->c_oflag, &(u)->c_oflag); \
+	put_user((k)->c_cflag, &(u)->c_cflag); \
+	put_user((k)->c_lflag, &(u)->c_lflag); \
+	put_user((k)->c_line, &(u)->c_line); \
+	copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+	if(!((k)->c_lflag & ICANON)) { \
+		put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+		put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+	} else { \
+		put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+		put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+	} \
+} while(0)
 
 #endif	/* __KERNEL__ */
 
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc/unistd.h linux/include/asm-sparc/unistd.h
--- v2.1.18/linux/include/asm-sparc/unistd.h	Sun Dec 22 16:37:41 1996
+++ linux/include/asm-sparc/unistd.h	Mon Dec 30 12:00:02 1996
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.25 1996/12/18 06:56:10 tridge Exp $ */
+/* $Id: unistd.h,v 1.26 1996/12/29 20:49:14 davem Exp $ */
 #ifndef _SPARC_UNISTD_H
 #define _SPARC_UNISTD_H
 
@@ -200,7 +200,7 @@
 #define __NR_aiowait            181 /* SunOS Specific                              */
 #define __NR_aiocancel          182 /* SunOS Specific                              */
 #define __NR_sigpending         183 /* Common                                      */
-/* #define __NR_ni_syscall      184    ENOSYS under SunOS                          */
+#define __NR_query_module       184 /* Linux Specific                              */
 #define __NR_setpgid            185 /* Common                                      */
 #define __NR_pathconf           186 /* SunOS Specific                              */
 #define __NR_fpathconf          187 /* SunOS Specific                              */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/a.out.h linux/include/asm-sparc64/a.out.h
--- v2.1.18/linux/include/asm-sparc64/a.out.h	Wed Dec 18 15:59:02 1996
+++ linux/include/asm-sparc64/a.out.h	Mon Dec 30 12:00:02 1996
@@ -1,10 +1,12 @@
-/* $Id: a.out.h,v 1.1 1996/11/20 12:05:19 davem Exp $ */
+/* $Id: a.out.h,v 1.2 1996/12/28 18:39:49 davem Exp $ */
 #ifndef __SPARC64_A_OUT_H__
 #define __SPARC64_A_OUT_H__
 
 #define SPARC_PGSIZE    0x2000        /* Thanks to the sun4 architecture... */
 #define SEGMENT_SIZE    SPARC_PGSIZE  /* whee... */
 
+#ifndef __ASSEMBLY__
+
 struct exec {
 	unsigned char a_dynamic:1;      /* A __DYNAMIC is in this image */
 	unsigned char a_toolversion:7;
@@ -19,6 +21,8 @@
 	unsigned int a_drsize;
 };
 
+#endif __ASSEMBLY__
+
 /* Where in the file does the text information begin? */
 #define N_TXTOFF(x)     (N_MAGIC(x) == ZMAGIC ? 0 : sizeof (struct exec))
 
@@ -41,6 +45,8 @@
 #define N_DRSIZE(a)	((a).a_drsize)
 #define N_SYMSIZE(a)	((a).a_syms)
 
+#ifndef __ASSEMBLY__
+
 /*
  * Sparc relocation types
  */
@@ -93,4 +99,6 @@
 
 #endif
 
-#endif /* __SPARC64_A_OUT_H__ */
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC64_A_OUT_H__) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/bitops.h linux/include/asm-sparc64/bitops.h
--- v2.1.18/linux/include/asm-sparc64/bitops.h	Mon Dec 30 15:39:15 1996
+++ linux/include/asm-sparc64/bitops.h	Mon Dec 30 12:00:02 1996
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.5 1996/12/21 06:09:28 davem Exp $
+/* $Id: bitops.h,v 1.6 1996/12/26 15:36:49 davem Exp $
  * bitops.h: Bit string operations on the V9.
  *
  * Copyright 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -225,10 +225,10 @@
 	if (offset >= size)
 		return size;
 	size -= result;
-	offset &= 31UL;
+	offset &= 63UL;
 	if(offset) {
 		tmp = *(p++);
-		tmp |= __swab64(~0UL >> (64-offset));
+		tmp |= __swab64((~0UL >> (64-offset)));
 		if(size < 64)
 			goto found_first;
 		if(~tmp)
@@ -247,9 +247,9 @@
 	tmp = *p;
 
 found_first:
-	return result + ffz(__swab32(tmp) | (~0UL << size));
+	return result + ffz(__swab64(tmp) | (~0UL << size));
 found_middle:
-	return result + ffz(__swab32(tmp));
+	return result + ffz(__swab64(tmp));
 }
 
 #ifdef __KERNEL__
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/bsderrno.h linux/include/asm-sparc64/bsderrno.h
--- v2.1.18/linux/include/asm-sparc64/bsderrno.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/bsderrno.h	Mon Dec 30 12:00:02 1996
@@ -0,0 +1,94 @@
+/* $Id: bsderrno.h,v 1.1 1996/12/26 13:25:21 davem Exp $
+ * bsderrno.h: Error numbers for NetBSD binary compatibility
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_BSDERRNO_H
+#define _SPARC64_BSDERRNO_H
+
+#define BSD_EPERM         1      /* Operation not permitted */
+#define BSD_ENOENT        2      /* No such file or directory */
+#define BSD_ESRCH         3      /* No such process */
+#define BSD_EINTR         4      /* Interrupted system call */
+#define BSD_EIO           5      /* Input/output error */
+#define BSD_ENXIO         6      /* Device not configured */
+#define BSD_E2BIG         7      /* Argument list too long */
+#define BSD_ENOEXEC       8      /* Exec format error */
+#define BSD_EBADF         9      /* Bad file descriptor */
+#define BSD_ECHILD        10     /* No child processes */
+#define BSD_EDEADLK       11     /* Resource deadlock avoided */
+#define BSD_ENOMEM        12     /* Cannot allocate memory */
+#define BSD_EACCES        13     /* Permission denied */
+#define BSD_EFAULT        14     /* Bad address */
+#define BSD_ENOTBLK       15     /* Block device required */
+#define BSD_EBUSY         16     /* Device busy */
+#define BSD_EEXIST        17     /* File exists */
+#define BSD_EXDEV         18     /* Cross-device link */
+#define BSD_ENODEV        19     /* Operation not supported by device */
+#define BSD_ENOTDIR       20     /* Not a directory */
+#define BSD_EISDIR        21     /* Is a directory */
+#define BSD_EINVAL        22     /* Invalid argument */
+#define BSD_ENFILE        23     /* Too many open files in system */
+#define BSD_EMFILE        24     /* Too many open files */
+#define BSD_ENOTTY        25     /* Inappropriate ioctl for device */
+#define BSD_ETXTBSY       26     /* Text file busy */
+#define BSD_EFBIG         27     /* File too large */
+#define BSD_ENOSPC        28     /* No space left on device */
+#define BSD_ESPIPE        29     /* Illegal seek */
+#define BSD_EROFS         30     /* Read-only file system */
+#define BSD_EMLINK        31     /* Too many links */
+#define BSD_EPIPE         32     /* Broken pipe */
+#define BSD_EDOM          33     /* Numerical argument out of domain */
+#define BSD_ERANGE        34     /* Result too large */
+#define BSD_EAGAIN        35     /* Resource temporarily unavailable */
+#define BSD_EWOULDBLOCK   EAGAIN /* Operation would block */
+#define BSD_EINPROGRESS   36     /* Operation now in progress */
+#define BSD_EALREADY      37     /* Operation already in progress */
+#define BSD_ENOTSOCK      38     /* Socket operation on non-socket */
+#define BSD_EDESTADDRREQ  39     /* Destination address required */
+#define BSD_EMSGSIZE      40     /* Message too long */
+#define BSD_EPROTOTYPE    41     /* Protocol wrong type for socket */
+#define BSD_ENOPROTOOPT   42     /* Protocol not available */
+#define BSD_EPROTONOSUPPORT  43  /* Protocol not supported */
+#define BSD_ESOCKTNOSUPPORT  44  /* Socket type not supported */
+#define BSD_EOPNOTSUPP    45     /* Operation not supported */
+#define BSD_EPFNOSUPPORT  46     /* Protocol family not supported */
+#define BSD_EAFNOSUPPORT  47     /* Address family not supported by protocol family */
+#define BSD_EADDRINUSE    48     /* Address already in use */
+#define BSD_EADDRNOTAVAIL 49     /* Can't assign requested address */
+#define BSD_ENETDOWN      50     /* Network is down */
+#define BSD_ENETUNREACH   51     /* Network is unreachable */
+#define BSD_ENETRESET     52     /* Network dropped connection on reset */
+#define BSD_ECONNABORTED  53     /* Software caused connection abort */
+#define BSD_ECONNRESET    54     /* Connection reset by peer */
+#define BSD_ENOBUFS       55     /* No buffer space available */
+#define BSD_EISCONN       56     /* Socket is already connected */
+#define BSD_ENOTCONN      57     /* Socket is not connected */
+#define BSD_ESHUTDOWN     58     /* Can't send after socket shutdown */
+#define BSD_ETOOMANYREFS  59     /* Too many references: can't splice */
+#define BSD_ETIMEDOUT     60     /* Operation timed out */
+#define BSD_ECONNREFUSED  61     /* Connection refused */
+#define BSD_ELOOP         62     /* Too many levels of symbolic links */
+#define BSD_ENAMETOOLONG  63     /* File name too long */
+#define BSD_EHOSTDOWN     64     /* Host is down */
+#define BSD_EHOSTUNREACH  65     /* No route to host */
+#define BSD_ENOTEMPTY     66     /* Directory not empty */
+#define BSD_EPROCLIM      67     /* Too many processes */
+#define BSD_EUSERS        68     /* Too many users */
+#define BSD_EDQUOT        69     /* Disc quota exceeded */
+#define BSD_ESTALE        70     /* Stale NFS file handle */
+#define BSD_EREMOTE       71     /* Too many levels of remote in path */
+#define BSD_EBADRPC       72     /* RPC struct is bad */
+#define BSD_ERPCMISMATCH  73     /* RPC version wrong */
+#define BSD_EPROGUNAVAIL  74     /* RPC prog. not avail */
+#define BSD_EPROGMISMATCH 75     /* Program version wrong */
+#define BSD_EPROCUNAVAIL  76     /* Bad procedure for program */
+#define BSD_ENOLCK        77     /* No locks available */
+#define BSD_ENOSYS        78     /* Function not implemented */
+#define BSD_EFTYPE        79     /* Inappropriate file type or format */
+#define BSD_EAUTH         80     /* Authentication error */
+#define BSD_ENEEDAUTH     81     /* Need authenticator */
+#define BSD_ELAST         81     /* Must be equal largest errno */
+
+#endif /* !(_SPARC64_BSDERRNO_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/bugs.h linux/include/asm-sparc64/bugs.h
--- v2.1.18/linux/include/asm-sparc64/bugs.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/bugs.h	Mon Dec 30 12:00:02 1996
@@ -0,0 +1,7 @@
+/*  $Id: bugs.h,v 1.1 1996/12/26 13:25:20 davem Exp $
+ *  include/asm-sparc64/bugs.h:  Sparc probes for various bugs.
+ *
+ *  Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+static void check_bugs(void) { }
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/byteorder.h linux/include/asm-sparc64/byteorder.h
--- v2.1.18/linux/include/asm-sparc64/byteorder.h	Wed Dec 18 15:59:02 1996
+++ linux/include/asm-sparc64/byteorder.h	Mon Dec 30 12:00:02 1996
@@ -1,17 +1,17 @@
-/* $Id: byteorder.h,v 1.1 1996/11/20 14:01:53 davem Exp $ */
+/* $Id: byteorder.h,v 1.2 1996/12/26 13:25:23 davem Exp $ */
 #ifndef _SPARC64_BYTEORDER_H
 #define _SPARC64_BYTEORDER_H
 
-#define ntohl(x) x
-#define ntohs(x) x
-#define htonl(x) x
-#define htons(x) x
+extern __inline__ unsigned long int ntohl(unsigned long int x) { return x; }
+extern __inline__ unsigned short int ntohs(unsigned short int x) { return x; }
+extern __inline__ unsigned long int htonl(unsigned long int x) { return x; }
+extern __inline__ unsigned short int htons(unsigned short int x) { return x; }
 
 /* Some programs depend upon these being around. */
-#define __constant_ntohl(x) x
-#define __constant_ntohs(x) x
-#define __constant_htonl(x) x
-#define __constant_htons(x) x
+extern __inline__ unsigned long int __constant_ntohl(unsigned long int x) { return x; }
+extern __inline__ unsigned short int __constant_ntohs(unsigned short int x) { return x; }
+extern __inline__ unsigned long int __constant_htonl(unsigned long int x) { return x; }
+extern __inline__ unsigned short int __constant_htons(unsigned short int x) { return x; }
 
 #ifndef __BIG_ENDIAN
 #define __BIG_ENDIAN 4321
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/current.h linux/include/asm-sparc64/current.h
--- v2.1.18/linux/include/asm-sparc64/current.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/current.h	Mon Dec 30 12:00:02 1996
@@ -0,0 +1,13 @@
+#ifndef _SPARC64_CURRENT_H
+#define _SPARC64_CURRENT_H
+
+/* Some architectures may want to do something "clever" here since
+ * this is the most frequently accessed piece of data in the entire
+ * kernel.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+
+/* Sparc rules... */
+register struct task_struct *current asm("g6");
+
+#endif /* !(_SPARC64_CURRENT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/dma.h linux/include/asm-sparc64/dma.h
--- v2.1.18/linux/include/asm-sparc64/dma.h	Wed Dec 18 15:59:02 1996
+++ linux/include/asm-sparc64/dma.h	Mon Dec 30 12:00:02 1996
@@ -1,7 +1,7 @@
-/* $Id: dma.h,v 1.1 1996/11/20 15:27:38 davem Exp $
+/* $Id: dma.h,v 1.2 1996/12/26 13:25:24 davem Exp $
  * include/asm-sparc64/dma.h
  *
- * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu)
+ * Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu)
  */
 
 #ifndef _ASM_SPARC64_DMA_H
@@ -9,7 +9,6 @@
 
 #include <linux/kernel.h>
 
-#include <asm/vac-ops.h>  /* for invalidate's, etc. */
 #include <asm/sbus.h>
 #include <asm/delay.h>
 #include <asm/oplib.h>
@@ -18,7 +17,7 @@
  * things can compile.
  */
 #define MAX_DMA_CHANNELS 8
-#define MAX_DMA_ADDRESS  (~0UL)
+#define MAX_DMA_ADDRESS  ((0x100000000) + PAGE_OFFSET)
 #define DMA_MODE_READ    1
 #define DMA_MODE_WRITE   2
 
@@ -164,40 +163,6 @@
 #define DMA_IRQ_EXIT(dma, dregs) do { \
 	if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
    } while(0)
-
-/* Pause until counter runs out or BIT isn't set in the DMA condition
- * register.
- */
-extern __inline__ void sparc_dma_pause(struct sparc_dma_registers *regs,
-				       unsigned long bit)
-{
-	int ctr = 50000;   /* Let's find some bugs ;) */
-
-	/* Busy wait until the bit is not set any more */
-	while((regs->cond_reg&bit) && (ctr>0)) {
-		ctr--;
-		__delay(5);
-	}
-
-	/* Check for bogus outcome. */
-	if(!ctr)
-		panic("DMA timeout");
-}
-
-/* Reset the friggin' thing... */
-#define DMA_RESET(dma) do { \
-	struct sparc_dma_registers *regs = dma->regs;                      \
-	/* Let the current FIFO drain itself */                            \
-	sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN));                         \
-	/* Reset the logic */                                              \
-	regs->cond_reg |= (DMA_RST_SCSI);     /* assert */                 \
-	__delay(400);                         /* let the bits set ;) */    \
-	regs->cond_reg &= ~(DMA_RST_SCSI);    /* de-assert */              \
-	sparc_dma_enable_interrupts(regs);    /* Re-enable interrupts */   \
-	/* Enable FAST transfers if available */                           \
-	if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS;            \
-	dma->running = 0;                                                  \
-} while(0)
 
 #define for_each_dvma(dma) \
         for((dma) = dma_chain; (dma); (dma) = (dma)->next)
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/elf.h linux/include/asm-sparc64/elf.h
--- v2.1.18/linux/include/asm-sparc64/elf.h	Wed Dec 18 15:59:02 1996
+++ linux/include/asm-sparc64/elf.h	Mon Dec 30 12:00:02 1996
@@ -1,4 +1,4 @@
-/* $Id: elf.h,v 1.1 1996/11/20 15:27:38 davem Exp $ */
+/* $Id: elf.h,v 1.2 1996/12/26 13:25:25 davem Exp $ */
 #ifndef __ASM_SPARC64_ELF_H
 #define __ASM_SPARC64_ELF_H
 
@@ -23,8 +23,8 @@
 /*
  * These are used to set parameters in the core dumps.
  */
-#define ELF_ARCH	EM_SPARC
-#define ELF_CLASS	ELFCLASS32
+#define ELF_ARCH	EM_SPARC64
+#define ELF_CLASS	ELFCLASS64
 #define ELF_DATA	ELFDATA2MSB;
 
 #define USE_ELF_CORE_DUMP
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/head.h linux/include/asm-sparc64/head.h
--- v2.1.18/linux/include/asm-sparc64/head.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/head.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,40 @@
+/* $Id: head.h,v 1.2 1996/12/28 18:39:49 davem Exp $ */
+#ifndef _SPARC64_HEAD_H
+#define _SPARC64_HEAD_H
+
+#define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop;
+
+#define BTRAP(lvl)
+
+#define BTRAPTL1(lvl)
+
+#define CLEAN_WINDOW							\
+	clr	%o0;	clr	%o1;	clr	%o2;	clr	%o3;	\
+	clr	%o4;	clr	%o5;	clr	%o6;	clr	%o7;	\
+	clr	%l0;	clr	%l1;	clr	%l2;	clr	%l3;	\
+	clr	%l4;	clr	%l5;	clr	%l6;	clr	%l7;	\
+	rdpr %cleanwin, %g1; 		add %g1, 1, %g1;		\
+	wrpr %g1, 0x0, %cleanwin;	retry;				\
+	nop;		nop;		nop;		nop;
+
+#define TRAP(routine)			\
+	b	etrap;			\
+	 rd	%pc, %g7;		\
+	call	routine;		\
+	 add	%sp, REGWIN_SZ, %o0;	\
+	b	rtrap;			\
+	 subcc	%g0, %o0, %g0;		\
+	nop;				\
+	nop;
+
+#define TRAP_IRQ(routine, level)	\
+	b	etrap;			\
+	 rd	%pc, %g7;		\
+	add	%sp, REGWIN_SZ, %o0;	\
+	call	routine;		\
+	 mov	level, %o1;		\
+	b	rtrap;			\
+	 subcc	%g0, %o0, %g0;		\
+	nop;
+
+#endif /* !(_SPARC64_HEAD_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/io.h linux/include/asm-sparc64/io.h
--- v2.1.18/linux/include/asm-sparc64/io.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/io.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,62 @@
+/* $Id: io.h,v 1.1 1996/12/26 13:25:21 davem Exp $ */
+#ifndef __SPARC64_IO_H
+#define __SPARC64_IO_H
+
+#include <linux/kernel.h>
+
+#include <asm/page.h>      /* IO address mapping routines need this */
+#include <asm/system.h>
+
+extern void sun4c_mapioaddr(unsigned long, unsigned long, int bus_type, int rdonly);
+extern void srmmu_mapioaddr(unsigned long, unsigned long, int bus_type, int rdonly);
+
+extern __inline__ void mapioaddr(unsigned long physaddr, unsigned long virt_addr,
+				 int bus, int rdonly)
+{
+	switch(sparc_cpu_model) {
+	case sun4c:
+		sun4c_mapioaddr(physaddr, virt_addr, bus, rdonly);
+		break;
+	case sun4m:
+	case sun4d:
+	case sun4e:
+		srmmu_mapioaddr(physaddr, virt_addr, bus, rdonly);
+		break;
+	default:
+		printk("mapioaddr: Trying to map IO space for unsupported machine.\n");
+		printk("mapioaddr: sparc_cpu_model = %d\n", sparc_cpu_model);
+		printk("mapioaddr: Halting...\n");
+		halt();
+	};
+	return;
+}
+
+extern void srmmu_unmapioaddr(unsigned long virt);
+extern void sun4c_unmapioaddr(unsigned long virt);
+
+extern __inline__ void unmapioaddr(unsigned long virt_addr)
+{
+	switch(sparc_cpu_model) {
+	case sun4c:
+		sun4c_unmapioaddr(virt_addr);
+		break;
+	case sun4m:
+	case sun4d:
+	case sun4e:
+		srmmu_unmapioaddr(virt_addr);
+		break;
+	default:
+		printk("unmapioaddr: sparc_cpu_model = %d, halt...\n", sparc_cpu_model);
+		halt();
+	};
+	return;
+}
+
+extern void *sparc_alloc_io (void *, void *, int, char *, int, int);
+extern void sparc_free_io (void *, int);
+extern void *sparc_dvma_malloc (int, char *);
+
+#define virt_to_phys(x) __pa((unsigned long)(x))
+#define phys_to_virt(x) __va((unsigned long)(x))
+
+#endif /* !(__SPARC64_IO_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/iommu.h linux/include/asm-sparc64/iommu.h
--- v2.1.18/linux/include/asm-sparc64/iommu.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/iommu.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,73 @@
+/* iommu.h: Definitions for the sun5 IOMMU.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC64_IOMMU_H
+#define _SPARC64_IOMMU_H
+
+#include <asm/page.h>
+
+/* The iommu handles all virtual to physical address translations
+ * that occur between the SYSIO and physical memory.  Access by
+ * the cpu to IO registers and similar go over the UPA so are
+ * translated by the on chip TLB's.  The iommu and the TLB do
+ * not need to have the same translations at all, in fact most
+ * of the time the translations they handle are a disjoint set.
+ * Basically the iommu handles all SYSIO dvma translations.
+ */
+
+/* The IOMMU register set. */
+struct iommu_regs {
+	volatile unsigned long		csr;
+	volatile unsigned long		tsb_base;
+	volatile unsigned long		flush;
+	unsigned char _unused0[PAGE_SIZE - 0x18];
+
+	volatile unsigned long		va_diag;
+	volatile unsigned long		tag_compare;
+	unsigned char _unused1[0x100 - 0x10];
+
+	volatile unsigned long		lru_diag[0x80  / 8];
+	volatile unsigned long		tag_diag[0x80  / 8];
+	volatile unsigned long		ram_diag[0x100 / 8];
+};
+
+#define IOMMU_CTRL_IMPL     0xf000000000000000 /* Implementation                */
+#define IOMMU_CTRL_VERS     0x0f00000000000000 /* Version                       */
+#define IOMMU_CTRL_TSBSZ    0x0000000000070000 /* TSB Size                      */
+#define IOMMU_TSBSZ_1K      0x0000000000000000 /* TSB Table 1024 8-byte entries */
+#define IOMMU_TSBSZ_2K      0x0000000000010000 /* TSB Table 2048 8-byte entries */
+#define IOMMU_TSBSZ_4K      0x0000000000020000 /* TSB Table 4096 8-byte entries */
+#define IOMMU_TSBSZ_8K      0x0000000000030000 /* TSB Table 8192 8-byte entries */
+#define IOMMU_TSBSZ_16K     0x0000000000040000 /* TSB Table 16k 8-byte entries  */
+#define IOMMU_TSBSZ_32K     0x0000000000050000 /* TSB Table 32k 8-byte entries  */
+#define IOMMU_TSBSZ_64K     0x0000000000060000 /* TSB Table 64k 8-byte entries  */
+#define IOMMU_TSBSZ_128K    0x0000000000070000 /* TSB Table 128k 8-byte entries */
+#define IOMMU_CTRL_TBWSZ    0x0000000000000004 /* Assumed page size, 0=8k 1=64k */
+#define IOMMU_CTRL_DENAB    0x0000000000000002 /* Diagnostic mode enable        */
+#define IOMMU_CTRL_ENAB     0x0000000000000001 /* IOMMU Enable                  */
+
+/* The format of an iopte in the page tables, we only use 64k pages. */
+#define IOPTE_VALID         0x8000000000000000 /* IOPTE is valid                   */
+#define IOPTE_64K           0x2000000000000000 /* IOPTE is for 64k page            */
+#define IOPTE_STBUF         0x1000000000000000 /* DVMA can use streaming buffer    */
+#define IOPTE_INTRA         0x0800000000000000 /* XXX what does this thing do?     */
+#define IOPTE_PAGE          0x000001ffffffe000 /* Physical page number (PA[40:13]) */
+#define IOPTE_CACHE         0x0000000000000010 /* Cached (in UPA E-cache)          */
+#define IOPTE_WRITE         0x0000000000000002 /* Writeable                        */
+
+struct iommu_struct {
+	struct iommu_regs *regs;
+	iopte_t *page_table;
+
+	/* For convenience */
+	unsigned long start; /* First managed virtual address */
+	unsigned long end;   /* Last managed virtual address */
+};
+
+extern __inline__ void iommu_invalidate_page(struct iommu_regs *regs, unsigned long page)
+{
+	regs->flush = (page & (PAGE_MASK << 3));
+}
+
+#endif /* !(_SPARC_IOMMU_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/ipc.h linux/include/asm-sparc64/ipc.h
--- v2.1.18/linux/include/asm-sparc64/ipc.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/ipc.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,28 @@
+#ifndef __SPARC64_IPC_H__
+#define __SPARC64_IPC_H__
+
+/* 
+ * These are used to wrap system calls on the sparc.
+ *
+ * See arch/sparc64/kernel/sys_sparc.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/irq.h linux/include/asm-sparc64/irq.h
--- v2.1.18/linux/include/asm-sparc64/irq.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/irq.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,41 @@
+/* $Id: irq.h,v 1.1 1996/12/26 17:28:13 davem Exp $
+ * irq.h: IRQ registers on the 64-bit Sparc.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* XXX Write the sun5 specific code... XXX */
+
+#ifndef _SPARC64_IRQ_H
+#define _SPARC64_IRQ_H
+
+#include <linux/linkage.h>
+
+#include <asm/system.h>     /* For NCPUS */
+
+#define NR_IRQS    15
+
+/* Dave Redman (djhr@tadpole.co.uk)
+ * changed these to function pointers.. it saves cycles and will allow
+ * the irq dependencies to be split into different files at a later date
+ * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size.
+ */
+extern void (*disable_irq)(unsigned int);
+extern void (*enable_irq)(unsigned int);
+extern void (*clear_clock_irq)( void );
+extern void (*clear_profile_irq)( void );
+extern void (*load_profile_irq)( unsigned int timeout );
+extern void (*init_timers)(void (*lvl10_irq)(int, void *, struct pt_regs *));
+extern void claim_ticker14(void (*irq_handler)(int, void *, struct pt_regs *),
+			   int irq,
+			   unsigned int timeout);
+
+#ifdef __SMP__
+extern void (*set_cpu_int)(int, int);
+extern void (*clear_cpu_int)(int, int);
+extern void (*set_irq_udt)(int);
+#endif
+
+extern int request_fast_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, __const__ char *devname);
+
+#endif
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/lsu.h linux/include/asm-sparc64/lsu.h
--- v2.1.18/linux/include/asm-sparc64/lsu.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/lsu.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,18 @@
+/* $Id */
+#ifndef _SPARC64_LSU_H
+#define _SPARC64_LSU_H
+
+/* LSU Control Register */
+#define LSU_CONTROL_PM		0x000001fe00000000 /* Phys-watchpoint byte mask     */
+#define LSU_CONTROL_VM		0x00000001fe000000 /* Virt-watchpoint byte mask     */
+#define LSU_CONTROL_PR		0x0000000001000000 /* Phys-read watchpoint enable   */
+#define LSU_CONTROL_PW		0x0000000000800000 /* Phys-write watchpoint enable  */
+#define LSU_CONTROL_VR		0x0000000000400000 /* Virt-read watchpoint enable   */
+#define LSU_CONTROL_VW		0x0000000000200000 /* Virt-write watchpoint enable  */
+#define LSU_CONTROL_FM		0x00000000000ffff0 /* Parity mask enables.          */
+#define LSU_CONTROL_DM		0x0000000000000008 /* Data MMU enable.              */
+#define LSU_CONTROL_IM		0x0000000000000004 /* Instruction MMU enable.       */
+#define LSU_CONTROL_DC		0x0000000000000002 /* Data cache enable.            */
+#define LSU_CONTROL_IC		0x0000000000000001 /* Instruction cache enable.     */
+
+#endif /* !(_SPARC64_LSU_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/mmu_context.h linux/include/asm-sparc64/mmu_context.h
--- v2.1.18/linux/include/asm-sparc64/mmu_context.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/mmu_context.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,36 @@
+/* $Id: mmu_context.h,v 1.4 1996/12/28 18:39:51 davem Exp $ */
+#ifndef __SPARC64_MMU_CONTEXT_H
+#define __SPARC64_MMU_CONTEXT_H
+
+#include <asm/system.h>
+#include <asm/spitfire.h>
+
+#define NO_CONTEXT     -1
+
+#ifndef __ASSEMBLY__
+
+/* Initialize the context related info for a new mm_struct
+ * instance.
+ */
+#define init_new_context(mm) ((mm)->context = NO_CONTEXT)
+
+extern void spitfire_get_new_context(struct mm_struct *mm);
+
+extern __inline__ void get_mmu_context(struct task_struct *tsk)
+{
+	struct mm_struct *mm = tsk->mm;
+
+	if(tsk->mm->context == NO_CONTEXT)
+		spitfire_get_new_context(mm);
+
+	/* Get current set of user windows out of the cpu. */
+	flushw_user();
+
+	/* Jump into new ASN. */
+	spitfire_set_primary_context(mm->context);
+	spitfire_set_secondary_context(mm->context);
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC64_MMU_CONTEXT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/mostek.h linux/include/asm-sparc64/mostek.h
--- v2.1.18/linux/include/asm-sparc64/mostek.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/mostek.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,120 @@
+/* $Id: mostek.h,v 1.1 1996/12/26 13:25:22 davem Exp $
+ * mostek.h:  Describes the various Mostek time of day clock registers.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ */
+
+#ifndef _SPARC64_MOSTEK_H
+#define _SPARC64_MOSTEK_H
+
+#include <asm/idprom.h>
+
+/*       M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
+ *
+ *                             Data
+ * Address                                                 Function
+ *        Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
+ *   7ff  -     -     -     -    -     -     -     -       Year 00-99
+ *   7fe  0     0     0     -    -     -     -     -      Month 01-12
+ *   7fd  0     0     -     -    -     -     -     -       Date 01-31
+ *   7fc  0     FT    0     0    0     -     -     -        Day 01-07
+ *   7fb  KS    0     -     -    -     -     -     -      Hours 00-23
+ *   7fa  0     -     -     -    -     -     -     -    Minutes 00-59
+ *   7f9  ST    -     -     -    -     -     -     -    Seconds 00-59
+ *   7f8  W     R     S     -    -     -     -     -    Control
+ *
+ *   * ST is STOP BIT
+ *   * W is WRITE BIT
+ *   * R is READ BIT
+ *   * S is SIGN BIT
+ *   * FT is FREQ TEST BIT
+ *   * KS is KICK START BIT
+ */
+
+/* The Mostek 48t02 real time clock and NVRAM chip. The registers
+ * other than the control register are in binary coded decimal. Some
+ * control bits also live outside the control register.
+ */
+
+struct mostek48t02 {
+	volatile char eeprom[2008];	/* This is the eeprom, don't touch! */
+	struct idprom idprom;		/* The idprom lives here. */
+	volatile unsigned char creg;	/* Control register */
+	volatile unsigned char sec;	/* Seconds (0-59) */
+	volatile unsigned char min;	/* Minutes (0-59) */
+	volatile unsigned char hour;	/* Hour (0-23) */
+	volatile unsigned char dow;	/* Day of the week (1-7) */
+	volatile unsigned char dom;	/* Day of the month (1-31) */
+	volatile unsigned char month;	/* Month of year (1-12) */
+	volatile unsigned char year;	/* Year (0-99) */
+};
+
+extern struct mostek48t02 *mstk48t02_regs;
+
+/* Control register values. */
+#define	MSTK_CREG_WRITE	0x80	/* Must set this before placing values. */
+#define	MSTK_CREG_READ	0x40	/* Stop updates to allow a clean read. */
+#define	MSTK_CREG_SIGN	0x20	/* Slow/speed clock in calibration mode. */
+
+/* Control bits that live in the other registers. */
+#define	MSTK_STOP	0x80	/* Stop the clock oscillator. (sec) */
+#define	MSTK_KICK_START	0x80	/* Kick start the clock chip. (hour) */
+#define MSTK_FREQ_TEST	0x40	/* Frequency test mode. (day) */
+
+#define MSTK_YEAR_ZERO       1968   /* If year reg has zero, it is 1968. */
+#define MSTK_CVT_YEAR(yr)  ((yr) + MSTK_YEAR_ZERO)
+
+/* Masks that define how much space each value takes up. */
+#define	MSTK_SEC_MASK	0x7f
+#define	MSTK_MIN_MASK	0x7f
+#define	MSTK_HOUR_MASK	0x3f
+#define	MSTK_DOW_MASK	0x07
+#define	MSTK_DOM_MASK	0x3f
+#define	MSTK_MONTH_MASK	0x1f
+#define	MSTK_YEAR_MASK	0xff
+
+/* Binary coded decimal conversion macros. */
+#define MSTK_REGVAL_TO_DECIMAL(x)  (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
+#define MSTK_DECIMAL_TO_REGVAL(x)  ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
+
+/* Generic register set and get macros for internal use. */
+#define MSTK_GET(regs,var,mask) (MSTK_REGVAL_TO_DECIMAL(regs->var & MSTK_ ## mask ## _MASK))
+#define MSTK_SET(regs,var,value,mask) do { regs->var &= ~(MSTK_ ## mask ## _MASK); regs->var |= MSTK_DECIMAL_TO_REGVAL(value) & (MSTK_ ## mask ## _MASK); } while (0)
+
+/* Macros to make register access easier on our fingers. These give you
+ * the decimal value of the register requested if applicable. You pass
+ * the a pointer to a 'struct mostek48t02'.
+ */
+#define	MSTK_REG_CREG(regs)	(regs->creg)
+#define	MSTK_REG_SEC(regs)	MSTK_GET(regs,sec,SEC)
+#define	MSTK_REG_MIN(regs)	MSTK_GET(regs,min,MIN)
+#define	MSTK_REG_HOUR(regs)	MSTK_GET(regs,hour,HOUR)
+#define	MSTK_REG_DOW(regs)	MSTK_GET(regs,dow,DOW)
+#define	MSTK_REG_DOM(regs)	MSTK_GET(regs,dom,DOM)
+#define	MSTK_REG_MONTH(regs)	MSTK_GET(regs,month,MONTH)
+#define	MSTK_REG_YEAR(regs)	MSTK_GET(regs,year,YEAR)
+
+#define	MSTK_SET_REG_SEC(regs,value)	MSTK_SET(regs,sec,value,SEC)
+#define	MSTK_SET_REG_MIN(regs,value)	MSTK_SET(regs,min,value,MIN)
+#define	MSTK_SET_REG_HOUR(regs,value)	MSTK_SET(regs,hour,value,HOUR)
+#define	MSTK_SET_REG_DOW(regs,value)	MSTK_SET(regs,dow,value,DOW)
+#define	MSTK_SET_REG_DOM(regs,value)	MSTK_SET(regs,dom,value,DOM)
+#define	MSTK_SET_REG_MONTH(regs,value)	MSTK_SET(regs,month,value,MONTH)
+#define	MSTK_SET_REG_YEAR(regs,value)	MSTK_SET(regs,year,value,YEAR)
+
+
+/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
+ * same (basically) layout of the 48t02 chip except for the extra
+ * NVRAM on board (8 KB against the 48t02's 2 KB).
+ */
+struct mostek48t08 {
+	char offset[6*1024];         /* Magic things may be here, who knows? */
+	struct mostek48t02 regs;     /* Here is what we are interested in.   */
+};
+extern struct mostek48t08 *mstk48t08_regs;
+
+enum sparc_clock_type {	MSTK48T02, MSTK48T08, MSTK_INVALID };
+extern enum sparc_clock_type sp_clock_typ;
+
+#endif /* !(_SPARC64_MOSTEK_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/namei.h linux/include/asm-sparc64/namei.h
--- v2.1.18/linux/include/asm-sparc64/namei.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/namei.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,56 @@
+/* $Id: namei.h,v 1.1 1996/12/26 13:25:22 davem Exp $
+ * linux/include/asm-sparc64/namei.h
+ *
+ * Routines to handle famous /usr/gnemul/s*.
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __SPARC64_NAMEI_H
+#define __SPARC64_NAMEI_H
+
+#define SPARC_BSD_EMUL "usr/gnemul/sunos/"
+#define SPARC_SOL_EMUL "usr/gnemul/solaris/"
+
+#define gnemul_namei(pathname, base, follow_links, res_inode) ({			\
+ if ((current->personality & (PER_BSD|PER_SVR4)) && !base && *pathname == '/') {	\
+	struct inode *emul_ino;								\
+	int namelen;									\
+	const char *name;								\
+											\
+	while (*pathname == '/')							\
+		pathname++;								\
+	current->fs->root->i_count++;							\
+	if (dir_namei (current->personality & PER_BSD ? SPARC_BSD_EMUL : SPARC_SOL_EMUL,\
+		&namelen, &name, current->fs->root, &emul_ino) >= 0 && emul_ino) {	\
+			*res_inode = NULL;						\
+			if (_namei (pathname, emul_ino, follow_links, res_inode) >= 0 &&\
+					*res_inode) 					\
+				return 0;						\
+	}										\
+	base = current->fs->root;							\
+	base->i_count++;								\
+  }											\
+})
+
+#define gnemul_open_namei(pathname, flag, mode, res_inode, base) ({			\
+  if ((current->personality & (PER_BSD|PER_SVR4)) && !base && *pathname == '/') {	\
+	struct inode *emul_ino;								\
+	int namelen;									\
+	const char *name;								\
+											\
+	while (*pathname == '/')							\
+		pathname++;								\
+	current->fs->root->i_count++;							\
+	if (dir_namei (current->personality & PER_BSD ? SPARC_BSD_EMUL : SPARC_SOL_EMUL,\
+		  &namelen, &name, current->fs->root, &emul_ino) >= 0 && emul_ino) {	\
+		*res_inode = NULL;							\
+		if (open_namei (pathname, flag, mode, res_inode, emul_ino) >= 0 && 	\
+				*res_inode)						\
+			return 0;							\
+	}										\
+	base = current->fs->root;							\
+	base->i_count++;								\
+  }											\
+})
+
+#endif /* __SPARC64_NAMEI_H */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/openprom.h linux/include/asm-sparc64/openprom.h
--- v2.1.18/linux/include/asm-sparc64/openprom.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/openprom.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,210 @@
+/* $Id: openprom.h,v 1.1 1996/12/26 14:22:32 davem Exp $ */
+#ifndef __SPARC64_OPENPROM_H
+#define __SPARC64_OPENPROM_H
+
+/* openprom.h:  Prom structures and defines for access to the OPENBOOT
+ *              prom routines and data areas.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* Empirical constants... */
+#define KADB_DEBUGGER_BEGVM     0xffc00000    /* Where kern debugger is in virt-mem */
+#define	LINUX_OPPROM_BEGVM	0xffd00000
+#define	LINUX_OPPROM_ENDVM	0xfff00000
+#define	LINUX_OPPROM_MAGIC      0x10010407
+
+#ifndef __ASSEMBLY__
+/* V0 prom device operations. */
+struct linux_dev_v0_funcs {
+	int (*v0_devopen)(char *device_str);
+	int (*v0_devclose)(int dev_desc);
+	int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+	int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+	int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
+	int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
+	int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+	int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+	int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
+};
+
+/* V2 and later prom device operations. */
+struct linux_dev_v2_funcs {
+	int (*v2_inst2pkg)(int d);	/* Convert ihandle to phandle */
+	char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
+	void (*v2_dumb_mem_free)(char *va, unsigned sz);
+
+	/* To map devices into virtual I/O space. */
+	char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
+	void (*v2_dumb_munmap)(char *virta, unsigned size);
+
+	int (*v2_dev_open)(char *devpath);
+	void (*v2_dev_close)(int d);
+	int (*v2_dev_read)(int d, char *buf, int nbytes);
+	int (*v2_dev_write)(int d, char *buf, int nbytes);
+	int (*v2_dev_seek)(int d, int hi, int lo);
+
+	/* Never issued (multistage load support) */
+	void (*v2_wheee2)(void);
+	void (*v2_wheee3)(void);
+};
+
+struct linux_mlist_v0 {
+	struct linux_mlist_v0 *theres_more;
+	char *start_adr;
+	unsigned num_bytes;
+};
+
+struct linux_mem_v0 {
+	struct linux_mlist_v0 **v0_totphys;
+	struct linux_mlist_v0 **v0_prommap;
+	struct linux_mlist_v0 **v0_available; /* What we can use */
+};
+
+/* Arguments sent to the kernel from the boot prompt. */
+struct linux_arguments_v0 {
+	char *argv[8];
+	char args[100];
+	char boot_dev[2];
+	int boot_dev_ctrl;
+	int boot_dev_unit;
+	int dev_partition;
+	char *kernel_file_name;
+	void *aieee1;           /* XXX */
+};
+
+/* V2 and up boot things. */
+struct linux_bootargs_v2 {
+	char **bootpath;
+	char **bootargs;
+	int *fd_stdin;
+	int *fd_stdout;
+};
+
+/* The top level PROM vector. */
+struct linux_romvec {
+	/* Version numbers. */
+	unsigned int pv_magic_cookie;
+	unsigned int pv_romvers;
+	unsigned int pv_plugin_revision;
+	unsigned int pv_printrev;
+
+	/* Version 0 memory descriptors. */
+	struct linux_mem_v0 pv_v0mem;
+
+	/* Node operations. */
+	struct linux_nodeops *pv_nodeops;
+
+	char **pv_bootstr;
+	struct linux_dev_v0_funcs pv_v0devops;
+
+	char *pv_stdin;
+	char *pv_stdout;
+#define	PROMDEV_KBD	0		/* input from keyboard */
+#define	PROMDEV_SCREEN	0		/* output to screen */
+#define	PROMDEV_TTYA	1		/* in/out to ttya */
+#define	PROMDEV_TTYB	2		/* in/out to ttyb */
+
+	/* Blocking getchar/putchar.  NOT REENTRANT! (grr) */
+	int (*pv_getchar)(void);
+	void (*pv_putchar)(int ch);
+
+	/* Non-blocking variants. */
+	int (*pv_nbgetchar)(void);
+	int (*pv_nbputchar)(int ch);
+
+	void (*pv_putstr)(char *str, int len);
+
+	/* Miscellany. */
+	void (*pv_reboot)(char *bootstr);
+	void (*pv_printf)(__const__ char *fmt, ...);
+	void (*pv_abort)(void);
+	__volatile__ int *pv_ticks;
+	void (*pv_halt)(void);
+	void (**pv_synchook)(void);
+
+	/* Evaluate a forth string, not different proto for V0 and V2->up. */
+	union {
+		void (*v0_eval)(int len, char *str);
+		void (*v2_eval)(char *str);
+	} pv_fortheval;
+
+	struct linux_arguments_v0 **pv_v0bootargs;
+
+	/* Get ether address. */
+	unsigned int (*pv_enaddr)(int d, char *enaddr);
+
+	struct linux_bootargs_v2 pv_v2bootargs;
+	struct linux_dev_v2_funcs pv_v2devops;
+
+	int filler[15];
+
+	/* This one is sun4c/sun4 only. */
+	void (*pv_setctxt)(int ctxt, char *va, int pmeg);
+
+	/* Prom version 3 Multiprocessor routines. This stuff is crazy.
+	 * No joke. Calling these when there is only one cpu probably
+	 * crashes the machine, have to test this. :-)
+	 */
+
+	/* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
+	 * 'thiscontext' executing at address 'prog_counter'
+	 */
+	int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
+			   int thiscontext, char *prog_counter);
+
+	/* v3_cpustop() will cause cpu 'whichcpu' to stop executing
+	 * until a resume cpu call is made.
+	 */
+	int (*v3_cpustop)(unsigned int whichcpu);
+
+	/* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
+	 * resume cpu call is made.
+	 */
+	int (*v3_cpuidle)(unsigned int whichcpu);
+
+	/* v3_cpuresume() will resume processor 'whichcpu' executing
+	 * starting with whatever 'pc' and 'npc' were left at the
+	 * last 'idle' or 'stop' call.
+	 */
+	int (*v3_cpuresume)(unsigned int whichcpu);
+};
+
+/* Routines for traversing the prom device tree. */
+struct linux_nodeops {
+	int (*no_nextnode)(int node);
+	int (*no_child)(int node);
+	int (*no_proplen)(int node, char *name);
+	int (*no_getprop)(int node, char *name, char *val);
+	int (*no_setprop)(int node, char *name, char *val, int len);
+	char * (*no_nextprop)(int node, char *name);
+};
+
+/* More fun PROM structures for device probing. */
+#define PROMREG_MAX     16
+#define PROMVADDR_MAX   16
+#define PROMINTR_MAX    15
+
+struct linux_prom_registers {
+	int which_io;         /* is this in OBIO space? */
+	char *phys_addr;      /* The physical address of this register */
+	int reg_size;         /* How many bytes does this register take up? */
+};
+
+struct linux_prom_irqs {
+	int pri;    /* IRQ priority */
+	int vector; /* This is foobar, what does it do? */
+};
+
+/* Element of the "ranges" vector */
+struct linux_prom_ranges {
+	unsigned int ot_child_space;
+	unsigned int ot_child_base;		/* Bus feels this */
+	unsigned int ot_parent_space;
+	unsigned int ot_parent_base;		/* CPU looks from here */
+	unsigned int or_size;
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC64_OPENPROM_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/openpromio.h linux/include/asm-sparc64/openpromio.h
--- v2.1.18/linux/include/asm-sparc64/openpromio.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/openpromio.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,70 @@
+#ifndef	_SPARC64_OPENPROMIO_H
+#define	_SPARC64_OPENPROMIO_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/*
+ * SunOS and Solaris /dev/openprom definitions. The ioctl values
+ * were chosen to be exactly equal to the SunOS equivalents.
+ */
+
+struct openpromio
+{
+	u_int	oprom_size;		/* Actual size of the oprom_array. */
+	char	oprom_array[1];		/* Holds property names and values. */
+};
+
+#define	OPROMMAXPARAM	4096		/* Maximum size of oprom_array. */
+
+#define	OPROMGETOPT		0x20004F01
+#define	OPROMSETOPT		0x20004F02
+#define	OPROMNXTOPT		0x20004F03
+#define	OPROMSETOPT2		0x20004F04
+#define	OPROMNEXT		0x20004F05
+#define	OPROMCHILD		0x20004F06
+#define	OPROMGETPROP		0x20004F07
+#define	OPROMNXTPROP		0x20004F08
+#define	OPROMU2P		0x20004F09
+#define	OPROMGETCONS		0x20004F0A
+#define	OPROMGETFBNAME		0x20004F0B
+#define	OPROMGETBOOTARGS	0x20004F0C
+
+/*
+ * Return values from OPROMGETCONS:
+ */
+
+#define OPROMCONS_NOT_WSCONS    0
+#define OPROMCONS_STDIN_IS_KBD  0x1     /* stdin device is kbd */
+#define OPROMCONS_STDOUT_IS_FB  0x2     /* stdout is a framebuffer */
+#define OPROMCONS_OPENPROM      0x4     /* supports openboot */
+
+
+/*
+ *  NetBSD/OpenBSD /dev/openprom definitions.
+ */
+
+struct opiocdesc
+{
+	int	op_nodeid;		/* PROM Node ID (value-result) */
+	int	op_namelen;		/* Length of op_name. */
+	char	*op_name;		/* Pointer to the property name. */
+	int	op_buflen;		/* Length of op_buf (value-result) */
+	char	*op_buf;		/* Pointer to buffer. */
+};
+
+#define	OPIOCGET	_IOWR('O', 1, struct opiocdesc)
+#define	OPIOCSET	_IOW('O', 2, struct opiocdesc)
+#define	OPIOCNEXTPROP	_IOWR('O', 3, struct opiocdesc)
+#define	OPIOCGETOPTNODE	_IOR('O', 4, int)
+#define	OPIOCGETNEXT	_IOWR('O', 5, int)
+#define	OPIOCGETCHILD	_IOWR('O', 6, int)
+
+
+#ifdef __KERNEL__
+int openprom_init(void);
+#endif
+
+
+#endif /* _SPARC64_OPENPROMIO_H */
+
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/oplib.h linux/include/asm-sparc64/oplib.h
--- v2.1.18/linux/include/asm-sparc64/oplib.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/oplib.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,279 @@
+/* $Id: oplib.h,v 1.2 1996/12/27 08:49:07 jj Exp $
+ * oplib.h:  Describes the interface and available routines in the
+ *           Linux Prom library.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#ifndef __SPARC64_OPLIB_H
+#define __SPARC64_OPLIB_H
+
+#include <asm/openprom.h>
+
+/* Enumeration to describe the prom major version we have detected. */
+enum prom_major_version {
+	PROM_V0,      /* Original sun4c V0 prom */
+	PROM_V2,      /* sun4c and early sun4m V2 prom */
+	PROM_V3,      /* sun4m and later, up to sun4d/sun4e machines V3 */
+	PROM_P1275,   /* IEEE compliant ISA based Sun PROM, only sun4u */
+        PROM_AP1000,  /* actually no prom at all */
+};
+
+extern enum prom_major_version prom_vers;
+/* Revision, and firmware revision. */
+extern unsigned int prom_rev, prom_prev;
+
+/* Root node of the prom device tree, this stays constant after
+ * initialization is complete.
+ */
+extern int prom_root_node;
+
+/* The functions... */
+
+/* You must call prom_init() before using any of the library services,
+ * preferably as early as possible.  Pass it the romvec pointer.
+ */
+extern void prom_init(void *cif_handler, void *cif_stack);
+
+/* Boot argument acquisition, returns the boot command line string. */
+extern char *prom_getbootargs(void);
+
+/* Device utilities. */
+
+/* Device operations. */
+
+/* Open the device described by the passed string.  Note, that the format
+ * of the string is different on V0 vs. V2->higher proms.  The caller must
+ * know what he/she is doing!  Returns the device descriptor, an int.
+ */
+extern int prom_devopen(char *device_string);
+
+/* Close a previously opened device described by the passed integer
+ * descriptor.
+ */
+extern int prom_devclose(int device_handle);
+
+/* Do a seek operation on the device described by the passed integer
+ * descriptor.
+ */
+extern void prom_seek(int device_handle, unsigned int seek_hival,
+		      unsigned int seek_lowval);
+
+/* Machine memory configuration routine. */
+
+/* This function returns a V0 format memory descriptor table, it has three
+ * entries.  One for the total amount of physical ram on the machine, one
+ * for the amount of physical ram available, and one describing the virtual
+ * areas which are allocated by the prom.  So, in a sense the physical
+ * available is a calculation of the total physical minus the physical mapped
+ * by the prom with virtual mappings.
+ *
+ * These lists are returned pre-sorted, this should make your life easier
+ * since the prom itself is way too lazy to do such nice things.
+ */
+extern struct linux_mem_v0 *prom_meminfo(void);
+
+/* Miscellaneous routines, don't really fit in any category per se. */
+
+/* Reboot the machine with the command line passed. */
+extern void prom_reboot(char *boot_command);
+
+/* Evaluate the forth string passed. */
+extern void prom_feval(char *forth_string);
+
+/* Enter the prom, with possibility of continuation with the 'go'
+ * command in newer proms.
+ */
+extern void prom_cmdline(void);
+
+/* Enter the prom, with no chance of continuation for the stand-alone
+ * which calls this.
+ */
+extern void prom_halt(void);
+
+/* Set the PROM 'sync' callback function to the passed function pointer.
+ * When the user gives the 'sync' command at the prom prompt while the
+ * kernel is still active, the prom will call this routine.
+ *
+ */
+typedef void (*sync_func_t)(long *cmd);
+extern void prom_setsync(sync_func_t func_ptr);
+
+/* Acquire the IDPROM of the root node in the prom device tree.  This
+ * gets passed a buffer where you would like it stuffed.  The return value
+ * is the format type of this idprom or 0xff on error.
+ */
+extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
+
+/* Get the prom major version. */
+extern int prom_version(void);
+
+/* Get the prom plugin revision. */
+extern int prom_getrev(void);
+
+/* Get the prom firmware revision. */
+extern int prom_getprev(void);
+
+/* Character operations to/from the console.... */
+
+/* Non-blocking get character from console. */
+extern int prom_nbgetchar(void);
+
+/* Non-blocking put character to console. */
+extern int prom_nbputchar(char character);
+
+/* Blocking get character from console. */
+extern char prom_getchar(void);
+
+/* Blocking put character to console. */
+extern void prom_putchar(char character);
+
+/* Prom's internal printf routine, don't use in kernel/boot code. */
+void prom_printf(char *fmt, ...);
+
+/* Query for input device type */
+
+enum prom_input_device {
+	PROMDEV_IKBD,			/* input from keyboard */
+	PROMDEV_ITTYA,			/* input from ttya */
+	PROMDEV_ITTYB,			/* input from ttyb */
+	PROMDEV_I_UNK,
+};
+
+extern enum prom_input_device prom_query_input_device(void);
+
+/* Query for output device type */
+
+enum prom_output_device {
+	PROMDEV_OSCREEN,		/* to screen */
+	PROMDEV_OTTYA,			/* to ttya */
+	PROMDEV_OTTYB,			/* to ttyb */
+	PROMDEV_O_UNK,
+};
+
+extern enum prom_output_device prom_query_output_device(void);
+
+/* Multiprocessor operations... */
+
+/* Start the CPU with the given device tree node, context table, and context
+ * at the passed program counter.
+ */
+extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
+			 int context, char *program_counter);
+
+/* Stop the CPU with the passed device tree node. */
+extern int prom_stopcpu(int cpunode);
+
+/* Idle the CPU with the passed device tree node. */
+extern int prom_idlecpu(int cpunode);
+
+/* Re-Start the CPU with the passed device tree node. */
+extern int prom_restartcpu(int cpunode);
+
+/* PROM device tree traversal functions... */
+
+/* Get the child node of the given node, or zero if no child exists. */
+extern int prom_getchild(int parent_node);
+
+/* Get the next sibling node of the given node, or zero if no further
+ * siblings exist.
+ */
+extern int prom_getsibling(int node);
+
+/* Get the length, at the passed node, of the given property type.
+ * Returns -1 on error (ie. no such property at this node).
+ */
+extern int prom_getproplen(int thisnode, char *property);
+
+/* Fetch the requested property using the given buffer.  Returns
+ * the number of bytes the prom put into your buffer or -1 on error.
+ */
+extern int prom_getproperty(int thisnode, char *property,
+			    char *prop_buffer, int propbuf_size);
+
+/* Acquire an integer property. */
+extern int prom_getint(int node, char *property);
+
+/* Acquire an integer property, with a default value. */
+extern int prom_getintdefault(int node, char *property, int defval);
+
+/* Acquire a boolean property, 0=FALSE 1=TRUE. */
+extern int prom_getbool(int node, char *prop);
+
+/* Acquire a string property, null string on error. */
+extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
+
+/* Does the passed node have the given "name"? YES=1 NO=0 */
+extern int prom_nodematch(int thisnode, char *name);
+
+/* Puts in buffer a prom name in the form name@x,y or name (x for which_io 
+ * and y for first regs phys address
+ */
+extern int prom_getname(int node, char *buf, int buflen);
+
+/* Search all siblings starting at the passed node for "name" matching
+ * the given string.  Returns the node on success, zero on failure.
+ */
+extern int prom_searchsiblings(int node_start, char *name);
+
+/* Return the first property type, as a string, for the given node.
+ * Returns a null string on error. Buffer should be at least 32B long.
+ */
+extern char *prom_firstprop(int node, char *buffer);
+
+/* Returns the next property after the passed property for the given
+ * node.  Returns null string on failure. Buffer should be at least 32B long.
+ */
+extern char *prom_nextprop(int node, char *prev_property, char *buffer);
+
+/* Returns 1 if the specified node has given property. */
+extern int prom_node_has_property(int node, char *property);
+
+/* Returns phandle of the path specified */
+extern int prom_finddevice(char *name);
+
+/* Set the indicated property at the given node with the passed value.
+ * Returns the number of bytes of your value that the prom took.
+ */
+extern int prom_setprop(int node, char *prop_name, char *prop_value,
+			int value_size);
+			
+extern int prom_pathtoinode(char *path);
+extern int prom_inst2pkg(int);
+
+/* Dorking with Bus ranges... */
+
+/* Adjust reg values with the passed ranges. */
+extern void prom_adjust_regs(struct linux_prom_registers *regp, int nregs,
+			     struct linux_prom_ranges *rangep, int nranges);
+
+/* Adjust child ranges with the passed parent ranges. */
+extern void prom_adjust_ranges(struct linux_prom_ranges *cranges, int ncranges,
+			       struct linux_prom_ranges *pranges, int npranges);
+
+/* Apply promlib probed OBIO ranges to registers. */
+extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
+
+/* Apply ranges of any prom node (and optionally parent node as well) to registers. */
+extern void prom_apply_generic_ranges(int node, int parent, 
+				      struct linux_prom_registers *sbusregs, int nregs);
+				      
+extern long (*prom_command)(char *, long, ...);
+				   
+
+#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
+
+/* We support at most 16 input and 1 output argument */
+#define P1275_ARG_NUMBER		0
+#define P1275_ARG_IN_STRING		1
+#define P1275_ARG_OUT_BUF		2
+#define P1275_ARG_OUT_32B		3
+#define P1275_ARG_IN_FUNCTION		4
+
+#define P1275_IN(x) ((x) & 0xf)
+#define P1275_OUT(x) (((x) << 4) & 0xf0)
+#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
+#define P1275_ARG(n,x) ((x) << ((n)*3 + 8)
+
+#endif /* !(__SPARC64_OPLIB_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/page.h linux/include/asm-sparc64/page.h
--- v2.1.18/linux/include/asm-sparc64/page.h	Wed Dec 18 15:59:02 1996
+++ linux/include/asm-sparc64/page.h	Mon Dec 30 12:00:03 1996
@@ -1,14 +1,20 @@
-/* $Id: page.h,v 1.2 1996/12/02 00:01:06 davem Exp $ */
+/* $Id: page.h,v 1.4 1996/12/28 18:39:51 davem Exp $ */
 
 #ifndef _SPARC64_PAGE_H
 #define _SPARC64_PAGE_H
 
 #define PAGE_SHIFT   13
+
+#ifndef __ASSEMBLY__
+
 #define PAGE_SIZE    (1UL << PAGE_SHIFT)
 #define PAGE_MASK    (~(PAGE_SIZE-1))
 
 #ifdef __KERNEL__
 
+#define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from)	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+
 #define STRICT_MM_TYPECHECKS
 
 #ifdef STRICT_MM_TYPECHECKS
@@ -63,7 +69,9 @@
 #define __pgprot(x)	(x)
 #define __iopgprot(x)	(x)
 
-#endif
+#endif /* (STRICT_MM_TYPECHECKS) */
+
+#endif /* !(__ASSEMBLY__) */
 
 #define TASK_UNMAPPED_BASE	0x0000000070000000UL
 
@@ -75,6 +83,8 @@
 #define __va(x)			((void *)((unsigned long) (x) + PAGE_OFFSET))
 #define MAP_NR(addr)		(__pa(addr) >> PAGE_SHIFT)
 
+#ifndef __ASSEMBLY__
+
 /* The following structure is used to hold the physical
  * memory configuration of the machine.  This is filled in
  * probe_memory() and is later used by mem_init() to set up
@@ -92,6 +102,8 @@
 
 extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
 
-#endif /* __KERNEL__ */
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__KERNEL__) */
 
-#endif /* _SPARC64_PAGE_H */
+#endif /* !(_SPARC64_PAGE_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/pgtable.h linux/include/asm-sparc64/pgtable.h
--- v2.1.18/linux/include/asm-sparc64/pgtable.h	Wed Dec 18 15:59:02 1996
+++ linux/include/asm-sparc64/pgtable.h	Mon Dec 30 12:00:03 1996
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.1 1996/12/02 00:01:17 davem Exp $
+/* $Id: pgtable.h,v 1.8 1996/12/28 18:39:52 davem Exp $
  * pgtable.h: SpitFire page table operations.
  *
  * Copyright 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -11,10 +11,13 @@
  * the SpitFire page tables.
  */
 
+#include <asm/spitfire.h>
 #include <asm/asi.h>
 #include <asm/mmu_context.h>
 #include <asm/system.h>
 
+#ifndef __ASSEMBLY__
+
 /* Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
@@ -42,6 +45,8 @@
 #define VMALLOC_START		0xFFFFFE0000000000UL
 #define VMALLOC_VMADDR(x)	((unsigned long)(x))
 
+#endif /* !(__ASSEMBLY__) */
+
 /* SpitFire TTE bits. */
 #define _PAGE_VALID	0x8000000000000000UL	/* Valid TTE                          */
 #define _PAGE_R		0x8000000000000000UL	/* Used to keep ref bit up to date    */
@@ -77,7 +82,6 @@
 
 #define _PFN_MASK	_PAGE_PADDR
 
-#define _PAGE_TABLE	(_PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS)
 #define _PAGE_CHG_MASK	(_PFN_MASK | _PAGE_MODIFIED | _PAGE_ACCESSED)
 
 #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_CACHE)
@@ -106,29 +110,18 @@
 #define __S110	PAGE_SHARED
 #define __S111	PAGE_SHARED
 
+#ifndef __ASSEMBLY__
+
 extern pte_t __bad_page(void);
 extern pmd_t *__bad_pagetable(void);
 extern unsigned long __zero_page(void);
 
 #define BAD_PAGETABLE	__bad_pagetable()
 #define BAD_PAGE	__bad_page()
-#define ZERO_PAGE	__zero_page()
 
-/* Cache and TLB flush operations. */
-
-extern __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
-{
-	__asm__ __volatile__("stxa	%0, [%1] %2"
-			     : /* No outputs */
-			     : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
-}
+#define ZERO_PAGE	PAGE_OFFSET
 
-extern __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
-{
-	__asm__ __volatile__("stxa	%0, [%1] %2"
-			     : /* No outputs */
-			     : "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
-}
+/* Cache and TLB flush operations. */
 
 /* This is a bit tricky to do most efficiently.  The I-CACHE on the
  * SpitFire will snoop stores from _other_ processors and changes done
@@ -162,9 +155,9 @@
 	flush		%0 + 0x30
 	flush		%0 + 0x38
 	subcc		%1, 0x40, %1
-	bge,pt		%icc, 1b
+	bge,pt		%%icc, 1b
 	 add		%2, %1, %0
-"	: "=&r" (page), "=&r" (temp),
+"	: "=&r" (page), "=&r" (temp)
 	: "r" (page), "0" (page + PAGE_SIZE - 0x40), "1" (PAGE_SIZE - 0x40));
 }
 
@@ -178,6 +171,9 @@
 		spitfire_put_icache_tag(addr, 0x0UL);
 		membar("#Sync");
 	}
+
+	/* Kill the pipeline. */
+	flushi(PAGE_OFFSET);
 }
 
 extern __inline__ void flush_cache_mm(struct mm_struct *mm)
@@ -192,6 +188,9 @@
 			membar("#Sync");
 		}
 	}
+
+	/* Kill the pipeline. */
+	flushi(PAGE_OFFSET);
 }
 
 extern __inline__ void flush_cache_range(struct mm_struct *mm, unsigned long start,
@@ -205,6 +204,9 @@
 			spitfire_put_icache_tag(addr, 0x0UL);
 			membar("#Sync");
 		}
+
+		/* Kill the pipeline. */
+		flushi(PAGE_OFFSET);
 	}
 }
 
@@ -234,12 +236,12 @@
 	for(entry = 0; entry < 64; entry++) {
 		unsigned long dtag, itag;
 
-		dtag = spitfire_get_dtlb_tag(entry);
-		itag = spitfire_get_itlb_tag(entry);
+		dtag = spitfire_get_dtlb_data(entry);
+		itag = spitfire_get_itlb_data(entry);
 		if(!(dtag & _PAGE_L))
-			spitfire_put_dtlb_tag(entry, 0x0UL);
+			spitfire_put_dtlb_data(entry, 0x0UL);
 		if(!(itag & _PAGE_L))
-			spitfire_put_itlb_tag(entry, 0x0UL);
+			spitfire_put_itlb_data(entry, 0x0UL);
 	}
 }
 
@@ -271,6 +273,7 @@
 	struct mm_struct *mm = vma->vm_mm;
 
 	if(mm->context != NO_CONTEXT) {
+		page &= PAGE_MASK;
 		spitfire_set_secondary_context(mm->context);
 		if(vma->vm_flags & VM_EXEC)
 			spitfire_flush_itlb_secondary_page(page);
@@ -288,32 +291,32 @@
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
 
 extern inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
-{ pmd_val(*pmdp) = _PAGE_TABLE | ((unsigned long) ptep); }
+{ pmd_val(*pmdp) = ((unsigned long) ptep) - PAGE_OFFSET; }
 
 extern inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
-{ pgd_val(*pgdp) = _PAGE_TABLE | ((unsigned long) pmdp); }
+{ pgd_val(*pgdp) = ((unsigned long) pmdp) - PAGE_OFFSET; }
 
 extern inline unsigned long pte_page(pte_t pte)
 { return PAGE_OFFSET + (pte_val(pte) & _PFN_MASK); }
 
 extern inline unsigned long pmd_page(pmd_t pmd)
-{ return (pmd_val(pmd) & PAGE_MASK); }
+{ return (pmd_val(pmd) + PAGE_OFFSET); }
 
 extern inline unsigned long pgd_page(pgd_t pgd)
-{ return (pgd_val(pgd) & PAGE_MASK); }
+{ return (pgd_val(pgd) + PAGE_OFFSET); }
 
 extern inline int pte_none(pte_t pte) 		{ return !pte_val(pte); }
 extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_PRESENT; }
-extern inline void pte_cleat(pte_t *pte)	{ pte_val(*pte) = 0; }
+extern inline void pte_clear(pte_t *pte)	{ pte_val(*pte) = 0; }
 
 extern inline int pmd_none(pmd_t pmd)		{ return !pmd_val(pmd); }
-extern inline int pmd_bad(pmd_t pmd)		{ return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE; }
-extern inline int pmd_present(pmd_t pmd)	{ return pmd_val(pmd) & _PAGE_PRESENT; }
+extern inline int pmd_bad(pmd_t pmd)		{ return (pmd_val(pmd) & ~PAGE_MASK); }
+extern inline int pmd_present(pmd_t pmd)	{ return pmd_val(pmd); }
 extern inline void pmd_clear(pmd_t *pmdp)	{ pmd_val(*pmdp) = 0; }
 
 extern inline int pgd_none(pgd_t pgd)		{ return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd)		{ return (pgd_val(pgd) & ~PAGE_MASK) != _PAGE_TABLE; }
-extern inline int pgd_present(pgd_t pgd)	{ return pgd_val(pgd) & _PAGE_PRESENT; }
+extern inline int pgd_bad(pgd_t pgd)		{ return (pgd_val(pgd) & ~PAGE_MASK); }
+extern inline int pgd_present(pgd_t pgd)	{ return pgd_val(pgd); }
 extern inline void pgd_clear(pgd_t *pgdp)	{ pgd_val(*pgdp) = 0; }
 
 /* The following only work if pte_present() is true.
@@ -331,7 +334,7 @@
 { return __pte(pte_val(pte) & ~(_PAGE_READ|_PAGE_R)); }
 
 extern inline pte_t pte_mkclean(pte_t pte)
-{ return __pte(pte_val(pte) & ~(_PAGE_MODIFIED | _PAGE_W); }
+{ return __pte(pte_val(pte) & ~(_PAGE_MODIFIED | _PAGE_W)); }
 
 extern inline pte_t pte_mkold(pte_t pte)
 { return __pte(pte_val(pte) & ~(_PAGE_ACCESSED | _PAGE_R)); }
@@ -361,12 +364,30 @@
 }
 
 extern inline void SET_PAGE_DIR(struct task_struct *tsk, pgd_t *pgdir)
-{ /* XXX */ }
+{
+	register unsigned long paddr asm("%o5");
+
+	paddr = ((unsigned long) pgdir) - PAGE_OFFSET;
+
+	if(tsk->mm == current->mm) {
+		__asm__ __volatile__("
+			rdpr		%%pstate, %%g1
+			or		%%g1, %1, %%g2
+			wrpr		%%g2, %2, %%pstate
+			mov		%0, %%g7
+			wrpr		%%g1, 0x0, %%pstate
+		" : : "r" (paddr), "i" (PSTATE_MG), "i" (PSTATE_IE)
+		  : "g1", "g2");
+	}
+}
 
 /* to find an entry in a page-table-directory. */
 extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
 { return mm->pgd + ((address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); }
 
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
 /* Find an entry in the second-level page table.. */
 extern inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
 { return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); }
@@ -489,13 +510,64 @@
 extern inline pgd_t * pgd_alloc(void)
 { return (pgd_t *) get_free_page(GFP_KERNEL); }
 
-#define pgd_flush(pgd)	do { } while (0)
-
-extern pgd_t swapper_pg_dir[1024];	/* XXX */
+extern pgd_t swapper_pg_dir[1024];
 
 extern inline void update_mmu_cache(struct vm_area_struct * vma,
 	unsigned long address, pte_t pte)
-{ /* XXX */ }
+{
+	/* Find and fix bad virutal cache aliases. */
+	if((vma->vm_flags & (VM_WRITE|VM_SHARED)) == (VM_WRITE|VM_SHARED)) {
+		struct vm_area_struct *vmaring;
+		struct inode *inode;
+		unsigned long vaddr, offset, start;
+		pgd_t *pgdp;
+		pmd_t *pmdp;
+		pte_t *ptep;
+		int alias_found = 0;
+
+		inode = vma->vm_inode;
+		if(!inode)
+			return;
+
+		offset = (address & PAGE_MASK) - vma->vm_start;
+		vmaring = inode->i_mmap;
+		do {
+			vaddr = vmaring->vm_start + offset;
+
+			/* This conditional is misleading... */
+			if((vaddr ^ address) & PAGE_SIZE) {
+				alias_found++;
+				start = vmaring->vm_start;
+				while(start < vmaring->vm_end) {
+					pgdp = pgd_offset(vmaring->vm_mm, start);
+					if(!pgdp) goto next;
+					pmdp = pmd_offset(pgdp, start);
+					if(!pmdp) goto next;
+					ptep = pte_offset(pmdp, start);
+					if(!ptep) goto next;
+
+					if(pte_val(*ptep) & _PAGE_PRESENT) {
+						flush_cache_page(vmaring, start);
+						*ptep = __pte(pte_val(*ptep) &
+							      ~(_PAGE_CV));
+						flush_tlb_page(vmaring, start);
+					}
+				next:
+					start += PAGE_SIZE;
+				}
+			}
+		} while((vmaring = vmaring->vm_next_share) != inode->i_mmap);
+
+		if(alias_found && (pte_val(pte) & _PAGE_CV)) {
+			pgdp = pgd_offset(vma->vm_mm, address);
+			pmdp = pmd_offset(pgdp, address);
+			ptep = pte_offset(pmdp, address);
+			flush_cache_page(vma, address);
+			*ptep = __pte(pte_val(*ptep) & ~(_PAGE_CV));
+			flush_tlb_page(vma, address);
+		}
+	}
+}
 
 /* Make a non-present pseudo-TTE. */
 extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
@@ -505,4 +577,6 @@
 #define SWP_OFFSET(entry)	((entry) >> 8)
 #define SWP_ENTRY(type,offset)	pte_val(mk_swap_pte((type),(offset)))
 
-#endif /* _SPARC64_PGTABLE_H */
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_SPARC64_PGTABLE_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/posix_types.h linux/include/asm-sparc64/posix_types.h
--- v2.1.18/linux/include/asm-sparc64/posix_types.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/posix_types.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,106 @@
+#ifndef __ARCH_SPARC64_POSIX_TYPES_H
+#define __ARCH_SPARC64_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long long     __kernel_size_t;
+
+typedef int                    __kernel_ssize_t;
+typedef unsigned long long int __kernel_ptrdiff_t;
+typedef long                   __kernel_time_t;
+typedef long                   __kernel_clock_t;
+typedef int                    __kernel_pid_t;
+typedef unsigned short         __kernel_ipc_pid_t;
+typedef unsigned short         __kernel_uid_t;
+typedef unsigned short         __kernel_gid_t;
+typedef unsigned short         __kernel_dev_t;
+typedef unsigned long          __kernel_ino_t;
+typedef unsigned short         __kernel_mode_t;
+typedef unsigned short         __kernel_umode_t;
+typedef short                  __kernel_nlink_t;
+typedef long                   __kernel_daddr_t;
+typedef long                   __kernel_off_t;
+typedef char *                 __kernel_caddr_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+	int	val[2];
+} __kernel_fsid_t;
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
+{ 
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant cases (8 or 32 longs,
+ * for 256 and 1024-bit fd_sets respectively)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+{
+	unsigned long *tmp = p->fds_bits;
+	int i;
+
+	if (__builtin_constant_p(__FDSET_LONGS)) {
+		switch (__FDSET_LONGS) {
+			case 32:
+			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+			  tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+			  tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+			  tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+			  tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0;
+			  tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0;
+			  tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0;
+			  tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0;
+			  return;
+			case 16:
+			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+			  tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+			  tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+			  tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+			  return;
+			case 8:
+			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+			  tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+			  return;
+			case 4:
+			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+			  return;
+		}
+	}
+	i = __FDSET_LONGS;
+	while (i) {
+		i--;
+		*tmp = 0;
+		tmp++;
+	}
+}
+
+#endif /* !(__ARCH_SPARC64_POSIX_TYPES_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/processor.h linux/include/asm-sparc64/processor.h
--- v2.1.18/linux/include/asm-sparc64/processor.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/processor.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,202 @@
+/* $Id: processor.h,v 1.6 1996/12/28 20:05:14 davem Exp $
+ * include/asm-sparc64/processor.h
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __ASM_SPARC64_PROCESSOR_H
+#define __ASM_SPARC64_PROCESSOR_H
+
+#include <asm/a.out.h>
+#include <asm/pstate.h>
+#include <asm/ptrace.h>
+#include <asm/head.h>
+#include <asm/signal.h>
+#include <asm/segment.h>
+
+/* Bus types */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/* The sparc has no problems with write protection */
+#define wp_works_ok 1
+#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
+
+/* Whee, this is STACK_TOP + PAGE_SIZE and the lowest kernel address too... 
+ * That one page is used to protect kernel from intruders, so that
+ * we can make our access_ok test faster
+ */
+#define TASK_SIZE	(0xFFFFF80000000000UL)
+
+#ifndef __ASSEMBLY__
+
+/* Ok this is hot.  Sparc exception save area. */
+struct exception_struct {
+	unsigned long count;   /* Exception count */
+	unsigned long pc;      /* Callers PC for copy/clear user */
+	unsigned long expc;    /* Where to jump when exception signaled */
+	unsigned long address; /* Saved user base address for transfer */
+};
+
+#define NSWINS		8
+
+/* The Sparc processor specific thread struct. */
+struct thread_struct {
+	/* Context switch saved kernel state. */
+	unsigned long user_globals[8];		/* performance hack */
+	unsigned long ksp, kpc;
+
+	/* Floating point regs */
+	unsigned long   float_regs[64] __attribute__ ((aligned (64)));
+	unsigned long   fsr;
+	unsigned long   fpqdepth;
+	struct fpq {
+		unsigned long *insn_addr;
+		unsigned long insn;
+	} fpqueue[16];
+
+	/* Storage for windows when user stack is bogus. */
+	struct reg_window reg_window[NSWINS] __attribute__ ((aligned (16)));
+	unsigned long rwbuf_stkptrs[NSWINS] __attribute__ ((aligned (8)));
+	unsigned long w_saved;
+
+	/* Arch-specific task state flags, see below. */
+	unsigned long flags;
+
+	/* For signal handling */
+	unsigned long sig_address __attribute__ ((aligned (8)));
+	unsigned long sig_desc;
+
+	struct exception_struct;
+	struct sigstack sstk_info;
+	int current_ds, new_signal;
+	struct exec core_exec;     /* just what it says. */
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#define SPARC_FLAG_KTHREAD      0x1    /* task is a kernel thread */
+#define SPARC_FLAG_UNALIGNED    0x2    /* is allowed to do unaligned accesses */
+#define SPARC_FLAG_NEWSIGNALS   0x4    /* task wants new-style signals */
+#define SPARC_FLAG_32BIT        0x8    /* task is older 32-bit binary */
+
+#define INIT_MMAP { &init_mm, 0xfffff80000000000, 0xfffffe00000, \
+		    PAGE_SHARED , VM_READ | VM_WRITE | VM_EXEC }
+
+#define INIT_TSS  {							\
+/* user_globals */ 							\
+   { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 					\
+/* ksp, kpc */ 								\
+   0,   0, 								\
+/* FPU regs */   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	\
+                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	\
+                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	\
+                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },	\
+/* FPU status, FPU qdepth, FPU queue */ 				\
+   0,          0,          { { 0, 0, }, }, 				\
+/* reg_window */							\
+{ { { 0, }, { 0, } }, }, 						\
+/* rwbuf_stkptrs */							\
+{ 0, 0, 0, 0, 0, 0, 0, 0, },						\
+/* w_saved */								\
+   0, 									\
+/* flags */								\
+   SPARC_FLAG_KTHREAD,							\
+/* sig_address, sig_desc */						\
+   0,           0,							\
+/* ex,     sstk_info, current_ds, */					\
+   { 0, }, { 0, 0, }, USER_DS,						\
+/* new_signal */							\
+  0,									\
+/* core_exec */								\
+{ 0, },									\
+}
+
+#ifndef __ASSEMBLY__
+
+/* Return saved PC of a blocked thread. */
+extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	return t->kpc;
+}
+
+/* Do necessary setup to start up a newly executed thread. */
+extern __inline__ void start_thread(struct pt_regs *regs, unsigned long pc,
+				    unsigned long sp)
+{
+	regs->tstate = (regs->tstate & (TSTATE_CWP)) | TSTATE_IE;
+	regs->tpc = ((pc & (~3)) - 4);
+	regs->tnpc = regs->tpc + 4;
+	regs->y = 0;
+	__asm__ __volatile__("
+		stx		%%g0, [%0 + %2 + 0x00]
+		stx		%%g0, [%0 + %2 + 0x08]
+		stx		%%g0, [%0 + %2 + 0x10]
+		stx		%%g0, [%0 + %2 + 0x18]
+		stx		%%g0, [%0 + %2 + 0x20]
+		stx		%%g0, [%0 + %2 + 0x28]
+		stx		%%g0, [%0 + %2 + 0x30]
+		stx		%%g0, [%0 + %2 + 0x38]
+		stx		%%g0, [%0 + %2 + 0x40]
+		stx		%%g0, [%0 + %2 + 0x48]
+		stx		%%g0, [%0 + %2 + 0x50]
+		stx		%%g0, [%0 + %2 + 0x58]
+		stx		%%g0, [%0 + %2 + 0x60]
+		stx		%%g0, [%0 + %2 + 0x68]
+		stx		%1,   [%0 + %2 + 0x70]
+		stx		%%g0, [%0 + %2 + 0x78]
+		" : : "r" (regs), "r" (sp - REGWIN_SZ),
+		      "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])));
+}
+
+extern __inline__ void start_thread32(struct pt_regs *regs, unsigned long pc,
+				      unsigned long sp)
+{
+	register unsigned int zero asm("g1");
+
+	pc &= 0x00000000ffffffffUL;
+	sp &= 0x00000000ffffffffUL;
+
+	regs->tstate = (regs->tstate & (TSTATE_CWP)) | (TSTATE_IE | TSTATE_AM);
+	regs->tpc = ((pc & (~3)) - 4);
+	regs->tnpc = regs->tpc + 4;
+	regs->y = 0;
+	zero = 0;
+	__asm__ __volatile__("
+		stx		%%g0, [%0 + %2 + 0x00]
+		stx		%%g0, [%0 + %2 + 0x08]
+		stx		%%g0, [%0 + %2 + 0x10]
+		stx		%%g0, [%0 + %2 + 0x18]
+		stx		%%g0, [%0 + %2 + 0x20]
+		stx		%%g0, [%0 + %2 + 0x28]
+		stx		%%g0, [%0 + %2 + 0x30]
+		stx		%%g0, [%0 + %2 + 0x38]
+		stx		%%g0, [%0 + %2 + 0x40]
+		stx		%%g0, [%0 + %2 + 0x48]
+		stx		%%g0, [%0 + %2 + 0x50]
+		stx		%%g0, [%0 + %2 + 0x58]
+		stx		%%g0, [%0 + %2 + 0x60]
+		stx		%%g0, [%0 + %2 + 0x68]
+		stx		%1,   [%0 + %2 + 0x70]
+		stx		%%g0, [%0 + %2 + 0x78]
+		" : : "r" (regs), "r" (sp - REGWIN32_SZ),
+		      "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])),
+		      "r" (zero));
+}
+
+/* Free all resources held by a thread. */
+#define release_thread(tsk)		do { } while(0)
+
+#ifdef __KERNEL__
+/* Allocation and freeing of basic task resources. */
+#define alloc_kernel_stack(tsk)		__get_free_page(GFP_KERNEL)
+#define free_kernel_stack(stack)	free_page(stack)
+#define alloc_task_struct()		kmalloc(sizeof(struct task_struct), GFP_KERNEL)
+#define free_task_struct(tsk)		kfree(tsk)
+#endif
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__ASM_SPARC64_PROCESSOR_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/psrcompat.h linux/include/asm-sparc64/psrcompat.h
--- v2.1.18/linux/include/asm-sparc64/psrcompat.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/psrcompat.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,55 @@
+/* $Id: psrcompat.h,v 1.1 1996/12/26 10:02:30 davem Exp $ */
+#ifndef _SPARC64_PSRCOMPAT_H
+#define _SPARC64_PSRCOMPAT_H
+
+#include <asm/pstate.h>
+
+/* Old 32-bit PSR fields for the compatability conversion code. */
+#define PSR_CWP     0x0000001f         /* current window pointer     */
+#define PSR_ET      0x00000020         /* enable traps field         */
+#define PSR_PS      0x00000040         /* previous privilege level   */
+#define PSR_S       0x00000080         /* current privilege level    */
+#define PSR_PIL     0x00000f00         /* processor interrupt level  */
+#define PSR_EF      0x00001000         /* enable floating point      */
+#define PSR_EC      0x00002000         /* enable co-processor        */
+#define PSR_LE      0x00008000         /* SuperSparcII little-endian */
+#define PSR_ICC     0x00f00000         /* integer condition codes    */
+#define PSR_C       0x00100000         /* carry bit                  */
+#define PSR_V       0x00200000         /* overflow bit               */
+#define PSR_Z       0x00400000         /* zero bit                   */
+#define PSR_N       0x00800000         /* negative bit               */
+#define PSR_VERS    0x0f000000         /* cpu-version field          */
+#define PSR_IMPL    0xf0000000         /* cpu-implementation field   */
+
+extern inline unsigned int tstate_to_psr(unsigned long tstate)
+{
+	unsigned int psr;
+	unsigned long vers;
+
+	/* These fields are in the same place. */
+	psr  = (tstate & (TSTATE_CWP | TSTATE_PEF));
+
+	/* This is what the user would have always seen. */
+	psr |= PSR_S;
+
+	/* Slam in the 32-bit condition codes. */
+	psr |= ((tstate & TSTATE_ICC) >> 12);
+
+	/* This is completely arbitrary. */
+	__asm__ __volatile__("rdpr	%vers, %0" : "=r" (vers));
+	psr |= ((vers << 8) >> 32) & PSR_IMPL;
+	psr |= ((vers << 24) >> 36) & PSR_VERS;
+
+	return psr;
+}
+
+extern inline unsigned long psr_to_tstate_icc(unsigned int psr)
+{
+	unsigned long tstate;
+
+	tstate = (psr & PSR_ICC) << 12;
+
+	return tstate;
+}
+
+#endif /* !(_SPARC64_PSRCOMPAT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/pstate.h linux/include/asm-sparc64/pstate.h
--- v2.1.18/linux/include/asm-sparc64/pstate.h	Wed Dec 18 15:59:02 1996
+++ linux/include/asm-sparc64/pstate.h	Mon Dec 30 12:00:03 1996
@@ -1,4 +1,4 @@
-/* $Id: pstate.h,v 1.1 1996/12/12 11:57:14 davem Exp $ */
+/* $Id: pstate.h,v 1.2 1996/12/26 09:56:16 davem Exp $ */
 #ifndef _SPARC64_PSTATE_H
 #define _SPARC64_PSTATE_H
 
@@ -29,10 +29,12 @@
  *  63    40 39   32 31   24 23    20 19       8 7      5 4     0
  */
 #define TSTATE_CCR	0x000000ff00000000	/* Condition Codes.		*/
+#define TSTATE_XCC	0x000000f000000000	/* Condition Codes.		*/
 #define TSTATE_XNEG	0x0000008000000000	/* %xcc Negative.		*/
 #define TSTATE_XZERO	0x0000004000000000	/* %xcc Zero.			*/
 #define TSTATE_XOVFL	0x0000002000000000	/* %xcc Overflow.		*/
 #define TSTATE_XCARRY	0x0000001000000000	/* %xcc Carry.			*/
+#define TSTATE_ICC	0x0000000f00000000	/* Condition Codes.		*/
 #define TSTATE_INEG	0x0000000800000000	/* %icc Negative.		*/
 #define TSTATE_IZERO	0x0000000400000000	/* %icc Zero.			*/
 #define TSTATE_IOVFL	0x0000000200000000	/* %icc Overflow.		*/
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/ptrace.h linux/include/asm-sparc64/ptrace.h
--- v2.1.18/linux/include/asm-sparc64/ptrace.h	Wed Dec 18 15:59:02 1996
+++ linux/include/asm-sparc64/ptrace.h	Mon Dec 30 12:00:03 1996
@@ -1,4 +1,4 @@
-/* $Id: ptrace.h,v 1.1 1996/12/12 11:59:35 davem Exp $ */
+/* $Id: ptrace.h,v 1.4 1996/12/28 18:39:54 davem Exp $ */
 #ifndef _SPARC64_PTRACE_H
 #define _SPARC64_PTRACE_H
 
@@ -18,6 +18,14 @@
 	unsigned long y;
 };
 
+struct pt_regs32 {
+	unsigned int psr;
+	unsigned int pc;
+	unsigned int npc;
+	unsigned int y;
+	unsigned int u_regs[16]; /* globals and ins */
+};
+
 #define UREG_G0        0
 #define UREG_G1        1
 #define UREG_G2        2
@@ -44,7 +52,7 @@
 };
 
 /* A 32-bit register window. */
-struct reg_window_32 {
+struct reg_window32 {
 	unsigned int locals[8];
 	unsigned int ins[8];
 };
@@ -61,7 +69,7 @@
 };	
 
 /* A 32-bit Sparc stack frame */
-struct sparc_stackf_32 {
+struct sparc_stackf32 {
 	unsigned int locals[8];
         unsigned int ins[6];
 	unsigned int fp;
@@ -71,19 +79,36 @@
 	unsigned int xxargs[1];
 };	
 
-#define TRACEREG_SZ   sizeof(struct pt_regs)
-#define STACKFRAME_SZ sizeof(struct sparc_stackf)
-#define REGWIN_SZ     sizeof(struct reg_window)
+struct sparc_trapf {
+	unsigned long locals[8];
+	unsigned long ins[8];
+	unsigned long _unused;
+	struct pt_regs *regs;
+};
+
+#define TRACEREG_SZ	sizeof(struct pt_regs)
+#define STACKFRAME_SZ	sizeof(struct sparc_stackf)
+#define REGWIN_SZ	sizeof(struct reg_window)
+
+#define TRACEREG32_SZ	sizeof(struct pt_regs32)
+#define STACKFRAME32_SZ	sizeof(struct sparc_stackf32)
+#define REGWIN32_SZ	sizeof(struct reg_window32)
 
 #ifdef __KERNEL__
-#define user_mode(regs) (!((regs)->tstate & PSR_PS))
+#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
 #define instruction_pointer(regs) ((regs)->tpc)
 extern void show_regs(struct pt_regs *);
 #endif
 
 #else /* __ASSEMBLY__ */
 /* For assembly code. */
-#define TRACEREG_SZ       0x50
-#define STACKFRAME_SZ     0x60
-#define REGWIN_SZ         0x40
+#define TRACEREG_SZ		XXX
+#define STACKFRAME_SZ		YYY
+#define REGWIN_SZ		ZZZ
+
+#define TRACEREG32_SZ		0x50
+#define STACKFRAME32_SZ		0x60
+#define REGWIN32_SZ		0x40
 #endif
+
+#endif /* !(_SPARC64_PTRACE_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/reg.h linux/include/asm-sparc64/reg.h
--- v2.1.18/linux/include/asm-sparc64/reg.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/reg.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,79 @@
+/* $Id: reg.h,v 1.1 1996/12/26 14:22:34 davem Exp $
+ * linux/asm-sparc64/reg.h
+ * Layout of the registers as expected by gdb on the Sparc
+ * we should replace the user.h definitions with those in
+ * this file, we don't even use the other 
+ * -miguel
+ *
+ * The names of the structures, constants and aliases in this file
+ * have the same names as the sunos ones, some programs rely on these
+ * names (gdb for example).
+ *
+ */
+
+#ifndef __SPARC64_REG_H
+#define __SPARC64_REG_H
+
+struct regs {
+	int     r_psr;
+#define r_ps r_psr
+        int     r_pc; 
+        int     r_npc;
+        int     r_y;  
+        int     r_g1; 
+        int     r_g2;
+        int     r_g3;
+        int     r_g4;
+        int     r_g5;
+        int     r_g6;
+        int     r_g7;
+        int     r_o0;
+        int     r_o1;
+        int     r_o2;
+        int     r_o3;
+        int     r_o4;
+        int     r_o5;
+        int     r_o6;
+        int     r_o7;
+};
+
+struct fpq {
+        unsigned int *addr;
+        unsigned ing instr;
+};
+
+struct  fq {
+        union {
+                double  whole;
+                struct  fpq fpq;
+        } FQu;
+};
+
+#define FPU_REGS_TYPE unsigned int
+#define FPU_FSR_TYPE unsigned
+
+struct fp_status {
+        union {
+                FPU_REGS_TYPE Fpu_regs[32];
+                double  Fpu_dregs[16];
+        } fpu_fr;
+        FPU_FSR_TYPE Fpu_fsr;
+        unsigned Fpu_flags;
+        unsigned Fpu_extra;
+        unsigned Fpu_qcnt;
+        struct fq Fpu_q[16];
+};
+
+#define fpu_regs  f_fpstatus.fpu_fr.Fpu_regs
+#define fpu_dregs f_fpstatus.fpu_fr.Fpu_dregs
+#define fpu_fsr   f_fpstatus.Fpu_fsr
+#define fpu_flags f_fpstatus.Fpu_flags
+#define fpu_extra f_fpstatus.Fpu_extra
+#define fpu_q     f_fpstatus.Fpu_q
+#define fpu_qcnt  f_fpstatus.Fpu_qcnt
+
+struct fpu {
+        struct fp_status f_fpstatus;
+};
+
+#endif /* __SPARC64_REG_H */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/resource.h linux/include/asm-sparc64/resource.h
--- v2.1.18/linux/include/asm-sparc64/resource.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/resource.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,40 @@
+/* $Id: resource.h,v 1.1 1996/12/26 14:22:34 davem Exp $
+ * resource.h: Resource definitions.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_RESOURCE_H
+#define _SPARC64_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NOFILE	6		/* max number of open files */
+#define RLIMIT_NPROC	7		/* max number of processes */
+#define RLIMIT_MEMLOCK  8               /* max locked-in-memory address space */
+#define RLIMIT_AS       9               /* address space limit */
+
+#define RLIM_NLIMITS	10
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS							\
+{									\
+    {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX},				\
+    {LONG_MAX, LONG_MAX}, {_STK_LIM, _STK_LIM},				\
+    {       0, LONG_MAX}, {LONG_MAX, LONG_MAX},				\
+    {NR_OPEN, NR_OPEN}, {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER},	\
+    {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}                          \
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* !(_SPARC64_RESOURCE_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/rtc.h linux/include/asm-sparc64/rtc.h
--- v2.1.18/linux/include/asm-sparc64/rtc.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/rtc.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,27 @@
+/* $Id: rtc.h,v 1.1 1996/12/26 14:22:35 davem Exp $
+ *
+ * rtc.h: Definitions for access to the Mostek real time clock
+ *
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ */
+
+#ifndef _RTC_H
+#define _RTC_H
+
+#include <linux/ioctl.h>
+
+struct rtc_time
+{
+	int	sec;	/* Seconds (0-59) */
+	int	min;	/* Minutes (0-59) */
+	int	hour;	/* Hour (0-23) */
+	int	dow;	/* Day of the week (1-7) */
+	int	dom;	/* Day of the month (1-31) */
+	int	month;	/* Month of year (1-12) */
+	int	year;	/* Year (0-99) */
+};
+
+#define RTCGET _IOR('p', 20, struct rtc_time)
+#define RTCSET _IOW('p', 21, struct rtc_time)
+
+#endif
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/sbus.h linux/include/asm-sparc64/sbus.h
--- v2.1.18/linux/include/asm-sparc64/sbus.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/sbus.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,98 @@
+/* $Id: sbus.h,v 1.1 1996/12/26 14:22:36 davem Exp $
+ * sbus.h:  Defines for the Sun SBus.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* XXX This needs to be mostly redone for sun5 SYSIO. */
+
+#ifndef _SPARC64_SBUS_H
+#define _SPARC64_SBUS_H
+
+#include <asm/oplib.h>
+#include <asm/iommu.h>
+
+/* We scan which devices are on the SBus using the PROM node device
+ * tree.  SBus devices are described in two different ways.  You can
+ * either get an absolute address at which to access the device, or
+ * you can get a SBus 'slot' number and an offset within that slot.
+ */
+
+/* The base address at which to calculate device OBIO addresses. */
+#define SUN_SBUS_BVADDR        0xf8000000
+#define SBUS_OFF_MASK          0x01ffffff
+
+/* These routines are used to calculate device address from slot
+ * numbers + offsets, and vice versa.
+ */
+
+extern __inline__ unsigned long sbus_devaddr(int slotnum, unsigned long offset)
+{
+  return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset));
+}
+
+extern __inline__ int sbus_dev_slot(unsigned long dev_addr)
+{
+  return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25);
+}
+
+extern __inline__ unsigned long sbus_dev_offset(unsigned long dev_addr)
+{
+  return (unsigned long) (((dev_addr)-SUN_SBUS_BVADDR)&SBUS_OFF_MASK);
+}
+
+struct linux_sbus;
+
+/* Linux SBUS device tables */
+struct linux_sbus_device {
+  struct linux_sbus_device *next;      /* next device on this SBus or null */
+  struct linux_sbus_device *child;     /* For ledma and espdma on sun4m */
+  struct linux_sbus *my_bus;           /* Back ptr to sbus */
+  int prom_node;                       /* PROM device tree node for this device */
+  char prom_name[64];                  /* PROM device name */
+  char linux_name[64];                 /* Name used internally by Linux */
+
+  struct linux_prom_registers reg_addrs[PROMREG_MAX];
+  int num_registers;
+
+  struct linux_prom_irqs irqs[PROMINTR_MAX];
+  int num_irqs;
+
+  unsigned long sbus_addr;             /* Absolute base address for device. */
+  unsigned long sbus_vaddrs[PROMVADDR_MAX];
+  unsigned long num_vaddrs;
+  unsigned long offset;                /* Offset given by PROM */
+  int slot;
+};
+
+/* This struct describes the SBus(s) found on this machine. */
+struct linux_sbus {
+	struct linux_sbus *next;             /* next SBus, if more than one SBus */
+	struct linux_sbus_device *devices;   /* Link to devices on this SBus */
+	struct iommu_struct *iommu;          /* IOMMU for this sbus if applicable */
+	int prom_node;                       /* PROM device tree node for this SBus */
+	char prom_name[64];                  /* Usually "sbus" or "sbi" */
+	int clock_freq;
+	struct linux_prom_ranges sbus_ranges[PROMREG_MAX];
+	int num_sbus_ranges;
+};
+
+extern struct linux_sbus *SBus_chain;
+
+/* Device probing routines could find these handy */
+#define for_each_sbus(bus) \
+        for((bus) = SBus_chain; (bus); (bus)=(bus)->next)
+
+#define for_each_sbusdev(device, bus) \
+        for((device) = (bus)->devices; (device); (device)=(device)->next)
+        
+#define for_all_sbusdev(device, bus) \
+	for((bus) = SBus_chain, (device) = (bus)->devices; (bus); (device)=((device)->next ? (device)->next : ((bus) = (bus)->next, (bus) ? (bus)->devices : 0)))
+
+/* XXX This is promlib stuff, what is it doing here? XXX */
+
+/* Apply promlib probed SBUS ranges to registers. */
+extern void prom_apply_sbus_ranges(struct linux_sbus *sbus, 
+				   struct linux_prom_registers *sbusregs, int nregs);
+
+#endif /* !(_SPARC64_SBUS_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/scatterlist.h linux/include/asm-sparc64/scatterlist.h
--- v2.1.18/linux/include/asm-sparc64/scatterlist.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/scatterlist.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,18 @@
+/* $Id: scatterlist.h,v 1.1 1996/12/26 14:22:32 davem Exp $ */
+#ifndef _SPARC64_SCATTERLIST_H
+#define _SPARC64_SCATTERLIST_H
+
+#include <asm/page.h>
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+			 * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+
+    char * dvma_address; /* A place to hang host-specific addresses at. */
+};
+
+#define ISA_DMA_THRESHOLD ((0x100000000) + PAGE_OFFSET)
+
+#endif /* !(_SPARC64_SCATTERLIST_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/segment.h linux/include/asm-sparc64/segment.h
--- v2.1.18/linux/include/asm-sparc64/segment.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/segment.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,6 @@
+#ifndef __SPARC64_SEGMENT_H
+#define __SPARC64_SEGMENT_H
+
+/* Only here because we have some old header files that expect it.. */
+
+#endif
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/shmparam.h linux/include/asm-sparc64/shmparam.h
--- v2.1.18/linux/include/asm-sparc64/shmparam.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/shmparam.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,47 @@
+/* $Id: shmparam.h,v 1.1 1996/12/26 14:22:36 davem Exp $ */
+#ifndef _ASMSPARC64_SHMPARAM_H
+#define _ASMSPARC64_SHMPARAM_H
+
+/* XXX Redo most of this... */
+
+/* address range for shared memory attaches if no address passed to shmat() */
+#define SHM_RANGE_START	0x10000000
+#define SHM_RANGE_END	0x20000000
+
+/*
+ * Format of a swap-entry for shared memory pages currently out in
+ * swap space (see also mm/swap.c).
+ *
+ * SWP_TYPE = SHM_SWP_TYPE
+ * SWP_OFFSET is used as follows:
+ *
+ *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
+ *  bits 7..21: index of page within shared memory segment (SHM_IDX)
+ *		(actually fewer bits get used since SHMMAX is so low)
+ */
+
+/*
+ * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
+ * there is a static array of size SHMMNI.
+ */
+#define _SHM_ID_BITS	7
+#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
+
+#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
+#define _SHM_IDX_BITS	15
+#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
+
+/*
+ * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
+ * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
+ */
+
+#define SHMMAX (1024 * 1024)		/* max shared seg size (bytes) */
+#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
+#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
+#define SHMALL				/* max shm system wide (pages) */ \
+	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
+#define	SHMLBA PAGE_SIZE		/* attach addr a multiple of this */
+#define SHMSEG SHMMNI			/* max shared segs per process */
+
+#endif /* _ASMSPARC64_SHMPARAM_H */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/sigcontext.h linux/include/asm-sparc64/sigcontext.h
--- v2.1.18/linux/include/asm-sparc64/sigcontext.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/sigcontext.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,67 @@
+/* $Id: sigcontext.h,v 1.1 1996/12/26 14:22:36 davem Exp $ */
+#ifndef _ASMsparc64_SIGCONTEXT_H
+#define _ASMsparc64_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+#define SUNOS_MAXWIN   31
+
+#ifndef __ASSEMBLY__
+
+/* SunOS system call sigstack() uses this arg. */
+struct sunos_sigstack {
+	unsigned int sig_sp;
+	int onstack_flag;
+};
+
+/* This is what SunOS does, so shall I. */
+struct sigcontext {
+	int sigc_onstack;      /* state to restore */
+	int sigc_mask;         /* sigmask to restore */
+	int sigc_sp;           /* stack pointer */
+	int sigc_pc;           /* program counter */
+	int sigc_npc;          /* next program counter */
+	int sigc_psr;          /* for condition codes etc */
+	int sigc_g1;           /* User uses these two registers */
+	int sigc_o0;           /* within the trampoline code. */
+
+	/* Now comes information regarding the users window set
+	 * at the time of the signal.
+	 */
+	int sigc_oswins;       /* outstanding windows */
+
+	/* stack ptrs for each regwin buf */
+	/* XXX 32-bit ptrs pinhead... */
+	char *sigc_spbuf[SUNOS_MAXWIN];
+
+	/* Windows to restore after signal */
+	struct reg_window32 sigc_wbuf[SUNOS_MAXWIN];
+};
+
+typedef struct {
+	struct     pt_regs32 si_regs;
+	unsigned   int si_float_regs [64];
+	unsigned   int si_fsr;
+	unsigned   int si_fpqdepth;
+	struct {
+		unsigned int *insn_addr;
+		unsigned int insn;
+	} si_fpqueue [16];
+	int si_mask;
+} __siginfo32_t;
+
+typedef struct {
+	struct     pt_regs si_regs;
+	unsigned   long si_float_regs [64];
+	unsigned   long si_fsr;
+	unsigned   int si_fpqdepth;
+	struct {
+		unsigned int *insn_addr;
+		unsigned int insn;
+	} si_fpqueue [16];
+	int si_mask;
+} __siginfo_t;
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_ASMsparc64_SIGCONTEXT_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/signal.h linux/include/asm-sparc64/signal.h
--- v2.1.18/linux/include/asm-sparc64/signal.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/signal.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,178 @@
+/* $Id: signal.h,v 1.1 1996/12/26 14:22:37 davem Exp $ */
+#ifndef _ASMSPARC64_SIGNAL_H
+#define _ASMSPARC64_SIGNAL_H
+
+#include <asm/sigcontext.h>
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+#include <linux/personality.h>
+#endif
+#endif
+
+/* On the Sparc the signal handlers get passed a 'sub-signal' code
+ * for certain signal types, which we document here.
+ */
+#define _NSIG             32
+#define NSIG		_NSIG
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define    SUBSIG_STACK       0
+#define    SUBSIG_ILLINST     2
+#define    SUBSIG_PRIVINST    3
+#define    SUBSIG_BADTRAP(t)  (0x80 + (t))
+
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+
+#define SIGEMT           7
+#define    SUBSIG_TAG    10
+
+#define SIGFPE		 8
+#define    SUBSIG_FPDISABLED     0x400
+#define    SUBSIG_FPERROR        0x404
+#define    SUBSIG_FPINTOVFL      0x001
+#define    SUBSIG_FPSTSIG        0x002
+#define    SUBSIG_IDIVZERO       0x014
+#define    SUBSIG_FPINEXACT      0x0c4
+#define    SUBSIG_FPDIVZERO      0x0c8
+#define    SUBSIG_FPUNFLOW       0x0cc
+#define    SUBSIG_FPOPERROR      0x0d0
+#define    SUBSIG_FPOVFLOW       0x0d4
+
+#define SIGKILL		 9
+#define SIGBUS          10
+#define    SUBSIG_BUSTIMEOUT    1
+#define    SUBSIG_ALIGNMENT     2
+#define    SUBSIG_MISCERROR     5
+
+#define SIGSEGV		11
+#define    SUBSIG_NOMAPPING     3
+#define    SUBSIG_PROTECTION    4
+#define    SUBSIG_SEGERROR      5
+
+#define SIGSYS		12
+
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGURG          16
+
+/* SunOS values which deviate from the Linux/i386 ones */
+#define SIGSTOP		17
+#define SIGTSTP		18
+#define SIGCONT		19
+#define SIGCHLD		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGIO		23
+#define SIGPOLL		SIGIO   /* SysV name for SIGIO */
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGLOST		29
+#define SIGUSR1		30
+#define SIGUSR2		31
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long sigset_t;
+typedef unsigned int sigset32_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+#endif
+
+/* A SunOS sigstack */
+struct sigstack {
+	/* XXX 32-bit pointers pinhead XXX */
+	char *the_stack;
+	int   cur_status;
+};
+
+/* Sigvec flags */
+#define SV_SSTACK    1     /* This signal handler should use sig-stack */
+#define SV_INTR      2     /* Sig return should not restart system call */
+#define SV_RESET     4     /* Set handler to SIG_DFL upon taken signal */
+#define SV_IGNCHILD  8     /* Do not send SIGCHLD */
+
+/*
+ * sa_flags values: SA_STACK is not currently supported, but will allow the
+ * usage of signal stacks by using the (now obsolete) sa_restorer field in
+ * the sigaction structure as a stack pointer. This is now possible due to
+ * the changes in signal handling. LBT 010493.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
+ */
+#define SA_NOCLDSTOP	SV_IGNCHILD
+#define SA_STACK	SV_SSTACK
+#define SA_RESTART	SV_INTR
+#define SA_ONESHOT	SV_RESET
+#define SA_INTERRUPT	0x10
+#define SA_NOMASK	0x20
+#define SA_SHIRQ	0x40
+
+#define SIG_BLOCK          0x01	/* for blocking signals */
+#define SIG_UNBLOCK        0x02	/* for unblocking signals */
+#define SIG_SETMASK        0x04	/* for setting the signal mask */
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ *
+ * DJHR
+ * SA_STATIC_ALLOC is used for the SPARC system to indicate that this
+ * interrupt handler's irq structure should be statically allocated
+ * by the request_irq routine.
+ * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge
+ * of interrupt usage and that sucks. Also without a flag like this
+ * it may be possible for the free_irq routine to attempt to free
+ * statically allocated data.. which is NOT GOOD.
+ *
+ */
+#define SA_PROBE SA_ONESHOT
+#define SA_SAMPLE_RANDOM SA_RESTART
+#define SA_STATIC_ALLOC		0x80
+#endif
+
+/* Type of a signal handler.  */
+#ifdef __KERNEL__
+typedef void (*__sighandler_t)(int, int, struct sigcontext *, char *);
+#else
+typedef void (*__sighandler_t)(int);
+#endif
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+struct sigaction {
+	__sighandler_t  sa_handler;
+	sigset_t        sa_mask;
+	unsigned long   sa_flags;
+	void (*sa_restorer) (void);     /* not used by Linux/SPARC yet */
+};
+
+struct sigaction32 {
+	/* XXX 32-bit func ptr... */
+	__sighandler_t  sa_handler;
+	sigset32_t      sa_mask;
+	unsigned int    sa_flags;
+
+	/* XXX 32-bit func ptr... */
+	void (*sa_restorer) (void);     /* not used by Linux/SPARC yet */
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_ASMSPARC64_SIGNAL_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/smp.h linux/include/asm-sparc64/smp.h
--- v2.1.18/linux/include/asm-sparc64/smp.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/smp.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,179 @@
+/* smp.h: Sparc64 specific SMP stuff.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_SMP_H
+#define _SPARC64_SMP_H
+
+#include <asm/asi.h>
+
+#ifndef __ASSEMBLY__
+/* PROM provided per-processor information we need
+ * to start them all up.
+ */
+
+struct prom_cpuinfo {
+	int prom_node;
+	int mid;
+};
+#endif /* !(__ASSEMBLY__) */
+
+#ifdef __SMP__
+
+#ifndef __ASSEMBLY__
+
+extern struct prom_cpuinfo linux_cpus[NCPUS];
+
+/* Per processor Sparc parameters we need. */
+
+struct cpuinfo_sparc {
+	unsigned long udelay_val; /* that's it */
+};
+
+extern struct cpuinfo_sparc cpu_data[NR_CPUS];
+
+typedef __volatile__ unsigned char klock_t;
+extern klock_t kernel_flag;
+
+#define KLOCK_HELD       0xff
+#define KLOCK_CLEAR      0x00
+
+/*
+ *	Private routines/data
+ */
+ 
+extern int smp_found_cpus;
+extern unsigned char boot_cpu_id;
+extern unsigned int cpu_present_map;
+extern __volatile__ unsigned long smp_invalidate_needed[NR_CPUS];
+extern __volatile__ unsigned long kernel_counter;
+extern __volatile__ unsigned char active_kernel_processor;
+extern void smp_message_irq(void);
+extern unsigned long ipi_count;
+extern __volatile__ unsigned long kernel_counter;
+extern __volatile__ unsigned long syscall_count;
+
+extern void print_lock_state(void);
+
+typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long,
+		       unsigned long, unsigned long);
+
+/*
+ *	General functions that each host system must provide.
+ */
+
+extern void smp_callin(void);
+extern void smp_boot_cpus(void);
+extern void smp_store_cpu_info(int id);
+extern void smp_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+			   unsigned long arg3, unsigned long arg4, unsigned long arg5);
+extern void smp_capture(void);
+extern void smp_release(void);
+
+extern __inline__ void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
+extern __inline__ void xc1(smpfunc_t func, unsigned long arg1)
+{ smp_cross_call(func, arg1, 0, 0, 0, 0); }
+extern __inline__ void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
+{ smp_cross_call(func, arg1, arg2, 0, 0, 0); }
+extern __inline__ void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+			   unsigned long arg3)
+{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); }
+extern __inline__ void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+			   unsigned long arg3, unsigned long arg4)
+{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); }
+extern __inline__ void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+			   unsigned long arg3, unsigned long arg4, unsigned long arg5)
+{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
+
+extern __volatile__ int cpu_number_map[NR_CPUS];
+extern __volatile__ int cpu_logical_map[NR_CPUS];
+
+extern __inline__ int smp_processor_id(void)
+{
+	int cpuid;
+
+	/* Get MID from UPA Config register, and use that. */
+	__asm__ __volatile__("
+		ldxa	[%g0] %1, %0
+		srlx	%0, 17, %0
+		and	%0, 0x1f, %0
+	" : "=r" cpuid
+	  : "i" (ASI_UPA_CONFIG));
+
+	return cpuid;
+}
+
+
+extern __volatile__ unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */
+extern __volatile__ int smp_process_available;
+
+extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr)
+{
+	unsigned long temp0, temp1;
+
+	__asm__ __volatile__("
+	lduw		[%2], %0
+1:
+	add		%0, 1, %1
+	cas		[%2], %0, %1
+	cmp		%0, %1
+	bne,a,pn	%%icc, 1b
+	 lduw		[%2], %0
+2:
+	membar		#StoreStore | #StoreLoad
+" 	: "=&r" (temp0), "=&r" (temp1), "=r" (ctr)
+	: "ir" (i), "r" (ctr));
+}
+
+extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr)
+{
+	unsigned long temp0, temp1;
+
+	__asm__ __volatile__("
+	lduw		[%2], %0
+1:
+	sub		%0, 1, %1
+	cas		[%2], %0, %1
+	cmp		%0, %1
+	bne,a,pn	%%icc, 1b
+	 lduw		[%2], %0
+2:
+	membar		#StoreStore | #StoreLoad
+" 	: "=&r" (temp0), "=&r" (temp1), "=r" (ctr)
+	: "ir" (i), "r" (ctr));
+}
+
+extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr)
+{
+	return *ctr;
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+/* Sparc specific messages. */
+#define MSG_CAPTURE            0x0004       /* Park a processor. */
+#define MSG_CROSS_CALL         0x0005       /* run func on cpus */
+
+/* Empirical PROM processor mailbox constants.  If the per-cpu mailbox
+ * contains something other than one of these then the ipi is from
+ * Linux's active_kernel_processor.  This facility exists so that
+ * the boot monitor can capture all the other cpus when one catches
+ * a watchdog reset or the user enters the monitor using L1-A keys.
+ */
+#define MBOX_STOPCPU          0xFB
+#define MBOX_IDLECPU          0xFC
+#define MBOX_IDLECPU2         0xFD
+#define MBOX_STOPCPU2         0xFE
+
+
+#define NO_PROC_ID            0xFF
+
+#define PROC_CHANGE_PENALTY     20
+
+#define SMP_FROM_INT		1
+#define SMP_FROM_SYSCALL	2
+
+#endif /* !(__SMP__) */
+
+#endif /* !(_SPARC64_SMP_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/smp_lock.h linux/include/asm-sparc64/smp_lock.h
--- v2.1.18/linux/include/asm-sparc64/smp_lock.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/smp_lock.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,60 @@
+/* smp_lock.h: Locking and unlocking the kernel on the 64-bit Sparc.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC64_SMPLOCK_H
+#define __SPARC64_SMPLOCK_H
+
+#include <asm/smp.h>
+#include <asm/bitops.h>
+#include <asm/pgtable.h>
+
+#ifdef __SMP__
+
+extern __inline__ __volatile__ unsigned char ldstub(volatile unsigned char *lock)
+{
+	volatile unsigned char retval;
+
+	__asm__ __volatile__("ldstub [%1], %0" : "=&r" (retval) : "r" (lock));
+	return retval;
+}
+
+/*
+ *	Locking the kernel 
+ */
+
+/* Knock knock... */
+extern __inline__ void lock_kernel(void)
+{
+	int proc = smp_processor_id();
+
+	while(ldstub(&kernel_flag)) {
+		if(proc == active_kernel_processor)
+			break;
+		do {
+#ifdef __SMP_PROF__		
+			smp_spins[smp_processor_id()]++;
+#endif			
+			barrier();
+		} while(kernel_flag); /* Don't lock the bus more than we have to. */
+	}
+	active_kernel_processor = proc;
+	kernel_counter++;
+}
+
+/* I want out... */
+extern __inline__ void unlock_kernel(void)
+{
+	if(kernel_counter == 0)
+		panic("Bogus kernel counter.\n");
+
+	if(!--kernel_counter) {
+		active_kernel_processor = NO_PROC_ID;
+		kernel_flag = KLOCK_CLEAR;
+	}
+}
+
+#endif /* (__SMP__) */
+
+#endif /* !(__SPARC64_SMPLOCK_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/socket.h linux/include/asm-sparc64/socket.h
--- v2.1.18/linux/include/asm-sparc64/socket.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/socket.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,38 @@
+/* $Id: socket.h,v 1.1 1996/12/26 14:22:39 davem Exp $ */
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	0xffff
+
+#define SO_DEBUG	0x0001
+#define SO_PASSCRED	0x0002
+#define SO_REUSEADDR	0x0004
+#define SO_KEEPALIVE	0x0008
+#define SO_DONTROUTE	0x0010
+#define SO_BROADCAST	0x0020
+#define SO_PEERCRED	0x0040
+#define SO_LINGER	0x0080
+#define SO_OOBINLINE	0x0100
+/* To add :#define SO_REUSEPORT 0x0200 */
+#define SO_BSDCOMPAT    0x0400
+#define SO_RCVLOWAT     0x0800
+#define SO_SNDLOWAT     0x1000
+#define SO_RCVTIMEO     0x2000
+#define SO_SNDTIMEO     0x4000
+
+/* wha!??? */
+#define SO_DONTLINGER   (~SO_LINGER)  /* Older SunOS compat. hack */
+
+#define SO_SNDBUF	0x1001
+#define SO_RCVBUF	0x1002
+#define SO_ERROR	0x1007
+#define SO_TYPE		0x1008
+
+/* Linux specific, keep the same. */
+#define SO_NO_CHECK	0x000b
+#define SO_PRIORITY	0x000c
+
+#endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/sockios.h linux/include/asm-sparc64/sockios.h
--- v2.1.18/linux/include/asm-sparc64/sockios.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/sockios.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,13 @@
+#ifndef _ASM_SPARC64_SOCKIOS_H
+#define _ASM_SPARC64_SOCKIOS_H
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* !(_ASM_SPARC64_SOCKIOS_H) */
+
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/solerrno.h linux/include/asm-sparc64/solerrno.h
--- v2.1.18/linux/include/asm-sparc64/solerrno.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/solerrno.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,132 @@
+/* $Id: solerrno.h,v 1.1 1996/12/26 14:22:40 davem Exp $
+ * solerrno.h: Solaris error return codes for compatibility.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_SOLERRNO_H
+#define _SPARC64_SOLERRNO_H
+
+#define SOL_EPERM          1     /* Required superuser access perms  */
+#define SOL_ENOENT         2     /* File or directory does not exist */
+#define SOL_ESRCH          3     /* Process did not exist            */
+#define	SOL_EINTR          4     /* System call was interrupted      */
+#define	SOL_EIO            5     /* An i/o error occurred            */
+#define	SOL_ENXIO          6     /* Device or Address does not exist */
+#define	SOL_E2BIG          7	 /* Too many arguments were given    */
+#define	SOL_ENOEXEC        8     /* Header of executable was munged  */
+#define	SOL_EBADF          9     /* Bogus file number                */
+#define	SOL_ECHILD         10    /* No children of process exist     */
+#define	SOL_EAGAIN         11    /* beep beep, "try again later"     */
+#define	SOL_ENOMEM         12    /* No memory available              */
+#define	SOL_EACCES         13    /* Access not allowed               */
+#define	SOL_EFAULT         14    /* Address passed was invalid       */
+#define	SOL_ENOTBLK        15    /* blkdev op on non-block device    */
+#define	SOL_EBUSY          16    /* Mounted device was busy          */
+#define	SOL_EEXIST         17    /* File specified already exists    */
+#define	SOL_EXDEV          18    /* Link request across diff devices */
+#define	SOL_ENODEV         19    /* Device does not exist on system  */
+#define	SOL_ENOTDIR        20    /* Dir operation on non-directory   */
+#define	SOL_EISDIR         21    /* File was of directory type       */
+#define	SOL_EINVAL         22    /* Argument passed was invalid      */
+#define	SOL_ENFILE         23    /* No more room in file table       */
+#define	SOL_EMFILE         24    /* Proc has too many files open     */
+#define	SOL_ENOTTY         25    /* Ioctl was invalid for req device */
+#define	SOL_ETXTBSY        26    /* Text file in busy state          */
+#define	SOL_EFBIG          27    /* Too big of a file for operation  */
+#define	SOL_ENOSPC         28    /* Disk is full                     */
+#define	SOL_ESPIPE         29    /* Seek attempted on non-seeking dev*/
+#define	SOL_EROFS          30    /* Write attempted on read-only fs  */
+#define	SOL_EMLINK         31    /* Too many links in file search    */
+#define	SOL_EPIPE          32    /* Call a plumber                   */
+#define	SOL_EDOM           33    /* Argument was out of fct domain   */
+#define	SOL_ERANGE         34    /* Could not represent math result  */
+#define	SOL_ENOMSG         35    /* Message of req type doesn't exist */
+#define	SOL_EIDRM          36    /* Identifier has been removed      */
+#define	SOL_ECHRNG         37    /* Req channel number out of range  */
+#define	SOL_EL2NSYNC       38    /* Could not sync at run level 2    */
+#define	SOL_EL3HLT         39    /* Halted at run level 3            */
+#define	SOL_EL3RST         40    /* Reset at run level 3             */
+#define	SOL_ELNRNG         41    /* Out of range link number         */
+#define	SOL_EUNATCH        42    /* Driver for protocol not attached */
+#define	SOL_ENOCSI         43    /* CSI structure not around         */
+#define	SOL_EL2HLT         44    /* Halted at run level 2            */
+#define	SOL_EDEADLK        45    /* Deadlock condition detected      */
+#define	SOL_ENOLCK         46    /* Record locks unavailable         */
+#define	SOL_ECANCELED      47    /* Cancellation of oper. happened   */
+#define	SOL_ENOTSUP        48    /* Attempt of unsupported operation */
+#define	SOL_EDQUOT         49    /* Users disk quota exceeded        */
+#define	SOL_EBADE          50    /* Invalid exchange                 */
+#define	SOL_EBADR          51    /* Request descriptor was invalid   */
+#define	SOL_EXFULL         52    /* Full exchange                    */
+#define	SOL_ENOANO         53    /* ano does not exist               */
+#define	SOL_EBADRQC        54    /* Req code was invalid             */
+#define	SOL_EBADSLT        55    /* Bad slot number                  */
+#define	SOL_EDEADLOCK      56    /* Deadlock in fs error             */
+#define	SOL_EBFONT         57    /* Font file format invalid         */
+/* YOW, I LOVE SYSV STREAMS!!!! */
+#define	SOL_ENOSTR         60    /* Stream-op on non-stream dev      */
+#define	SOL_ENODATA        61    /* No data avail at this time       */
+#define	SOL_ETIME          62    /* Expiration of time occurred      */
+#define	SOL_ENOSR          63    /* Streams resources exhausted      */
+#define	SOL_ENONET         64    /* No network connected             */
+#define	SOL_ENOPKG         65    /* Non-installed package            */
+#define	SOL_EREMOTE        66    /* Object was on remote machine     */
+#define	SOL_ENOLINK        67    /* Cut link                         */
+#define	SOL_EADV           68    /* Error in advertise               */
+#define	SOL_ESRMNT         69    /* Some magic srmount problem       */
+#define	SOL_ECOMM          70    /* During send, comm error occurred */
+#define	SOL_EPROTO         71    /* Protocol botch                   */
+#define	SOL_EMULTIHOP      74    /* Multihop attempted               */
+#define	SOL_EBADMSG        77    /* Message was unreadable           */
+#define	SOL_ENAMETOOLONG   78    /* Too long of a path name          */
+#define	SOL_EOVERFLOW      79    /* Data type too small for datum    */
+#define	SOL_ENOTUNIQ       80    /* Logical name was not unique      */
+#define	SOL_EBADFD         81    /* Op cannot be performed on fd     */
+#define	SOL_EREMCHG        82    /* Remote address is now different  */
+#define	SOL_ELIBACC        83    /* Shared lib could not be accessed */
+#define	SOL_ELIBBAD        84    /* ShLib is corrupted in some way   */
+#define	SOL_ELIBSCN        85    /* A.out ShLib problems             */
+#define	SOL_ELIBMAX        86    /* Exceeded ShLib linkage limit     */
+#define	SOL_ELIBEXEC       87    /* Execution of ShLib attempted     */
+#define	SOL_EILSEQ         88    /* Bad byte sequence found          */
+#define	SOL_ENOSYS         89    /* Invalid filesystem operation     */
+#define	SOL_ELOOP          90    /* Detected loop in symbolic links  */
+#define	SOL_ERESTART       91    /* System call is restartable       */
+#define	SOL_ESTRPIPE       92    /* Do not sleep in head of stream   */
+#define	SOL_ENOTEMPTY      93    /* Rmdir of non-empty directory     */
+#define	SOL_EUSERS         94    /* Over abundance of users for ufs  */
+#define	SOL_ENOTSOCK       95    /* Sock-op on non-sock              */
+#define	SOL_EDESTADDRREQ   96    /* No dest addr given, but needed   */
+#define	SOL_EMSGSIZE       97    /* Msg too big                      */
+#define	SOL_EPROTOTYPE     98    /* Bad socket protocol              */
+#define	SOL_ENOPROTOOPT    99    /* Unavailable protocol             */
+#define	SOL_EPROTONOSUPPORT 120  /* Unsupported protocol             */
+#define	SOL_ESOCKTNOSUPPORT 121  /* Unsupported socket type          */
+#define	SOL_EOPNOTSUPP     122   /* Unsupported sock-op              */
+#define	SOL_EPFNOSUPPORT   123   /* Unsupported protocol family      */
+#define	SOL_EAFNOSUPPORT   124   /* Unsup addr family for protocol   */
+#define	SOL_EADDRINUSE     125   /* Req addr is already in use       */
+#define	SOL_EADDRNOTAVAIL  126   /* Req addr not available right now */
+#define	SOL_ENETDOWN       127   /* Your subnet is on fire           */
+#define	SOL_ENETUNREACH    128   /* Someone playing with gateway and */
+                                 /* did not tell you he was going to */
+#define	SOL_ENETRESET      129   /* Buy less-buggy ethernet cards    */
+#define	SOL_ECONNABORTED   130   /* Aborted connection due to sw     */
+#define	SOL_ECONNRESET     131   /* Your peers reset your connection */
+#define	SOL_ENOBUFS        132   /* No buffer space available        */
+#define	SOL_EISCONN        133   /* Connect on already connected     */
+                                 /* socket attempted                 */
+#define	SOL_ENOTCONN       134   /* Comm on non-connected socket     */
+#define	SOL_ESHUTDOWN      143   /* Op attempted after sock-shutdown */
+#define	SOL_ETOOMANYREFS   144   /* Reference limit exceeded         */
+#define	SOL_ETIMEDOUT      145   /* Timed out connection             */
+#define	SOL_ECONNREFUSED   146   /* Connection refused by remote host*/
+#define	SOL_EHOSTDOWN      147   /* Remote host is up in flames      */
+#define	SOL_EHOSTUNREACH   148   /* Make a left at Easton Ave.....   */
+#define	SOL_EWOULDBLOCK    EAGAIN /* Just an alias */
+#define	SOL_EALREADY       149   /* Operation is already occurring   */
+#define	SOL_EINPROGRESS    150   /* Operation is happening now       */
+#define	SOL_ESTALE         151   /* Fungus growth on NFS file handle */
+
+#endif /* !(_SPARC64_SOLERRNO_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/spitfire.h linux/include/asm-sparc64/spitfire.h
--- v2.1.18/linux/include/asm-sparc64/spitfire.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/spitfire.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,197 @@
+/* $Id: spitfire.h,v 1.2 1996/12/28 18:39:55 davem Exp $
+ * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_SPITFIRE_H
+#define _SPARC64_SPITFIRE_H
+
+#include <asm/asi.h>
+
+/* The following register addresses are accessible via ASI_DMMU
+ * and ASI_IMMU, that is there is a distinct and unique copy of
+ * each these registers for each TLB.
+ */
+#define TSB_TAG_TARGET		0x0000000000000000
+#define TLB_SFSR		0x0000000000000018
+#define TSB_REG			0x0000000000000028
+#define TLB_TAG_ACCESS		0x0000000000000030
+
+/* These registers only exist as one entity, and are accessed
+ * via ASI_DMMU only.
+ */
+#define PRIMARY_CONTEXT		0x0000000000000008
+#define SECONDARY_CONTEXT	0x0000000000000010
+#define DMMU_SFAR		0x0000000000000020
+#define VIRT_WATCHPOINT		0x0000000000000038
+#define PHYS_WATCHPOINT		0x0000000000000040
+
+#ifndef __ASSEMBLY__
+
+extern __inline__ unsigned long spitfire_get_primary_context(void)
+{
+	unsigned long ctx;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (ctx)
+			     : "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+}
+
+extern __inline__ unsigned long spitfire_set_primary_context(unsigned long ctx)
+{
+	__asm__ __volatile__("stxa	%0, [%1] %2"
+			     : : "r" (ctx), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+}
+
+extern __inline__ unsigned long spitfire_get_secondary_context(void)
+{
+	unsigned long ctx;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (ctx)
+			     : "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU));
+}
+
+extern __inline__ unsigned long spitfire_set_secondary_context(unsigned long ctx)
+{
+	__asm__ __volatile__("stxa	%0, [%1] %2"
+			     : : "r" (ctx), "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU));
+}
+
+/* The data cache is write through, so this just invalidates the
+ * specified line.
+ */
+extern __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
+{
+	__asm__ __volatile__("stxa	%0, [%1] %2"
+			     : /* No outputs */
+			     : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
+}
+
+/* The instruction cache lines are flushed with this, but note that
+ * this does not flush the pipeline.  It is possible for a line to
+ * get flushed but stale instructions to still be in the pipeline,
+ * a flush instruction (to any address) is sufficient to handle
+ * this issue after the line is invalidated.
+ */
+extern __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
+{
+	__asm__ __volatile__("stxa	%0, [%1] %2"
+			     : /* No outputs */
+			     : "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
+}
+
+extern __inline__ unsigned long spitfire_get_dtlb_data(int entry)
+{
+	unsigned long data;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (data)
+			     : "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS));
+	return data;
+}
+
+extern __inline__ unsigned long spitfire_put_dtlb_data(int entry, unsigned long data)
+{
+	__asm__ __volatile__("stxa	%0, [%1] %2"
+			     : : "r" (data), "r" (entry << 3),
+			         "i" (ASI_DTLB_DATA_ACCESS));
+}
+
+extern __inline__ unsigned long spitfire_get_itlb_data(int entry)
+{
+	unsigned long data;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (data)
+			     : "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS));
+	return data;
+}
+
+extern __inline__ unsigned long spitfire_put_itlb_data(int entry, unsigned long data)
+{
+	__asm__ __volatile__("stxa	%0, [%1] %2"
+			     : : "r" (data), "r" (entry << 3),
+			         "i" (ASI_ITLB_DATA_ACCESS));
+}
+
+/* Spitfire hardware assisted TLB flushes. */
+
+/* Context level flushes. */
+extern __inline__ void spitfire_flush_dtlb_primary_context(void)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (0x40), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_primary_context(void)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (0x40), "i" (ASI_IMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_dtlb_secondary_context(void)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (0x41), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_secondary_context(void)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (0x41), "i" (ASI_IMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_dtlb_nucleus_context(void)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (0x42), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_nucleus_context(void)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (0x42), "i" (ASI_IMMU_DEMAP));
+}
+
+/* Page level flushes. */
+extern __inline__ void spitfire_flush_dtlb_primary_page(unsigned long page)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (page), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_primary_page(unsigned long page)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (page), "i" (ASI_IMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_dtlb_secondary_page(unsigned long page)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (page | 0x10), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_secondary_page(unsigned long page)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (page | 0x10), "i" (ASI_IMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_dtlb_nucleus_page(unsigned long page)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_nucleus_page(unsigned long page)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+			     : : "r" (page | 0x20), "i" (ASI_IMMU_DEMAP));
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_SPARC64_SPITFIRE_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/stat.h linux/include/asm-sparc64/stat.h
--- v2.1.18/linux/include/asm-sparc64/stat.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/stat.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,62 @@
+/* $Id: stat.h,v 1.1 1996/12/26 14:22:31 davem Exp $ */
+#ifndef _SPARC64_STAT_H
+#define _SPARC64_STAT_H
+
+#include <linux/types.h>
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+/* XXX Fix this for full backwards 32-bit compat. */
+struct stat32 {
+	dev_t   st_dev;
+	ino_t   st_ino;
+	mode_t  st_mode;
+	short   st_nlink;
+	uid_t   st_uid;
+	gid_t   st_gid;
+	dev_t   st_rdev;
+	off_t   st_size;
+	time_t  st_atime;
+	unsigned int  __unused1;
+	time_t  st_mtime;
+	unsigned int  __unused2;
+	time_t  st_ctime;
+	unsigned int  __unused3;
+	off_t   st_blksize;
+	off_t   st_blocks;
+	unsigned int  __unused4[2];
+};
+
+struct stat {
+	dev_t   st_dev;
+	ino_t   st_ino;
+	mode_t  st_mode;
+	short   st_nlink;
+	uid_t   st_uid;
+	gid_t   st_gid;
+	dev_t   st_rdev;
+	off_t   st_size;
+	time_t  st_atime;
+	unsigned long  __unused1;
+	time_t  st_mtime;
+	unsigned long  __unused2;
+	time_t  st_ctime;
+	unsigned long  __unused3;
+	off_t   st_blksize;
+	off_t   st_blocks;
+	unsigned long  __unused4[2];
+};
+
+#endif
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/statfs.h linux/include/asm-sparc64/statfs.h
--- v2.1.18/linux/include/asm-sparc64/statfs.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/statfs.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,40 @@
+/* $Id: statfs.h,v 1.1 1996/12/26 14:22:40 davem Exp $ */
+#ifndef _SPARC64_STATFS_H
+#define _SPARC64_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+/* XXX Fix this for full backwards 32-bit compat. */
+struct statfs32 {
+	int f_type;
+	int f_bsize;
+	int f_blocks;
+	int f_bfree;
+	int f_bavail;
+	int f_files;
+	int f_ffree;
+	__kernel_fsid_t f_fsid;
+	int f_namelen;  /* SunOS ignores this field. */
+	int f_spare[6];
+};
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/string.h linux/include/asm-sparc64/string.h
--- v2.1.18/linux/include/asm-sparc64/string.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/string.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,178 @@
+/* $Id: string.h,v 1.1 1996/12/26 14:22:40 davem Exp $
+ * string.h: External definitions for optimized assembly string
+ *           routines for the Linux Kernel.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC64_STRING_H__
+#define __SPARC64_STRING_H__
+
+/* Really, userland/ksyms should not see any of this stuff. */
+
+#if defined(__KERNEL__) && !defined(EXPORT_SYMTAB)
+
+/* First the mem*() things. */
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_MEMCPY
+extern void *__memcpy(void *,const void *,__kernel_size_t);
+
+extern inline void *__constant_memcpy(void *to, const void *from, __kernel_size_t n)
+{
+	extern void __copy_1page(void *, const void *);
+
+	if(n <= 32) {
+		__builtin_memcpy(to, from, n);
+	} else {
+		switch(n) {
+		case 8192:
+			__copy_1page(to, from);
+			break;
+		default:
+			__memcpy(to, from, n);
+			break;
+		}
+	}
+	return to;
+}
+
+extern inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_size_t n)
+{
+	__memcpy(to, from, n);
+	return to;
+}
+
+#undef memcpy
+#define memcpy(t, f, n) \
+(__builtin_constant_p(n) ? \
+ __constant_memcpy((t),(f),(n)) : \
+ __nonconstant_memcpy((t),(f),(n)))
+
+#define __HAVE_ARCH_MEMSET
+extern void *__memset(void *,int,__kernel_size_t);
+
+extern inline void *__constant_c_and_count_memset(void *s, char c, size_t count)
+{
+	extern void *bzero_1page(void *);
+	extern void *__bzero(void *, size_t);
+
+	if(!c) {
+		if(count == 8192)
+			bzero_1page(s);
+		else
+			__bzero(s, count);
+	} else {
+		__memset(s, c, count);
+	}
+	return s;
+}
+
+extern inline void *__constant_c_memset(void *s, char c, size_t count)
+{
+	extern void *__bzero(void *, size_t);
+
+	if(!c)
+		__bzero(s, count);
+	else
+		__memset(s, c, count);
+	return s;
+}
+
+#undef memset
+#define memset(s, c, count) \
+(__builtin_constant_p(c) ? (__builtin_constant_p(count) ? \
+                            __constant_c_and_count_memset((s), (c), (count)) : \
+                            __constant_c_memset((s), (c), (count))) \
+                         : __memset((s), (c), (count)))
+
+#define __HAVE_ARCH_MEMSCAN
+
+#undef memscan
+#define memscan(__arg0, __char, __arg2)						\
+({										\
+	extern void *__memscan_zero(void *, size_t);				\
+	extern void *__memscan_generic(void *, int, size_t);			\
+	void *__retval, *__addr = (__arg0);					\
+	size_t __size = (__arg2);						\
+										\
+	if(__builtin_constant_p(__char) && !(__char))				\
+		__retval = __memscan_zero(__addr, __size);			\
+	else									\
+		__retval = __memscan_generic(__addr, (__char), __size);		\
+										\
+	__retval;								\
+})
+
+#define __HAVE_ARCH_MEMCMP
+
+/* Now the str*() stuff... */
+#define __HAVE_ARCH_STRLEN
+
+#define __HAVE_ARCH_STRNCMP
+
+extern int __strncmp(const char *, const char *, __kernel_size_t);
+
+extern inline int __constant_strncmp(const char *src, const char *dest, __kernel_size_t count)
+{
+	register int retval;
+	switch(count) {
+	case 0: return 0;
+	case 1: return (src[0] - dest[0]);
+	case 2: retval = (src[0] - dest[0]);
+		if(!retval && src[0])
+		  retval = (src[1] - dest[1]);
+		return retval;
+	case 3: retval = (src[0] - dest[0]);
+		if(!retval && src[0]) {
+		  retval = (src[1] - dest[1]);
+		  if(!retval && src[1])
+		    retval = (src[2] - dest[2]);
+		}
+		return retval;
+	case 4: retval = (src[0] - dest[0]);
+		if(!retval && src[0]) {
+		  retval = (src[1] - dest[1]);
+		  if(!retval && src[1]) {
+		    retval = (src[2] - dest[2]);
+		    if (!retval && src[2])
+		      retval = (src[3] - dest[3]);
+		  }
+		}
+		return retval;
+	case 5: retval = (src[0] - dest[0]);
+		if(!retval && src[0]) {
+		  retval = (src[1] - dest[1]);
+		  if(!retval && src[1]) {
+		    retval = (src[2] - dest[2]);
+		    if (!retval && src[2]) {
+		      retval = (src[3] - dest[3]);
+		      if (!retval && src[3])
+		        retval = (src[4] - dest[4]);
+		    }
+		  }
+		}
+		return retval;
+	default:
+		retval = (src[0] - dest[0]);
+		if(!retval && src[0]) {
+		  retval = (src[1] - dest[1]);
+		  if(!retval && src[1]) {
+		    retval = (src[2] - dest[2]);
+		    if(!retval && src[2])
+		      retval = __strncmp(src+3,dest+3,count-3);
+		  }
+		}
+		return retval;
+	}
+}
+
+#undef strncmp
+#define strncmp(__arg0, __arg1, __arg2)	\
+(__builtin_constant_p(__arg2) ?	\
+ __constant_strncmp(__arg0, __arg1, __arg2) : \
+ __strncmp(__arg0, __arg1, __arg2))
+
+#endif /* (__KERNEL__) && !(EXPORT_SYMTAB) */
+
+#endif /* !(__SPARC64_STRING_H__) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/svr4.h linux/include/asm-sparc64/svr4.h
--- v2.1.18/linux/include/asm-sparc64/svr4.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/svr4.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,130 @@
+/* Solaris/SPARC constants and definitions -- 
+ * (C) 1996 Miguel de Icaza
+ *
+ * This file is not meant to be included by user level applications
+ * but the solaris syscall emulator
+ */
+
+#ifndef _SPARC64_SVR4_H
+#define _SPARC64_SVR4_H
+
+/* Signals as used by svr4 */
+typedef struct {                /* signal set type */
+	uint sigbits[4];
+} svr4_sigset_t;
+
+/* Values for siginfo.code */
+#define SVR4_SINOINFO 32767
+/* Siginfo, sucker expects bunch of information on those parameters */
+typedef union {
+	char total_size [128];
+	struct {
+		int signo;
+		int code;
+		int error;
+		union {
+		} data; 
+	} siginfo;
+} svr4_siginfo_t;
+
+/* Context definition */
+
+/* Location of the user stored registers into a greg_t */
+enum {
+	SVR4_PSR, SVR4_PC, SVR4_NPC, SVR4_Y,
+	SVR4_G1,  SVR4_G2, SVR4_G3,  SVR4_G4,
+	SVR4_G5,  SVR4_G6, SVR4_G7,  SVR4_O0,
+	SVR4_O1,  SVR4_O2, SVR4_O3,  SVR4_O4,
+	SVR4_O5,  SVR4_O6, SVR4_O7
+};
+
+/* sizeof (regs) / sizeof (greg_t), defined in the ABI */
+#define SVR4_NREGS  19
+#define SVR4_MAXWIN 31
+
+typedef struct {
+	uint rwin_lo[8];
+	uint rwin_in[8];
+} svr4_rwindow_t;
+
+typedef struct {
+	int            count;
+
+	/* XXX 32-bit pointers on 64-bit kernel... fixme XXX */
+	int            *winptr [SVR4_MAXWIN]; /* pointer to the windows */
+
+	svr4_rwindow_t win[SVR4_MAXWIN];      /* the windows */
+} svr4_gwindows_t;
+
+typedef int svr4_gregset_t[SVR4_NREGS];
+
+typedef struct {
+	double   fpu_regs[32];
+	void     *fp_q;
+	unsigned fp_fsr;
+	u_char   fp_nqel;
+	u_char   fp_nqsize;
+	u_char   inuse;		/* if fpu is in use */
+} svr4_fregset_t;
+
+typedef struct {
+	uint    id;		/* if this holds "xrs" string => ptr is valid */
+
+	/* XXX what is caddr_t on sparc64?? XXX */
+	caddr_t ptr;
+} svr4_xrs_t;
+
+/* Machine dependant context */
+typedef struct {
+	svr4_gregset_t   greg;	/* registers 0..19 (see top) */
+
+	/* XXX 32-bit pointers again... fixme XXX */
+	svr4_gwindows_t  *gwin;	/* may point to register windows */
+
+	svr4_fregset_t   freg;	/* floating point registers */
+	svr4_xrs_t       xrs;	/* mhm? */
+	int              pad[19];
+} svr4_mcontext_t;
+
+/* flags for stack_t.flags */
+enum svr4_stack_flags {
+	SS_ONSTACK,
+	SVR4_SS_DISABLE,
+};
+
+/* signal stack exection place, unsupported */
+typedef struct svr4_stack_t {
+        char *sp;
+        int  size;
+        int  flags;
+} svr4_stack_t;
+
+/* Context used by getcontext and setcontext */
+typedef struct svr4_ucontext_t {
+	u_int                flags; /* context flags, indicate what is loaded */
+
+	/* XXX 32-bit pointer... fixme XXX */
+	struct svr4_ucontext *link;
+
+	svr4_sigset_t        sigmask;
+	svr4_stack_t         stack;
+	svr4_mcontext_t      mcontext;
+	int                  pad[23];
+} svr4_ucontext_t;                          
+
+/* windows hold the windows as they were at signal time,
+ * ucontext->mcontext holds a pointer to them.
+ * addresses for uc and si are passed as parameters to svr4 signal
+ * handler
+ */
+
+/* This is the signal frame that is passed to the signal handler */
+typedef struct {
+	svr4_gwindows_t gw;	/* windows */
+	svr4_ucontext_t uc;	/* machine context */
+	svr4_siginfo_t  si;	/* siginfo */
+} svr4_signal_frame_t;
+
+#define SVR4_SF_ALIGNED (((sizeof (svr4_signal_frame_t) + 7) & (~7)))
+
+#endif /* include control */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/system.h linux/include/asm-sparc64/system.h
--- v2.1.18/linux/include/asm-sparc64/system.h	Wed Dec 18 15:59:02 1996
+++ linux/include/asm-sparc64/system.h	Mon Dec 30 12:00:03 1996
@@ -1,7 +1,10 @@
-/* $Id: system.h,v 1.2 1996/12/02 00:01:07 davem Exp $ */
+/* $Id: system.h,v 1.4 1996/12/28 18:39:56 davem Exp $ */
 #ifndef __SPARC64_SYSTEM_H
 #define __SPARC64_SYSTEM_H
 
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+
 #define setipl(__new_ipl) \
 	__asm__ __volatile__("wrpr	%0, %%pil"  : : "r" (__new_ipl) : "memory")
 
@@ -43,6 +46,28 @@
 
 #define membar(type)	__asm__ __volatile__ ("membar " type : : : "memory");
 
+#define flushi(addr)	__asm__ __volatile__ ("flush %0" : : "r" (addr))
+
+#define flushw_all()	__asm__ __volatile__("flushw")
+
+#ifndef __ASSEMBLY__
+
+extern __inline__ void flushw_user(void)
+{
+	__asm__ __volatile__("
+		rdpr		%%otherwin, %%g1
+1:
+		rdpr		%%otherwin, %%g2
+		brnz,pn		%%g2, 1b
+		 save		%%sp, %0, %%sp
+1:
+		subcc		%%g1, 1, %%g1
+		bne,pn		%%xcc, 1b
+		 restore	%%g0, %%g0, %%g0
+	" : : "i" (-REGWIN_SZ)
+	  : "g1", "g2");
+}
+
 /* Unlike the hybrid v7/v8 kernel, we can assume swap exists under V9. */
 extern __inline__ unsigned long xchg_u32(__volatile__ unsigned int *m, unsigned int val)
 {
@@ -86,5 +111,7 @@
 	__xchg_called_with_bad_pointer();
 	return x;
 }
+
+#endif /* !(__ASSEMBLY__) */
 
 #endif /* !(__SPARC64_SYSTEM_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/termbits.h linux/include/asm-sparc64/termbits.h
--- v2.1.18/linux/include/asm-sparc64/termbits.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/termbits.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,210 @@
+#ifndef _SPARC64_TERMBITS_H
+#define _SPARC64_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char   cc_t;
+typedef unsigned int    speed_t;
+
+/* XXX is this right for sparc64?  it was an unsigned long... XXX */
+typedef unsigned int    tcflag_t;
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#define NCCS 17
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+#ifdef __KERNEL__
+#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
+	cc_t _x_cc[2];                  /* We need them to hold vmin/vtime */
+#endif
+};
+
+/* c_cc characters */
+#define VINTR    0
+#define VQUIT    1
+#define VERASE   2
+#define VKILL    3
+#define VEOF     4
+#define VEOL     5
+#define VEOL2    6
+#define VSWTC    7
+#define VSTART   8
+#define VSTOP    9
+
+
+
+#define VSUSP    10
+#define VDSUSP   11  /* SunOS POSIX nicety I do believe... */
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE  14
+#define VLNEXT   15
+
+/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is
+ * shared with eof/eol
+ */
+#ifdef __KERNEL__
+#define VMIN     16
+#define VTIME    17
+#else
+#define VMIN     VEOF
+#define VTIME    VEOL
+#endif
+
+/* c_iflag bits */
+#define IGNBRK	0x00000001
+#define BRKINT	0x00000002
+#define IGNPAR	0x00000004
+#define PARMRK	0x00000008
+#define INPCK	0x00000010
+#define ISTRIP	0x00000020
+#define INLCR	0x00000040
+#define IGNCR	0x00000080
+#define ICRNL	0x00000100
+#define IUCLC	0x00000200
+#define IXON	0x00000400
+#define IXANY	0x00000800
+#define IXOFF	0x00001000
+#define IMAXBEL	0x00002000
+
+/* c_oflag bits */
+#define OPOST	0x00000001
+#define OLCUC	0x00000002
+#define ONLCR	0x00000004
+#define OCRNL	0x00000008
+#define ONOCR	0x00000010
+#define ONLRET	0x00000020
+#define OFILL	0x00000040
+#define OFDEL	0x00000080
+#define NLDLY	0x00000100
+#define   NL0	0x00000000
+#define   NL1	0x00000100
+#define CRDLY	0x00000600
+#define   CR0	0x00000000
+#define   CR1	0x00000200
+#define   CR2	0x00000400
+#define   CR3	0x00000600
+#define TABDLY	0x00001800
+#define   TAB0	0x00000000
+#define   TAB1	0x00000800
+#define   TAB2	0x00001000
+#define   TAB3	0x00001800
+#define   XTABS	0x00001800
+#define BSDLY	0x00002000
+#define   BS0	0x00000000
+#define   BS1	0x00002000
+#define VTDLY	0x00004000
+#define   VT0	0x00000000
+#define   VT1	0x00004000
+#define FFDLY	0x00008000
+#define   FF0	0x00000000
+#define   FF1	0x00008000
+#define PAGEOUT 0x00010000  /* SUNOS specific */
+#define WRAP    0x00020000  /* SUNOS specific */
+
+/* c_cflag bit meaning */
+#define CBAUD	0x0000000f
+#define  B0	0x00000000   /* hang up */
+#define  B50	0x00000001
+#define  B75	0x00000002
+#define  B110	0x00000003
+#define  B134	0x00000004
+#define  B150	0x00000005
+#define  B200	0x00000006
+#define  B300	0x00000007
+#define  B600	0x00000008
+#define  B1200	0x00000009
+#define  B1800	0x0000000a
+#define  B2400	0x0000000b
+#define  B4800	0x0000000c
+#define  B9600	0x0000000d
+#define  B19200	0x0000000e
+#define  B38400	0x0000000f
+#define EXTA    B19200
+#define EXTB    B38400
+#define  CSIZE  0x00000030
+#define   CS5	0x00000000
+#define   CS6	0x00000010
+#define   CS7	0x00000020
+#define   CS8	0x00000030
+#define CSTOPB	0x00000040
+#define CREAD	0x00000080
+#define PARENB	0x00000100
+#define PARODD	0x00000200
+#define HUPCL	0x00000400
+#define CLOCAL	0x00000800
+/* We'll never see these speeds with the Zilogs' but for completeness... */
+#define CBAUDEX 0x00010000
+#define  B57600  0x00010001
+#define  B115200 0x00010002
+#define  B230400 0x00010003
+#define  B460800 0x00010004
+#define CIBAUD	  0x000f0000  /* input baud rate (not used) */
+#define CRTSCTS	  0x80000000  /* flow control */
+
+/* c_lflag bits */
+#define ISIG	0x00000001
+#define ICANON	0x00000002
+#define XCASE	0x00000004
+#define ECHO	0x00000008
+#define ECHOE	0x00000010
+#define ECHOK	0x00000020
+#define ECHONL	0x00000040
+#define NOFLSH	0x00000080
+#define TOSTOP	0x00000100
+#define ECHOCTL	0x00000200
+#define ECHOPRT	0x00000400
+#define ECHOKE	0x00000800
+#define DEFECHO 0x00001000  /* SUNOS thing, what is it? */
+#define FLUSHO	0x00002000
+#define PENDIN	0x00004000
+#define IEXTEN	0x00008000
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* !(_SPARC64_TERMBITS_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/termios.h linux/include/asm-sparc64/termios.h
--- v2.1.18/linux/include/asm-sparc64/termios.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/termios.h	Mon Dec 30 12:54:46 1996
@@ -0,0 +1,158 @@
+/* $Id: termios.h,v 1.2 1996/12/30 03:31:12 davem Exp $ */
+#ifndef _SPARC64_TERMIOS_H
+#define _SPARC64_TERMIOS_H
+
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
+
+#if defined(__KERNEL__) || defined(__DEFINE_BSD_TERMIOS)
+struct sgttyb {
+	char	sg_ispeed;
+	char	sg_ospeed;
+	char	sg_erase;
+	char	sg_kill;
+	short	sg_flags;
+};
+
+struct tchars {
+	char	t_intrc;
+	char	t_quitc;
+	char	t_startc;
+	char	t_stopc;
+	char	t_eofc;
+	char	t_brkc;
+};
+
+struct ltchars {
+	char	t_suspc;
+	char	t_dsuspc;
+	char	t_rprntc;
+	char	t_flushc;
+	char	t_werasc;
+	char	t_lnextc;
+};
+#endif /* __KERNEL__ */
+
+struct sunos_ttysize {
+	int st_lines;   /* Lines on the terminal */
+	int st_columns; /* Columns on the terminal */
+};
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+
+#ifdef __KERNEL__
+
+/*
+ * c_cc characters in the termio structure.  Oh, how I love being
+ * backwardly compatible.  Notice that character 4 and 5 are
+ * interpreted differently depending on whether ICANON is set in
+ * c_lflag.  If it's set, they are used as _VEOF and _VEOL, otherwise
+ * as _VMIN and V_TIME.  This is for compatibility with OSF/1 (which
+ * is compatible with sysV)...
+ */
+#define _VMIN	4
+#define _VTIME	5
+
+/*	intr=^C		quit=^\		erase=del	kill=^U
+	eof=^D		eol=\0		eol2=\0		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		dsusp=^Y
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	vmin=\1         vtime=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\000\000\000\021\023\032\031\022\025\027\026\001\000"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+	unsigned short tmp; \
+	get_user(tmp, &(termio)->c_iflag); \
+	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	get_user(tmp, &(termio)->c_oflag); \
+	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	get_user(tmp, &(termio)->c_cflag); \
+	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	get_user(tmp, &(termio)->c_lflag); \
+	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+} while(0)
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ *
+ * Note the "fun" _VMIN overloading.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+	if (!((termios)->c_lflag & ICANON)) { \
+		put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+		put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+	} \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) \
+do { \
+	get_user((k)->c_iflag, &(u)->c_iflag); \
+	get_user((k)->c_oflag, &(u)->c_oflag); \
+	get_user((k)->c_cflag, &(u)->c_cflag); \
+	get_user((k)->c_lflag, &(u)->c_lflag); \
+	get_user((k)->c_line,  &(u)->c_line); \
+	copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+	if((k)->c_lflag & ICANON) { \
+		get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+		get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+	} else { \
+		get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+		get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+	} \
+} while(0)
+
+#define kernel_termios_to_user_termios(u, k) \
+do { \
+	put_user((k)->c_iflag, &(u)->c_iflag); \
+	put_user((k)->c_oflag, &(u)->c_oflag); \
+	put_user((k)->c_cflag, &(u)->c_cflag); \
+	put_user((k)->c_lflag, &(u)->c_lflag); \
+	put_user((k)->c_line, &(u)->c_line); \
+	copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+	if(!((k)->c_lflag & ICANON)) { \
+		put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+		put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+	} else { \
+		put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+		put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+	} \
+} while(0)
+
+#endif	/* __KERNEL__ */
+
+#endif /* _SPARC64_TERMIOS_H */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/uaccess.h linux/include/asm-sparc64/uaccess.h
--- v2.1.18/linux/include/asm-sparc64/uaccess.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/uaccess.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,380 @@
+/* $Id: uaccess.h,v 1.2 1996/12/26 15:36:53 davem Exp $ */
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+
+#ifdef __KERNEL__
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <asm/a.out.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+/* Sparc is not segmented, however we need to be able to fool verify_area()
+ * when doing system calls from kernel mode legitimately.
+ *
+ * "For historical reasons, these macros are grossly misnamed." -Linus
+ */
+#define KERNEL_DS   0
+#define USER_DS     -1
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+#define get_fs() (current->tss.current_ds)
+#define get_ds() (KERNEL_DS)
+#define set_fs(val) ((current->tss.current_ds) = (val))
+
+/* We have there a nice not-mapped page at page_offset - PAGE_SIZE, so that this test
+ * can be fairly lightweight.
+ * No one can read/write anything from userland in the kernel space by setting
+ * large size and address near to page_offset - a fault will break his intentions.
+ */
+#define __user_ok(addr,size) ((addr) < PAGE_OFFSET)
+#define __kernel_ok (get_fs() == KERNEL_DS)
+#define __access_ok(addr,size) (__user_ok((addr) & get_fs(),(size)))
+#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ *
+ * There is a special way how to put a range of potentially faulting
+ * insns (like twenty ldd/std's with now intervening other instructions)
+ * You specify address of first in insn and 0 in fixup and in the next 
+ * exception_table_entry you specify last potentially faulting insn + 1
+ * and in fixup the routine which should handle the fault.
+ * That fixup code will get
+ * (faulting_insn_address - first_insn_in_the_range_address)/4
+ * in %g2 (ie. index of the faulting instruction in the range).
+ */
+
+struct exception_table_entry
+{
+        unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long, unsigned long *);
+
+extern void __ret_efault(void);
+
+/* Uh, these should become the main single-value transfer routines..
+ * They automatically use the right size if we just have the right
+ * pointer type..
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the uglyness from the user.
+ */
+#define put_user(x,ptr) ({ \
+unsigned long __pu_addr = (unsigned long)(ptr); \
+__put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
+
+#define put_user_ret(x,ptr,retval) ({ \
+unsigned long __pu_addr = (unsigned long)(ptr); \
+__put_user_check_ret((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr)),retval); })
+
+#define get_user(x,ptr) ({ \
+unsigned long __gu_addr = (unsigned long)(ptr); \
+__get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
+
+#define get_user_ret(x,ptr,retval) ({ \
+unsigned long __gu_addr = (unsigned long)(ptr); \
+__get_user_check_ret((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr)),retval); })
+
+/*
+ * The "__xxx" versions do not do address space checking, useful when
+ * doing multiple accesses to the same area (the user has to do the
+ * checks by hand with "access_ok()")
+ */
+#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __put_user_ret(x,ptr,retval) __put_user_nocheck_ret((x),(ptr),sizeof(*(ptr)),retval)
+#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)))
+#define __get_user_ret(x,ptr,retval) __get_user_nocheck_ret((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)),retval)
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) ((struct __large_struct *)(x))
+
+#define __put_user_check(x,addr,size) ({ \
+register int __pu_ret; \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
+case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
+case 4: __put_user_asm(x,w,addr,__pu_ret); break; \
+case 8: __put_user_asm(x,x,addr,__pu_ret); break; \
+default: __pu_ret = __put_user_bad(); break; \
+} } else { __pu_ret = -EFAULT; } __pu_ret; })
+
+#define __put_user_check_ret(x,addr,size,retval) ({ \
+register int __foo __asm__ ("l1"); \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \
+case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \
+case 4: __put_user_asm_ret(x,w,addr,retval,__foo); break; \
+case 8: __put_user_asm_ret(x,x,addr,retval,__foo); break; \
+default: if (__put_user_bad()) return retval; break; \
+} } else return retval; })
+
+#define __put_user_nocheck(x,addr,size) ({ \
+register int __pu_ret; \
+switch (size) { \
+case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
+case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
+case 4: __put_user_asm(x,w,addr,__pu_ret); break; \
+case 8: __put_user_asm(x,x,addr,__pu_ret); break; \
+default: __pu_ret = __put_user_bad(); break; \
+} __pu_ret; })
+
+#define __put_user_nocheck_ret(x,addr,size,retval) ({ \
+register int __foo __asm__ ("l1"); \
+switch (size) { \
+case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \
+case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \
+case 4: __put_user_asm_ret(x,w,addr,retval,__foo); break; \
+case 8: __put_user_asm_ret(x,x,addr,retval,__foo); break; \
+default: if (__put_user_bad()) return retval; break; \
+} })
+
+#define __put_user_asm(x,size,addr,ret)					\
+__asm__ __volatile__(							\
+	"/* Put user asm, inline. */\n"					\
+"1:\t"	"st"#size " %1, [%2]\n\t"					\
+	"clr	%0\n"							\
+"2:\n\n\t"								\
+	".section .fixup,#alloc,#execinstr\n\t"				\
+	".align	4\n"							\
+"3:\n\t"								\
+	"b	2b\n\t"							\
+	" mov	%3, %0\n\n\t"						\
+	".section __ex_table,#alloc\n\t"				\
+	".align	4\n\t"							\
+	".word	1b, 3b\n\t"						\
+	".text\n\n\t"							\
+       : "=&r" (ret) : "r" (x), "r" (__m(addr)),			\
+	 "i" (-EFAULT))
+
+#define __put_user_asm_ret(x,size,addr,ret,foo)				\
+if (__builtin_constant_p(ret) && ret == -EFAULT)			\
+__asm__ __volatile__(							\
+	"/* Put user asm ret, inline. */\n"				\
+"1:\t"	"st"#size " %1, [%2]\n\n\t"					\
+	".section __ex_table,#alloc\n\t"				\
+	".align	4\n\t"							\
+	".word	1b, __ret_efault\n\n\t"					\
+	".text\n\n\t"							\
+       : "=r" (foo) : "r" (x), "r" (__m(addr)));			\
+else									\
+__asm__ __volatile(							\
+	"/* Put user asm ret, inline. */\n"				\
+"1:\t"	"st"#size " %1, [%2]\n\n\t"					\
+	".section .fixup,#alloc,#execinstr\n\t"				\
+	".align	4\n"							\
+"3:\n\t"								\
+	"ret\n\t"							\
+	" restore %%g0, %3, %%o0\n\n\t"					\
+	".section __ex_table,#alloc\n\t"				\
+	".align	4\n\t"							\
+	".word	1b, 3b\n\n\t"						\
+	".text\n\n\t"							\
+       : "=r" (foo) : "r" (x), "r" (__m(addr)), "i" (ret))
+
+extern int __put_user_bad(void);
+
+#define __get_user_check(x,addr,size,type) ({ \
+register int __gu_ret; \
+register unsigned long __gu_val; \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
+case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
+case 4: __get_user_asm(__gu_val,uw,addr,__gu_ret); break; \
+case 8: __get_user_asm(__gu_val,x,addr,__gu_ret); break; \
+default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
+} } else { __gu_val = 0; __gu_ret = -EFAULT; } x = (type) __gu_val; __gu_ret; })
+
+#define __get_user_check_ret(x,addr,size,type,retval) ({ \
+register unsigned long __gu_val __asm__ ("l1"); \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
+case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
+case 4: __get_user_asm_ret(__gu_val,uw,addr,retval); break; \
+case 8: __get_user_asm_ret(__gu_val,x,addr,retval); break; \
+default: if (__get_user_bad()) return retval; \
+} x = (type) __gu_val; } else return retval; })
+
+#define __get_user_nocheck(x,addr,size,type) ({ \
+register int __gu_ret; \
+register unsigned long __gu_val; \
+switch (size) { \
+case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
+case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
+case 4: __get_user_asm(__gu_val,uw,addr,__gu_ret); break; \
+case 8: __get_user_asm(__gu_val,x,addr,__gu_ret); break; \
+default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
+} x = (type) __gu_val; __gu_ret; })
+
+#define __get_user_nocheck_ret(x,addr,size,type,retval) ({ \
+register unsigned long __gu_val __asm__ ("l1"); \
+switch (size) { \
+case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
+case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
+case 4: __get_user_asm_ret(__gu_val,uw,addr,retval); break; \
+case 8: __get_user_asm_ret(__gu_val,x,addr,retval); break; \
+default: if (__get_user_bad()) return retval; \
+} x = (type) __gu_val; })
+
+#define __get_user_asm(x,size,addr,ret)					\
+__asm__ __volatile__(							\
+	"/* Get user asm, inline. */\n"					\
+"1:\t"	"ld"#size " [%2], %1\n\t"					\
+	"clr	%0\n"							\
+"2:\n\n\t"								\
+	".section .fixup,#alloc,#execinstr\n\t"				\
+	".align	4\n"							\
+"3:\n\t"								\
+	"clr	%1\n\t"							\
+	"b	2b\n\t"							\
+	" mov	%3, %0\n\n\t"						\
+	".section __ex_table,#alloc\n\t"				\
+	".align	4\n\t"							\
+	".word	1b, 3b\n\n\t"						\
+	".text\n\t"							\
+       : "=&r" (ret), "=&r" (x) : "r" (__m(addr)),			\
+	 "i" (-EFAULT))
+
+#define __get_user_asm_ret(x,size,addr,retval)				\
+if (__builtin_constant_p(retval) && retval == -EFAULT)			\
+__asm__ __volatile__(							\
+	"/* Get user asm ret, inline. */\n"				\
+"1:\t"	"ld"#size " [%1], %0\n\n\t"					\
+	".section __ex_table,#alloc\n\t"				\
+	".align	4\n\t"							\
+	".word	1b,__ret_efault\n\n\t"					\
+	".text\n\t"							\
+       : "=&r" (x) : "r" (__m(addr)));					\
+else									\
+__asm__ __volatile__(							\
+	"/* Get user asm ret, inline. */\n"				\
+"1:\t"	"ld"#size " [%1], %0\n\n\t"					\
+	".section .fixup,#alloc,#execinstr\n\t"				\
+	".align	4\n"							\
+"3:\n\t"								\
+	"ret\n\t"							\
+	" restore %%g0, %2, %%o0\n\n\t"					\
+	".section __ex_table,#alloc\n\t"				\
+	".align	4\n\t"							\
+	".word	1b, 3b\n\n\t"						\
+	".text\n\t"							\
+       : "=&r" (x) : "r" (__m(addr)), "i" (retval))
+
+extern int __get_user_bad(void);
+
+extern int __copy_user(unsigned long to, unsigned long from, int size);
+
+#define copy_to_user(to,from,n) ({ \
+unsigned long __copy_to = (unsigned long) (to); \
+unsigned long __copy_size = (unsigned long) (n); \
+unsigned long __copy_res; \
+if(__copy_size && __access_ok(__copy_to, __copy_size)) { \
+__copy_res = __copy_user(__copy_to, (unsigned long) (from), __copy_size); \
+} else __copy_res = __copy_size; \
+__copy_res; })
+
+#define copy_to_user_ret(to,from,n,retval) ({ \
+if (copy_to_user(to,from,n)) \
+	return retval; \
+})
+
+#define __copy_to_user(to,from,n)		\
+	__copy_user((unsigned long)(to),	\
+		    (unsigned long)(from), n)
+
+#define __copy_to_user_ret(to,from,n,retval) ({ \
+if (__copy_to_user(to,from,n)) \
+	return retval; \
+})
+
+#define copy_from_user(to,from,n) ({ \
+unsigned long __copy_from = (unsigned long) (from); \
+unsigned long __copy_size = (unsigned long) (n); \
+unsigned long __copy_res; \
+if(__copy_size && __access_ok(__copy_from, __copy_size)) { \
+__copy_res = __copy_user((unsigned long) (to), __copy_from, __copy_size); \
+} else __copy_res = __copy_size; \
+__copy_res; })
+
+#define copy_from_user_ret(to,from,n,retval) ({ \
+if (copy_from_user(to,from,n)) \
+	return retval; \
+})
+
+#define __copy_from_user(to,from,n)		\
+	__copy_user((unsigned long)(to),	\
+		    (unsigned long)(from), n)
+
+#define __copy_from_user_ret(to,from,n,retval) ({ \
+if (__copy_from_user(to,from,n)) \
+	return retval; \
+})
+
+extern int __clear_user(unsigned long addr, int size);
+
+#define clear_user(addr,n) ({ \
+unsigned long __clear_addr = (unsigned long) (addr); \
+int __clear_size = (int) (n); \
+int __clear_res; \
+if(__clear_size && __access_ok(__clear_addr, __clear_size)) { \
+__clear_res = __clear_user(__clear_addr, __clear_size); \
+} else __clear_res = __clear_size; \
+__clear_res; })
+
+#define clear_user_ret(addr,size,retval) ({ \
+if (clear_user(addr,size)) \
+	return retval; \
+})
+
+extern int __strncpy_from_user(unsigned long dest, unsigned long src, int count);
+
+#define strncpy_from_user(dest,src,count) ({ \
+unsigned long __sfu_src = (unsigned long) (src); \
+int __sfu_count = (int) (count); \
+long __sfu_res = -EFAULT; \
+if(__access_ok(__sfu_src, __sfu_count)) { \
+__sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \
+} __sfu_res; })
+
+extern int __strlen_user(const char *);
+
+extern __inline__ int strlen_user(const char *str)
+{
+	if(!access_ok(VERIFY_READ, str, 0))
+		return 0;
+	else
+		return __strlen_user(str);
+}
+
+#endif  /* __ASSEMBLY__ */
+
+#endif /* _ASM_UACCESS_H */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/unaligned.h linux/include/asm-sparc64/unaligned.h
--- v2.1.18/linux/include/asm-sparc64/unaligned.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/unaligned.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,19 @@
+#ifndef _ASM_SPARC64_UNALIGNED_H_
+#define _ASM_SPARC64_UNALIGNED_H_
+
+/* Sparc can't handle unaligned accesses. */
+
+#include <asm/string.h>
+
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+#define get_unaligned(ptr) \
+  ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+
+#define put_unaligned(val, ptr)				\
+  ({ __typeof__(*(ptr)) __tmp = (val);			\
+     memmove((ptr), &__tmp, sizeof(*(ptr)));		\
+     (void)0; })
+
+#endif /* _ASM_SPARC64_UNALIGNED_H */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/unistd.h linux/include/asm-sparc64/unistd.h
--- v2.1.18/linux/include/asm-sparc64/unistd.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/unistd.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,493 @@
+/* $Id: unistd.h,v 1.1 1996/12/26 14:22:43 davem Exp $ */
+#ifndef _SPARC64_UNISTD_H
+#define _SPARC64_UNISTD_H
+
+/*
+ * System calls under the Sparc.
+ *
+ * Don't be scared by the ugly clobbers, it is the only way I can
+ * think of right now to force the arguments into fixed registers
+ * before the trap into the system call with gcc 'asm' statements.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * SunOS compatibility based upon preliminary work which is:
+ *
+ * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
+ */
+
+#define __NR_setup                0 /* Used only by init, to get system going.     */
+#define __NR_exit                 1 /* Common                                      */
+#define __NR_fork                 2 /* Common                                      */
+#define __NR_read                 3 /* Common                                      */
+#define __NR_write                4 /* Common                                      */
+#define __NR_open                 5 /* Common                                      */
+#define __NR_close                6 /* Common                                      */
+#define __NR_wait4                7 /* Common                                      */
+#define __NR_creat                8 /* Common                                      */
+#define __NR_link                 9 /* Common                                      */
+#define __NR_unlink              10 /* Common                                      */
+#define __NR_execv               11 /* SunOS Specific                              */
+#define __NR_chdir               12 /* Common                                      */
+/* #define __NR_ni_syscall       13    ENOSYS under SunOS                          */
+#define __NR_mknod               14 /* Common                                      */
+#define __NR_chmod               15 /* Common                                      */
+#define __NR_chown               16 /* Common                                      */
+#define __NR_brk                 17 /* Common                                      */
+/* #define __NR_ni_syscall       18    ENOSYS under SunOS                          */
+#define __NR_lseek               19 /* Common                                      */
+#define __NR_getpid              20 /* Common                                      */
+/* #define __NR_ni_syscall       21    ENOSYS under SunOS                          */
+/* #define __NR_ni_syscall       22    ENOSYS under SunOS                          */
+#define __NR_setuid              23 /* Implemented via setreuid in SunOS           */
+#define __NR_getuid              24 /* Common                                      */
+/* #define __NR_ni_syscall       25    ENOSYS under SunOS                          */
+#define __NR_ptrace              26 /* Common                                      */
+#define __NR_alarm               27 /* Implemented via setitimer in SunOS          */
+/* #define __NR_ni_syscall       28    ENOSYS under SunOS                          */
+#define __NR_pause               29 /* Is sigblock(0)->sigpause() in SunOS         */
+#define __NR_utime               30 /* Implemented via utimes() under SunOS        */
+#define __NR_stty                31 /* Implemented via ioctl() under SunOS         */
+#define __NR_gtty                32 /* Implemented via ioctl() under SunOS         */
+#define __NR_access              33 /* Common                                      */
+#define __NR_nice                34 /* Implemented via get/setpriority() in SunOS  */
+#define __NR_ftime               35 /* Implemented via gettimeofday() in SunOS     */
+#define __NR_sync                36 /* Common                                      */
+#define __NR_kill                37 /* Common                                      */
+#define __NR_stat                38 /* Common                                      */
+/* #define __NR_ni_syscall       39    ENOSYS under SunOS                          */
+#define __NR_lstat               40 /* Common                                      */
+#define __NR_dup                 41 /* Common                                      */
+#define __NR_pipe                42 /* Common                                      */
+#define __NR_times               43 /* Implemented via getrusage() in SunOS        */
+#define __NR_profil              44 /* Common                                      */
+/* #define __NR_ni_syscall       45    ENOSYS under SunOS                          */
+#define __NR_setgid              46 /* Implemented via setregid() in SunOS         */
+#define __NR_getgid              47 /* Common                                      */
+#define __NR_signal              48 /* Implemented via sigvec() in SunOS           */
+#define __NR_geteuid             49 /* SunOS calls getuid()                        */
+#define __NR_getegid             50 /* SunOS calls getgid()                        */
+#define __NR_acct                51 /* Common                                      */
+/* #define __NR_ni_syscall       52    ENOSYS under SunOS                          */
+#define __NR_mctl                53 /* SunOS specific                              */
+#define __NR_ioctl               54 /* Common                                      */
+#define __NR_reboot              55 /* Common                                      */
+/* #define __NR_ni_syscall       56    ENOSYS under SunOS                          */
+#define __NR_symlink             57 /* Common                                      */
+#define __NR_readlink            58 /* Common                                      */
+#define __NR_execve              59 /* Common                                      */
+#define __NR_umask               60 /* Common                                      */
+#define __NR_chroot              61 /* Common                                      */
+#define __NR_fstat               62 /* Common                                      */
+/* #define __NR_ni_syscall       63    ENOSYS under SunOS                          */
+#define __NR_getpagesize         64 /* Common                                      */
+#define __NR_msync               65 /* Common in newer 1.3.x revs...               */
+/* #define __NR_ni_syscall       66    ENOSYS under SunOS                          */
+/* #define __NR_ni_syscall       67    ENOSYS under SunOS                          */
+/* #define __NR_ni_syscall       68    ENOSYS under SunOS                          */
+#define __NR_sbrk                69 /* SunOS Specific                              */
+#define __NR_sstk                70 /* SunOS Specific                              */
+#define __NR_mmap                71 /* Common                                      */
+#define __NR_vadvise             72 /* SunOS Specific                              */
+#define __NR_munmap              73 /* Common                                      */
+#define __NR_mprotect            74 /* Common                                      */
+#define __NR_madvise             75 /* SunOS Specific                              */
+#define __NR_vhangup             76 /* Common                                      */
+/* #define __NR_ni_syscall       77    ENOSYS under SunOS                          */
+#define __NR_mincore             78 /* SunOS Specific                              */
+#define __NR_getgroups           79 /* Common                                      */
+#define __NR_setgroups           80 /* Common                                      */
+#define __NR_getpgrp             81 /* Common                                      */
+#define __NR_setpgrp             82 /* setpgid, same difference...                 */
+#define __NR_setitimer           83 /* Common                                      */
+/* #define __NR_ni_syscall       84    ENOSYS under SunOS                          */
+#define __NR_swapon              85 /* Common                                      */
+#define __NR_getitimer           86 /* Common                                      */
+#define __NR_gethostname         87 /* SunOS Specific                              */
+#define __NR_sethostname         88 /* Common                                      */
+#define __NR_getdtablesize       89 /* SunOS Specific                              */
+#define __NR_dup2                90 /* Common                                      */
+#define __NR_getdopt             91 /* SunOS Specific                              */
+#define __NR_fcntl               92 /* Common                                      */
+#define __NR_select              93 /* Common                                      */
+#define __NR_setdopt             94 /* SunOS Specific                              */
+#define __NR_fsync               95 /* Common                                      */
+#define __NR_setpriority         96 /* Common                                      */
+#define __NR_socket              97 /* SunOS Specific                              */
+#define __NR_connect             98 /* SunOS Specific                              */
+#define __NR_accept              99 /* SunOS Specific                              */
+#define __NR_getpriority        100 /* Common                                      */
+#define __NR_send               101 /* SunOS Specific                              */
+#define __NR_recv               102 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      103    ENOSYS under SunOS                          */
+#define __NR_bind               104 /* SunOS Specific                              */
+#define __NR_setsockopt         105 /* SunOS Specific                              */
+#define __NR_listen             106 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      107    ENOSYS under SunOS                          */
+#define __NR_sigvec             108 /* SunOS Specific                              */
+#define __NR_sigblock           109 /* SunOS Specific                              */
+#define __NR_sigsetmask         110 /* SunOS Specific                              */
+#define __NR_sigpause           111 /* SunOS Specific                              */
+#define __NR_sigstack           112 /* SunOS Specific                              */
+#define __NR_recvmsg            113 /* SunOS Specific                              */
+#define __NR_sendmsg            114 /* SunOS Specific                              */
+#define __NR_vtrace             115 /* SunOS Specific                              */
+#define __NR_gettimeofday       116 /* Common                                      */
+#define __NR_getrusage          117 /* Common                                      */
+#define __NR_getsockopt         118 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      119    ENOSYS under SunOS                          */
+#define __NR_readv              120 /* Common                                      */
+#define __NR_writev             121 /* Common                                      */
+#define __NR_settimeofday       122 /* Common                                      */
+#define __NR_fchown             123 /* Common                                      */
+#define __NR_fchmod             124 /* Common                                      */
+#define __NR_recvfrom           125 /* SunOS Specific                              */
+#define __NR_setreuid           126 /* Common                                      */
+#define __NR_setregid           127 /* Common                                      */
+#define __NR_rename             128 /* Common                                      */
+#define __NR_truncate           129 /* Common                                      */
+#define __NR_ftruncate          130 /* Common                                      */
+#define __NR_flock              131 /* Common                                      */
+/* #define __NR_ni_syscall      132    ENOSYS under SunOS                          */
+#define __NR_sendto             133 /* SunOS Specific                              */
+#define __NR_shutdown           134 /* SunOS Specific                              */
+#define __NR_socketpair         135 /* SunOS Specific                              */
+#define __NR_mkdir              136 /* Common                                      */
+#define __NR_rmdir              137 /* Common                                      */
+#define __NR_utimes             138 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      139    ENOSYS under SunOS                          */
+#define __NR_adjtime            140 /* SunOS Specific                              */
+#define __NR_getpeername        141 /* SunOS Specific                              */
+#define __NR_gethostid          142 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      143    ENOSYS under SunOS                          */
+#define __NR_getrlimit          144 /* Common                                      */
+#define __NR_setrlimit          145 /* Common                                      */
+#define __NR_killpg             146 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      147    ENOSYS under SunOS                          */
+/* #define __NR_ni_syscall      148    ENOSYS under SunOS                          */
+/* #define __NR_ni_syscall      149    ENOSYS under SunOS                          */
+#define __NR_getsockname        150 /* SunOS Specific                              */
+#define __NR_getmsg             151 /* SunOS Specific                              */
+#define __NR_putmsg             152 /* SunOS Specific                              */
+#define __NR_poll               153 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      154    ENOSYS under SunOS                          */
+#define __NR_nfssvc             155 /* SunOS Specific                              */
+#define __NR_getdirentries      156 /* SunOS Specific                              */
+#define __NR_statfs             157 /* Common                                      */
+#define __NR_fstatfs            158 /* Common                                      */
+#define __NR_umount             159 /* Common                                      */
+#define __NR_async_daemon       160 /* SunOS Specific                              */
+#define __NR_getfh              161 /* SunOS Specific                              */
+#define __NR_getdomainname      162 /* SunOS Specific                              */
+#define __NR_setdomainname      163 /* Common                                      */
+/* #define __NR_ni_syscall      164    ENOSYS under SunOS                          */
+#define __NR_quotactl           165 /* Common                                      */
+#define __NR_exportfs           166 /* SunOS Specific                              */
+#define __NR_mount              167 /* Common                                      */
+#define __NR_ustat              168 /* Common                                      */
+#define __NR_semsys             169 /* SunOS Specific                              */
+#define __NR_msgsys             170 /* SunOS Specific                              */
+#define __NR_shmsys             171 /* SunOS Specific                              */
+#define __NR_auditsys           172 /* SunOS Specific                              */
+#define __NR_rfssys             173 /* SunOS Specific                              */
+#define __NR_getdents           174 /* Common                                      */
+#define __NR_setsid             175 /* Common                                      */
+#define __NR_fchdir             176 /* Common                                      */
+#define __NR_fchroot            177 /* SunOS Specific                              */
+#define __NR_vpixsys            178 /* SunOS Specific                              */
+#define __NR_aioread            179 /* SunOS Specific                              */
+#define __NR_aiowrite           180 /* SunOS Specific                              */
+#define __NR_aiowait            181 /* SunOS Specific                              */
+#define __NR_aiocancel          182 /* SunOS Specific                              */
+#define __NR_sigpending         183 /* Common                                      */
+/* #define __NR_ni_syscall      184    ENOSYS under SunOS                          */
+#define __NR_setpgid            185 /* Common                                      */
+#define __NR_pathconf           186 /* SunOS Specific                              */
+#define __NR_fpathconf          187 /* SunOS Specific                              */
+#define __NR_sysconf            188 /* SunOS Specific                              */
+#define __NR_uname              189 /* Linux Specific                              */
+#define __NR_init_module        190 /* Linux Specific                              */
+#define __NR_personality        191 /* Linux Specific                              */
+#define __NR_prof               192 /* Linux Specific                              */
+#define __NR_break              193 /* Linux Specific                              */
+#define __NR_lock               194 /* Linux Specific                              */
+#define __NR_mpx                195 /* Linux Specific                              */
+#define __NR_ulimit             196 /* Linux Specific                              */
+#define __NR_getppid            197 /* Linux Specific                              */
+#define __NR_sigaction          198 /* Linux Specific                              */
+#define __NR_sgetmask           199 /* Linux Specific                              */
+#define __NR_ssetmask           200 /* Linux Specific                              */
+#define __NR_sigsuspend         201 /* Linux Specific                              */
+#define __NR_oldlstat           202 /* Linux Specific                              */
+#define __NR_uselib             203 /* Linux Specific                              */
+#define __NR_readdir            204 /* Linux Specific                              */
+#define __NR_ioperm             205 /* Linux Specific - i386 specific, unused      */
+#define __NR_socketcall         206 /* Linux Specific                              */
+#define __NR_syslog             207 /* Linux Specific                              */
+#define __NR_olduname           208 /* Linux Specific                              */
+#define __NR_iopl               209 /* Linux Specific - i386 specific, unused      */
+#define __NR_idle               210 /* Linux Specific                              */
+#define __NR_vm86               211 /* Linux Specific - i386 specific, unused      */
+#define __NR_waitpid            212 /* Linux Specific                              */
+#define __NR_swapoff            213 /* Linux Specific                              */
+#define __NR_sysinfo            214 /* Linux Specific                              */
+#define __NR_ipc                215 /* Linux Specific                              */
+#define __NR_sigreturn          216 /* Linux Specific                              */
+#define __NR_clone              217 /* Linux Specific                              */
+#define __NR_modify_ldt         218 /* Linux Specific - i386 specific, unused      */
+#define __NR_adjtimex           219 /* Linux Specific                              */
+#define __NR_sigprocmask        220 /* Linux Specific                              */
+#define __NR_create_module      221 /* Linux Specific                              */
+#define __NR_delete_module      222 /* Linux Specific                              */
+#define __NR_get_kernel_syms    223 /* Linux Specific                              */
+#define __NR_getpgid            224 /* Linux Specific                              */
+#define __NR_bdflush            225 /* Linux Specific                              */
+#define __NR_sysfs              226 /* Linux Specific                              */
+#define __NR_afs_syscall        227 /* Linux Specific                              */
+#define __NR_setfsuid           228 /* Linux Specific                              */
+#define __NR_setfsgid           229 /* Linux Specific                              */
+#define __NR__newselect         230 /* Linux Specific                              */
+#define __NR_time               231 /* Linux Specific                              */
+#define __NR_oldstat            232 /* Linux Specific                              */
+#define __NR_stime              233 /* Linux Specific                              */
+#define __NR_oldfstat           234 /* Linux Specific                              */
+#define __NR_phys               235 /* Linux Specific                              */
+#define __NR__llseek            236 /* Linux Specific                              */
+#define __NR_mlock              237
+#define __NR_munlock            238
+#define __NR_mlockall           239
+#define __NR_munlockall         240
+#define __NR_sched_setparam     241
+#define __NR_sched_getparam     242
+#define __NR_sched_setscheduler 243
+#define __NR_sched_getscheduler 244
+#define __NR_sched_yield        245
+#define __NR_sched_get_priority_max 246
+#define __NR_sched_get_priority_min 247
+#define __NR_sched_rr_get_interval  248
+#define __NR_nanosleep          249
+#define __NR_mremap             250
+#define __NR__sysctl            251
+#define __NR_getsid             252
+#define __NR_fdatasync          253
+#define __NR_nfsctl             254
+#define __NR_aplib              255
+
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+long __res; \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+		      "t 0x10\n\t" \
+		      "bcc 1f\n\t" \
+		      "or %%g0, %%o0, %0\n\t" \
+		      "sub %%g0, %%o0, %0\n\t" \
+		      "1:\n\t" \
+		      : "=r" (__res)\
+		      : "0" (__NR_##name) \
+		      : "g1", "o0"); \
+if (__res >= 0) \
+    return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+long __res; \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+		      "or %%g0, %1, %%o0\n\t" \
+		      "t 0x10\n\t" \
+		      "bcc 1f\n\t" \
+		      "or %%g0, %%o0, %0\n\t" \
+		      "sub %%g0, %%o0, %0\n\t" \
+		      "1:\n\t" \
+		      : "=r" (__res), "=r" ((long)(arg1)) \
+		      : "0" (__NR_##name),"1" ((long)(arg1)) \
+		      : "g1", "o0"); \
+if (__res >= 0) \
+	return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+long __res; \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+		      "or %%g0, %1, %%o0\n\t" \
+		      "or %%g0, %2, %%o1\n\t" \
+		      "t 0x10\n\t" \
+		      "bcc 1f\n\t" \
+		      "or %%g0, %%o0, %0\n\t" \
+		      "sub %%g0, %%o0, %0\n\t" \
+		      "1:\n\t" \
+		      : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)) \
+		      : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)) \
+		      : "g1", "o0", "o1"); \
+if (__res >= 0) \
+	return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+		      "or %%g0, %1, %%o0\n\t" \
+		      "or %%g0, %2, %%o1\n\t" \
+		      "or %%g0, %3, %%o2\n\t" \
+		      "t 0x10\n\t" \
+		      "bcc 1f\n\t" \
+		      "or %%g0, %%o0, %0\n\t" \
+		      "sub %%g0, %%o0, %0\n\t" \
+		      "1:\n\t" \
+		      : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
+		        "=r" ((long)(arg3)) \
+		      : "0" (__NR_##name), "1" ((long)(arg1)), "2" ((long)(arg2)), \
+		        "3" ((long)(arg3)) \
+		      : "g1", "o0", "o1", "o2"); \
+if (__res>=0) \
+	return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+long __res; \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+		      "or %%g0, %1, %%o0\n\t" \
+		      "or %%g0, %2, %%o1\n\t" \
+		      "or %%g0, %3, %%o2\n\t" \
+		      "or %%g0, %4, %%o3\n\t" \
+		      "t 0x10\n\t" \
+		      "bcc 1f\n\t" \
+		      "or %%g0, %%o0, %0\n\t" \
+		      "sub %%g0,%%o0, %0\n\t" \
+		      "1:\n\t" \
+		      : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
+		        "=r" ((long)(arg3)), "=r" ((long)(arg4)) \
+		      : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \
+		        "3" ((long)(arg3)),"4" ((long)(arg4)) \
+		      : "g1", "o0", "o1", "o2", "o3"); \
+if (__res>=0) \
+	return (type) __res; \
+errno = -__res; \
+return -1; \
+} 
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+      long __res; \
+\
+__asm__ __volatile__ ("or %%g0, %1, %%o0\n\t" \
+		      "or %%g0, %2, %%o1\n\t" \
+		      "or %%g0, %3, %%o2\n\t" \
+		      "or %%g0, %4, %%o3\n\t" \
+		      "or %%g0, %5, %%o4\n\t" \
+		      "or %%g0, %6, %%g1\n\t" \
+		      "t 0x10\n\t" \
+		      "bcc 1f\n\t" \
+		      "or %%g0, %%o0, %0\n\t" \
+		      "sub %%g0, %%o0, %0\n\t" \
+		      "1:\n\t" \
+		      : "=r" (__res) \
+		      : "r" ((long)(arg1)),"r" ((long)(arg2)), \
+		        "r" ((long)(arg3)),"r" ((long)(arg4)),"r" ((long)(arg5)), \
+		        "i" (__NR_##name)  \
+		      : "g1", "o0", "o1", "o2", "o3", "o4"); \
+if (__res>=0) \
+	return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static __inline__ _syscall0(int,idle)
+static __inline__ _syscall0(int,fork)
+static __inline__ _syscall2(int,clone,unsigned long,flags,char *,ksp)
+static __inline__ _syscall0(int,pause)
+static __inline__ _syscall0(int,setup)
+static __inline__ _syscall0(int,sync)
+static __inline__ _syscall0(pid_t,setsid)
+static __inline__ _syscall3(int,write,int,fd,__const__ char *,buf,off_t,count)
+static __inline__ _syscall1(int,dup,int,fd)
+static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp)
+static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode)
+static __inline__ _syscall1(int,close,int,fd)
+static __inline__ _syscall1(int,_exit,int,exitcode)
+static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+
+static __inline__ pid_t wait(int * wait_stat)
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ */
+static __inline__ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	long retval;
+
+	__asm__ __volatile("mov %4, %%g2\n\t"    /* Set aside fn ptr... */
+			   "mov %5, %%g3\n\t"    /* and arg. */
+			   "mov %1, %%g1\n\t"
+			   "mov %2, %%o0\n\t"    /* Clone flags. */
+			   "mov 0, %%o1\n\t"     /* usp arg == 0 */
+			   "t 0x10\n\t"          /* Linux/Sparc clone(). */
+			   "cmp %%o1, 0\n\t"
+			   "be 1f\n\t"           /* The parent, just return. */
+			   " nop\n\t"            /* Delay slot. */
+			   "jmpl %%g2, %%o7\n\t" /* Call the function. */
+			   " mov %%g3, %%o0\n\t" /* Get back the arg in delay. */
+			   "mov %3, %%g1\n\t"
+			   "t 0x10\n\t"          /* Linux/Sparc exit(). */
+			   /* Notreached by child. */
+			   "1: mov %%o0, %0\n\t" :
+			   "=r" (retval) :
+			   "i" (__NR_clone), "r" (flags | CLONE_VM),
+			   "i" (__NR_exit),  "r" (fn), "r" (arg) :
+			   "g1", "g2", "g3", "o0", "o1", "memory");
+	return retval;
+}
+
+#endif /* __KERNEL_SYSCALLS__ */
+
+/* sysconf options, for SunOS compatibility */
+#define   _SC_ARG_MAX             1
+#define   _SC_CHILD_MAX           2
+#define   _SC_CLK_TCK             3
+#define   _SC_NGROUPS_MAX         4
+#define   _SC_OPEN_MAX            5
+#define   _SC_JOB_CONTROL         6
+#define   _SC_SAVED_IDS           7
+#define   _SC_VERSION             8
+
+#endif /* _SPARC64_UNISTD_H */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/upa.h linux/include/asm-sparc64/upa.h
--- v2.1.18/linux/include/asm-sparc64/upa.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/upa.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,24 @@
+/* $Id */
+#ifndef _SPARC64_UPA_H
+#define _SPARC64_UPA_H
+
+/* UPA level registers and defines. */
+
+/* UPA Config Register */
+#define UPA_CONFIG_RESV		0xffffffffc0000000 /* Reserved.                    */
+#define UPA_CONFIG_PCON		0x000000003fc00000 /* Depth of various sys queues. */
+#define UPA_CONFIG_MID		0x00000000003e0000 /* Module ID.                   */
+#define UPA_CONFIG_PCAP		0x000000000001ffff /* Port Capabilities.           */
+
+/* UPA Port ID Register */
+#define UPA_PORTID_FNP		0xff00000000000000 /* Hardcoded to 0xfc on ultra.  */
+#define UPA_PORTID_RESV		0x00fffff800000000 /* Reserved.                    */
+#define UPA_PORTID_ECCVALID     0x0000000400000000 /* Zero if mod can generate ECC */
+#define UPA_PORTID_ONEREAD      0x0000000200000000 /* Set if mod generates P_RASB  */
+#define UPA_PORTID_PINTRDQ      0x0000000180000000 /* # outstanding P_INT_REQ's    */
+#define UPA_PORTID_PREQDQ       0x000000007e000000 /* slave-wr's to mod supported  */
+#define UPA_PORTID_PREQRD       0x0000000001e00000 /* # incoming P_REQ's supported */
+#define UPA_PORTID_UPACAP       0x00000000001f0000 /* UPA capabilities of mod      */
+#define UPA_PORTID_ID           0x000000000000ffff /* Module Indentification bits  */
+
+#endif /* !(_SPARC64_UPA_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/user.h linux/include/asm-sparc64/user.h
--- v2.1.18/linux/include/asm-sparc64/user.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/user.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,60 @@
+/* $Id: user.h,v 1.1 1996/12/26 14:22:44 davem Exp $
+ * asm-sparc64/user.h: Core file definitions for the Sparc.
+ *
+ * Keep in sync with reg.h.  Actually, we could get rid of this
+ * one, since we won't a.out core dump that much anyways - miguel.
+ * Copyright (C) 1995 (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC64_USER_H
+#define _SPARC64_USER_H
+
+#include <asm/a.out.h>
+struct sunos_regs {
+	unsigned int psr, pc, npc, y;
+	unsigned int regs[15];
+};
+
+struct sunos_fpqueue {
+	unsigned int *addr;
+	unsigned int inst;
+};
+
+struct sunos_fp {
+	union {
+		unsigned int regs[32];
+		double reg_dbls[16];
+	} fregs;
+	unsigned int fsr;
+	unsigned int flags;
+	unsigned int extra;
+	unsigned int fpq_count;
+	struct sunos_fpqueue fpq[16];
+};
+
+struct sunos_fpu {
+	struct sunos_fp fpstatus;
+};
+
+/* The SunOS core file header layout. */
+struct user {
+	unsigned int magic;
+	unsigned int len;
+	struct sunos_regs regs;
+	struct exec uexec;
+	int           signal;
+	size_t        u_tsize; /* all of these in bytes! */
+	size_t        u_dsize;
+	size_t        u_ssize;
+	char          u_comm[17];
+	struct sunos_fpu fpu;
+	unsigned int  sigcode;   /* Special sigcontext subcode, if any */
+};
+
+#define NBPG                   PAGE_SIZE /* XXX 4096 maybe? */
+#define UPAGES                 1
+#define HOST_TEXT_START_ADDR   (u.start_code)
+#define HOST_DATA_START_ADDR   (u.start_data)
+#define HOST_STACK_END_ADDR    (u.start_stack + u.u_ssize * NBPG)
+#define SUNOS_CORE_MAGIC       0x080456
+
+#endif /* !(_SPARC64_USER_H) */
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/vuid_event.h linux/include/asm-sparc64/vuid_event.h
--- v2.1.18/linux/include/asm-sparc64/vuid_event.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/vuid_event.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,42 @@
+/* SunOS Virtual User Input Device (VUID) compatibility */
+
+typedef struct firm_event {
+	unsigned short id;	  /* tag for this event */
+	unsigned char  pair_type; /* unused by X11 */
+        unsigned char  pair;	  /* unused by X11 */
+        int            value;	  /* VKEY_UP, VKEY_DOWN or delta */
+
+	/* XXX Timeval could hose old 32-bit programs, investigate and fixme XXX */
+        struct timeval time;
+} Firm_event;
+
+enum {
+    FE_PAIR_NONE,
+    FE_PAIR_SET,
+    FE_PAIR_DELTA,
+    FE_PAIR_ABSOLUTE
+};
+
+/* VUID stream formats */
+#define VUID_NATIVE     0	/* Native byte stream format */
+#define VUID_FIRM_EVENT 1	/* send firm_event structures */
+
+/* ioctls */
+    /* Set input device byte stream format (any of VUID_{NATIVE,FIRM_EVENT}) */
+#define VUIDSFORMAT   _IOW('v', 1, int)
+    /* Retrieve input device byte stream format */
+#define VUIDGFORMAT   _IOR('v', 2, int)
+
+/* Possible tag values */
+/*    mouse buttons: */
+#define MS_LEFT         0x7f20
+#define MS_MIDDLE       0x7f21
+#define MS_RIGHT        0x7f22
+/*    motion: */
+#define LOC_X_DELTA     0x7f80
+#define LOC_Y_DELTA     0x7f81
+#define LOC_X_ABSOLUTE  0x7f82  /* X compat, unsupported */
+#define LOC_Y_ABSOLUTE  0x7f83  /* X compat, unsupported */
+
+#define VKEY_UP   0
+#define VKEY_DOWN 1
diff -u --recursive --new-file v2.1.18/linux/include/asm-sparc64/winmacro.h linux/include/asm-sparc64/winmacro.h
--- v2.1.18/linux/include/asm-sparc64/winmacro.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-sparc64/winmacro.h	Mon Dec 30 12:00:03 1996
@@ -0,0 +1,66 @@
+/* $Id: winmacro.h,v 1.1 1996/12/26 13:25:20 davem Exp $
+ * winmacro.h: Window loading-unloading macros for Sparc/V9.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_WINMACRO_H
+#define _SPARC64_WINMACRO_H
+
+#define STORE_V9_WINDOW_GENERIC_ASI(store_insn, base, offset, the_asi)	\
+	store_insn	%l0, [base + offset + RW_V9_L0] the_asi;	\
+	store_insn	%l1, [base + offset + RW_V9_L1] the_asi;	\
+	store_insn	%l2, [base + offset + RW_V9_L2] the_asi;	\
+	store_insn	%l3, [base + offset + RW_V9_L3] the_asi;	\
+	store_insn	%l4, [base + offset + RW_V9_L4] the_asi;	\
+	store_insn	%l5, [base + offset + RW_V9_L5] the_asi;	\
+	store_insn	%l6, [base + offset + RW_V9_L6] the_asi;	\
+	store_insn	%l7, [base + offset + RW_V9_L7] the_asi;	\
+	store_insn	%i0, [base + offset + RW_V9_I0] the_asi;	\
+	store_insn	%i1, [base + offset + RW_V9_I1] the_asi;	\
+	store_insn	%i2, [base + offset + RW_V9_I2] the_asi;	\
+	store_insn	%i3, [base + offset + RW_V9_I3] the_asi;	\
+	store_insn	%i4, [base + offset + RW_V9_I4] the_asi;	\
+	store_insn	%i5, [base + offset + RW_V9_I5] the_asi;	\
+	store_insn	%i6, [base + offset + RW_V9_I6] the_asi;	\
+	store_insn	%i7, [base + offset + RW_V9_I7] the_asi;
+
+#define STORE_V9_WINDOW_KERNEL(base)		\
+	stx	%l0, [base + RW_V9_L0];		\
+	stx	%l1, [base + RW_V9_L1];		\
+	stx	%l2, [base + RW_V9_L2];		\
+	stx	%l3, [base + RW_V9_L3];		\
+	stx	%l4, [base + RW_V9_L4];		\
+	stx	%l5, [base + RW_V9_L5];		\
+	stx	%l6, [base + RW_V9_L6];		\
+	stx	%l7, [base + RW_V9_L7];		\
+	stx	%i0, [base + RW_V9_I0];		\
+	stx	%i1, [base + RW_V9_I1];		\
+	stx	%i2, [base + RW_V9_I2];		\
+	stx	%i3, [base + RW_V9_I3];		\
+	stx	%i4, [base + RW_V9_I4];		\
+	stx	%i5, [base + RW_V9_I5];		\
+	stx	%i6, [base + RW_V9_I6];		\
+	stx	%i7, [base + RW_V9_I7];
+
+#define LOAD_V9_WINDOW_KERNEL(base)		\
+	ldx	[base + RW_V9_L0], %l0;		\
+	ldx	[base + RW_V9_L1], %l1;		\
+	ldx	[base + RW_V9_L2], %l2;		\
+	ldx	[base + RW_V9_L3], %l3;		\
+	ldx	[base + RW_V9_L4], %l4;		\
+	ldx	[base + RW_V9_L5], %l5;		\
+	ldx	[base + RW_V9_L6], %l6;		\
+	ldx	[base + RW_V9_L7], %l7;		\
+	ldx	[base + RW_V9_I0], %i0;		\
+	ldx	[base + RW_V9_I1], %i1;		\
+	ldx	[base + RW_V9_I2], %i2;		\
+	ldx	[base + RW_V9_I3], %i3;		\
+	ldx	[base + RW_V9_I4], %i4;		\
+	ldx	[base + RW_V9_I5], %i5;		\
+	ldx	[base + RW_V9_I6], %i6;		\
+	ldx	[base + RW_V9_I7], %i7;
+
+#define STORE_V9_WINDOW_ASI_REG(base)		\
+
+#endif /* !(_SPARC64_WINMACRO_H) */
diff -u --recursive --new-file v2.1.18/linux/include/linux/msdos_fs.h linux/include/linux/msdos_fs.h
--- v2.1.18/linux/include/linux/msdos_fs.h	Sun Dec 22 16:37:41 1996
+++ linux/include/linux/msdos_fs.h	Tue Dec 31 14:12:51 1996
@@ -9,6 +9,8 @@
 #include <linux/fd.h>
 #include <linux/config.h>
 
+#include <asm/byteorder.h>
+
 #define MSDOS_ROOT_INO  1 /* == MINIX_ROOT_INO */
 #define SECTOR_SIZE     512 /* sector size (bytes) */
 #define SECTOR_BITS	9 /* log2(SECTOR_SIZE) */
@@ -96,11 +98,10 @@
  * BE = big-endian, c: W = word (16 bits), L = longword (32 bits)
  */
 
-#define CF_LE_W(v) (v)
-#define CF_LE_L(v) (v)
-#define CT_LE_W(v) (v)
-#define CT_LE_L(v) (v)
-
+#define CF_LE_W(v) le16_to_cpu(v)
+#define CF_LE_L(v) le32_to_cpu(v)
+#define CT_LE_W(v) cpu_to_le16(v)
+#define CT_LE_L(v) cpu_to_le32(v)
 
 struct msdos_boot_sector {
 	__s8	ignored[3];	/* Boot strap short or near jump */
diff -u --recursive --new-file v2.1.18/linux/include/linux/ncp.h linux/include/linux/ncp.h
--- v2.1.18/linux/include/linux/ncp.h	Sun Aug  4 15:14:16 1996
+++ linux/include/linux/ncp.h	Mon Dec 30 12:03:22 1996
@@ -2,6 +2,7 @@
  *  ncp.h
  *
  *  Copyright (C) 1995 by Volker Lendecke
+ *  Modified for sparc by J.F. Chadima
  *
  */
 
@@ -92,16 +93,16 @@
 #define NCP_MAX_FILENAME 14
 
 /* these define the attribute byte as seen by NCP */
-#define aRONLY     (1L<<0)
-#define aHIDDEN    (1L<<1)
-#define aSYSTEM    (1L<<2)
-#define aEXECUTE   (1L<<3)
-#define aDIR       (1L<<4)
-#define aARCH      (1L<<5)
-
-#define AR_READ      (0x01)
-#define AR_WRITE     (0x02)
-#define AR_EXCLUSIVE (0x20)
+#define aRONLY     (ntohl(0x01000000))
+#define aHIDDEN    (ntohl(0x02000000))
+#define aSYSTEM    (ntohl(0x04000000))
+#define aEXECUTE   (ntohl(0x08000000))
+#define aDIR       (ntohl(0x10000000))
+#define aARCH      (ntohl(0x20000000))
+
+#define AR_READ      (ntohs(0x0100))
+#define AR_WRITE     (ntohs(0x0200))
+#define AR_EXCLUSIVE (ntohs(0x2000))
 
 #define NCP_FILE_ID_LEN 6
 struct ncp_file_info {
@@ -124,20 +125,20 @@
 #define NW_NS_OS2     4
 
 /*  Defines for ReturnInformationMask */
-#define RIM_NAME	      (0x0001L)
-#define RIM_SPACE_ALLOCATED   (0x0002L)
-#define RIM_ATTRIBUTES	      (0x0004L)
-#define RIM_DATA_SIZE	      (0x0008L)
-#define RIM_TOTAL_SIZE	      (0x0010L)
-#define RIM_EXT_ATTR_INFO     (0x0020L)
-#define RIM_ARCHIVE	      (0x0040L)
-#define RIM_MODIFY	      (0x0080L)
-#define RIM_CREATION	      (0x0100L)
-#define RIM_OWNING_NAMESPACE  (0x0200L)
-#define RIM_DIRECTORY	      (0x0400L)
-#define RIM_RIGHTS	      (0x0800L)
-#define RIM_ALL 	      (0x0FFFL)
-#define RIM_COMPRESSED_INFO   (0x80000000L)
+#define RIM_NAME	      (ntohl(0x01000000L))
+#define RIM_SPACE_ALLOCATED   (ntohl(0x02000000L))
+#define RIM_ATTRIBUTES	      (ntohl(0x04000000L))
+#define RIM_DATA_SIZE	      (ntohl(0x08000000L))
+#define RIM_TOTAL_SIZE	      (ntohl(0x10000000L))
+#define RIM_EXT_ATTR_INFO     (ntohl(0x20000000L))
+#define RIM_ARCHIVE	      (ntohl(0x40000000L))
+#define RIM_MODIFY	      (ntohl(0x80000000L))
+#define RIM_CREATION	      (ntohl(0x00010000L))
+#define RIM_OWNING_NAMESPACE  (ntohl(0x00020000L))
+#define RIM_DIRECTORY	      (ntohl(0x00040000L))
+#define RIM_RIGHTS	      (ntohl(0x00080000L))
+#define RIM_ALL 	      (ntohl(0xFF0F0000L))
+#define RIM_COMPRESSED_INFO   (ntohl(0x00000080L))
 
 /* open/create modes */
 #define OC_MODE_OPEN	  0x01
@@ -194,19 +195,19 @@
 };
 
 /* modify mask - use with MODIFY_DOS_INFO structure */
-#define DM_ATTRIBUTES		  (0x0002L)
-#define DM_CREATE_DATE		  (0x0004L)
-#define DM_CREATE_TIME		  (0x0008L)
-#define DM_CREATOR_ID		  (0x0010L)
-#define DM_ARCHIVE_DATE 	  (0x0020L)
-#define DM_ARCHIVE_TIME 	  (0x0040L)
-#define DM_ARCHIVER_ID		  (0x0080L)
-#define DM_MODIFY_DATE		  (0x0100L)
-#define DM_MODIFY_TIME		  (0x0200L)
-#define DM_MODIFIER_ID		  (0x0400L)
-#define DM_LAST_ACCESS_DATE	  (0x0800L)
-#define DM_INHERITED_RIGHTS_MASK  (0x1000L)
-#define DM_MAXIMUM_SPACE	  (0x2000L)
+#define DM_ATTRIBUTES		  (ntohl(0x02000000L))
+#define DM_CREATE_DATE		  (ntohl(0x04000000L))
+#define DM_CREATE_TIME		  (ntohl(0x08000000L))
+#define DM_CREATOR_ID		  (ntohl(0x10000000L))
+#define DM_ARCHIVE_DATE 	  (ntohl(0x20000000L))
+#define DM_ARCHIVE_TIME 	  (ntohl(0x40000000L))
+#define DM_ARCHIVER_ID		  (ntohl(0x80000000L))
+#define DM_MODIFY_DATE		  (ntohl(0x00010000L))
+#define DM_MODIFY_TIME		  (ntohl(0x00020000L))
+#define DM_MODIFIER_ID		  (ntohl(0x00040000L))
+#define DM_LAST_ACCESS_DATE	  (ntohl(0x00080000L))
+#define DM_INHERITED_RIGHTS_MASK  (ntohl(0x00100000L))
+#define DM_MAXIMUM_SPACE	  (ntohl(0x00200000L))
 
 struct nw_modify_dos_info
 {
diff -u --recursive --new-file v2.1.18/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.1.18/linux/include/linux/sched.h	Sun Dec 22 16:37:41 1996
+++ linux/include/linux/sched.h	Tue Dec 31 14:09:19 1996
@@ -317,12 +317,9 @@
 extern struct task_struct init_task;
 extern struct task_struct *task[NR_TASKS];
 extern struct task_struct *last_task_used_math;
-extern struct task_struct *current_set[NR_CPUS];
-/*
- *	On a single processor system this comes out as current_set[0] when cpp
- *	has finished with it, which gcc will optimise away.
- */
-#define current (current_set[smp_processor_id()])	/* Current on this processor */
+
+#include <asm/current.h>
+
 extern unsigned long volatile jiffies;
 extern unsigned long itimer_ticks;
 extern unsigned long itimer_next;
diff -u --recursive --new-file v2.1.18/linux/include/linux/uio.h linux/include/linux/uio.h
--- v2.1.18/linux/include/linux/uio.h	Mon Dec 30 15:39:16 1996
+++ linux/include/linux/uio.h	Mon Dec 30 11:29:33 1996
@@ -1,6 +1,8 @@
 #ifndef __LINUX_UIO_H
 #define __LINUX_UIO_H
 
+#include <linux/types.h>
+
 /*
  *	Berkeley style UIO structures	-	Alan Cox 1994.
  *
diff -u --recursive --new-file v2.1.18/linux/kernel/exit.c linux/kernel/exit.c
--- v2.1.18/linux/kernel/exit.c	Tue Oct 29 19:58:48 1996
+++ linux/kernel/exit.c	Mon Dec 30 13:03:13 1996
@@ -19,6 +19,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
+#include <asm/mmu_context.h>
 
 extern void sem_exit (void);
 extern void acct_process (long exitcode);
@@ -475,6 +476,7 @@
 	if (mm != &init_mm) {
 		flush_cache_mm(mm);
 		flush_tlb_mm(mm);
+		destroy_context(mm);
 		tsk->mm = &init_mm;
 		tsk->swappable = 0;
 		SET_PAGE_DIR(tsk, swapper_pg_dir);
diff -u --recursive --new-file v2.1.18/linux/kernel/fork.c linux/kernel/fork.c
--- v2.1.18/linux/kernel/fork.c	Sun Dec 22 16:37:42 1996
+++ linux/kernel/fork.c	Mon Dec 30 13:03:13 1996
@@ -22,6 +22,7 @@
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
+#include <asm/mmu_context.h>
 #include <asm/uaccess.h>
 
 int nr_tasks=1;
@@ -118,6 +119,7 @@
 		if (!mm)
 			return -1;
 		*mm = *current->mm;
+		init_new_context(mm);
 		mm->count = 1;
 		mm->def_flags = 0;
 		tsk->mm = mm;
@@ -132,8 +134,8 @@
 		}
 		return 0;
 	}
-	SET_PAGE_DIR(tsk, current->mm->pgd);
 	current->mm->count++;
+	SET_PAGE_DIR(tsk, current->mm->pgd);
 	return 0;
 }
 
diff -u --recursive --new-file v2.1.18/linux/mm/mmap.c linux/mm/mmap.c
--- v2.1.18/linux/mm/mmap.c	Sun Dec 22 16:37:42 1996
+++ linux/mm/mmap.c	Mon Dec 30 11:56:18 1996
@@ -310,7 +310,7 @@
 	if (len > TASK_SIZE)
 		return 0;
 	if (!addr)
-		addr = TASK_SIZE / 3;
+		addr = TASK_UNMAPPED_BASE;
 	addr = PAGE_ALIGN(addr);
 
 	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
